Compare commits

...

80 Commits

Author SHA1 Message Date
Vikeo
fb91ef3224 add glow on start menu 2024-05-23 12:55:02 +02:00
Vikeo
c3e8326be2 add glow animation to start menu 2024-05-23 12:54:42 +02:00
Vikeo
9bbe6cbb3b style sliders 2024-05-23 10:05:02 +02:00
Vikeo
739048044c update colors 2024-05-22 10:49:03 +02:00
Vikeo
4656757554 update info icon 2024-05-22 10:26:42 +02:00
Vikeo
9a6bfe49a1 fix player settings background colour 2024-05-22 00:23:38 +02:00
Vikeo
e6e562a0c6 fix types 2024-05-22 00:14:25 +02:00
Vikeo
3e38332a68 check version using semver 2024-05-22 00:10:16 +02:00
Vikeo
c23509ae26 icon tweak 2024-05-21 23:48:25 +02:00
Vikeo
9f1cc35eab new logo by elin 2024-05-21 21:06:43 +02:00
Vikeo
fe43e464de pnpm 9 2024-05-21 20:13:36 +02:00
Viktor Rådberg
b074499c1f small settings menu tweak 2024-05-15 18:25:45 +02:00
Viktor Rådberg
5953cf6b49 debump 2024-05-15 18:06:18 +02:00
Viktor Rådberg
acefbb8846 fix start menu width 2024-05-15 18:05:02 +02:00
Viktor Rådberg
adb79bf0e8 fix width 2024-05-10 23:23:32 +02:00
Viktor Rådberg
92be2e56d4 bump 2024-05-05 20:52:51 +02:00
Viktor Rådberg
854ca81a40 fix width 2024-05-05 20:52:30 +02:00
Viktor Rådberg
9119ca5518 fix dialog on iOS 2024-05-01 14:46:53 +02:00
Vikeo
2837bb59b3 bumpb 2024-05-01 14:25:03 +02:00
Viktor Rådberg
623aec29f8 Remove MUI (#36)
* remove mui from layouts

* remove button

* remove switch

* remove mui
2024-05-01 14:24:38 +02:00
Vikeo
63aace2b07 fix typo and adjust touch roulette timings 2024-04-07 23:58:39 +02:00
Vikeo
ba9ca354fc fix crown being visible after reset 2024-04-01 18:48:06 +02:00
Viktor Rådberg
e79c728e6a Save game (#35)
* save

* hide scrollbar on desktop

* start menu styling

* bump
2024-04-01 00:28:59 +02:00
Viktor Rådberg
97f9bb75e5 bump 2024-03-31 19:58:00 +02:00
Viktor Rådberg
341cb3cde0 revert new api key 2024-03-31 19:57:16 +02:00
Viktor Rådberg
ce9c9ca997 default api key 2024-03-31 19:31:16 +02:00
Viktor Rådberg
ad485f059d debug release 2024-03-31 19:25:44 +02:00
Viktor Rådberg
92f954130f bump 2024-03-31 19:13:27 +02:00
Viktor Rådberg
112023bdd5 log if it works or not 2024-03-31 19:08:17 +02:00
Viktor Rådberg
4e6dc56d99 add api key back 2024-03-31 19:02:59 +02:00
Viktor Rådberg
e427bfd0cf new analytics api key 2024-03-31 18:52:08 +02:00
Viktor Rådberg
ed10edc6d2 bump 2024-03-31 12:30:18 +02:00
Viktor Rådberg
7696b357b4 add trivia prestart mode 2024-03-31 12:30:03 +02:00
Viktor Rådberg
a7b78b8e7a settings tracking 2024-03-31 12:28:34 +02:00
Viktor Rådberg
fa95d171b7 bump 2024-03-30 14:23:26 +01:00
Viktor Rådberg
00a556be0e always include version in tracked events 2024-03-30 14:22:37 +01:00
Viktor Rådberg
3276dc81fc Clearer way to see if there is an update, more fun tracking 2024-03-30 14:04:12 +01:00
Viktor Rådberg
28c2ff536f bump 2024-03-30 10:28:49 +01:00
Viktor Rådberg
6beddf06e2 better invalid settings handling 2024-03-30 10:27:16 +01:00
Viktor Rådberg
2a885f9a43 bump 2024-03-29 23:25:50 +01:00
Viktor Rådberg
9c27f34261 More Pre-Start modes. (#34)
* do

* parse settings before setting
2024-03-29 23:24:35 +01:00
Viktor Rådberg
fa5829b402 fix keep away state 2024-03-23 16:23:03 +01:00
Viktor Rådberg
71f26d0dc5 fix keep awake toggle and layout styling 2024-03-23 16:22:48 +01:00
Viktor Rådberg
3a568fc3ab Better scaling on small devices 2024-03-23 16:05:29 +01:00
Viktor Rådberg
355f4bd4cd track only on prod, and add life changed amount tracking 2024-03-23 12:39:07 +01:00
Viktor Rådberg
17e174bfe1 new deploy 2024-03-23 11:24:14 +01:00
Viktor Rådberg
e1e8da858b remove prod check 2024-03-23 11:23:46 +01:00
Viktor Rådberg
e02f071415 new deploy 2024-03-23 11:23:06 +01:00
Viktor Rådberg
e04f31bb67 prod log 2024-03-23 11:22:12 +01:00
Viktor Rådberg
e5386d08a4 fix settings cog color 2024-03-17 19:01:15 +01:00
Viktor Rådberg
d6cd678e9f fix random interval wrapper showing if enabled but show player is disabled 2024-03-17 18:41:58 +01:00
Viktor Rådberg
334b46db6e bump 2024-03-16 22:29:25 +01:00
Viktor Rådberg
e03ecc6f51 Merge pull request #33 from Vikeo/random-player-interval
random player interval
2024-03-16 22:28:49 +01:00
Viktor Rådberg
d4dc44076d fix lint 2024-03-16 22:28:37 +01:00
Viktor Rådberg
a1b5cfd871 fix tsc 2024-03-16 22:26:06 +01:00
Viktor Rådberg
f11eea5e53 better styling 2024-03-16 22:23:03 +01:00
Viktor Rådberg
905912a7fd fix random interval 2024-03-16 21:59:24 +01:00
Viktor Rådberg
a90dd7c9ea wip 2024-03-16 14:40:18 +01:00
Viktor Rådberg
ef1310d674 bump 2024-03-16 13:22:47 +01:00
Viktor Rådberg
fe3bb6c78c show starting player untill press 2024-03-16 13:22:03 +01:00
Viktor Rådberg
6d2b3b6a6f Add option to show player menu cog 2024-03-16 12:29:16 +01:00
Viktor Rådberg
0f86928cb3 Merge pull request #32 from Vikeo/better-colors
Better colors
2024-03-16 10:42:13 +01:00
Viktor Rådberg
efbfb7719c tsc 2024-03-16 10:40:18 +01:00
Viktor Rådberg
71e5614f52 bump to new version 2024-03-16 10:38:23 +01:00
Viktor Rådberg
677fd79bee fix long press down 2024-03-16 10:23:15 +01:00
Viktor Rådberg
1bff41bc10 remove colorful 2024-03-16 10:04:35 +01:00
Viktor Rådberg
7852520f8e minus plus icon color 2024-03-16 09:59:40 +01:00
Viktor Rådberg
04c3d60967 use normal picker again 2024-03-16 09:31:59 +01:00
Viktor Rådberg
664e2e5688 round color picker 2024-02-19 07:38:17 +01:00
Viktor Rådberg
6eb7ac9f50 Merge branch 'main' into better-colors 2024-02-18 16:08:09 +01:00
Viktor Rådberg
ef06e0d125 bump 2024-02-09 23:04:29 +01:00
Viktor Rådberg
ae9f5707b2 update blur 2024-02-09 23:04:14 +01:00
Viktor Rådberg
a18c253624 bump 2024-01-31 23:12:46 +01:00
Viktor Rådberg
3f319c4f3c add some blur to settings 2024-01-31 23:12:31 +01:00
Viktor Rådberg
8b33a2a38a wip 2024-01-28 17:04:30 +01:00
Viktor Rådberg
cc915dff36 better color picker 2024-01-28 11:54:37 +01:00
Viktor Rådberg
db80e563f2 bump 2024-01-27 18:05:54 +01:00
Viktor Rådberg
573af42b75 fix taps and some settings stuff 2024-01-27 18:05:18 +01:00
Viktor Rådberg
89e1eaff4e bump 2024-01-27 16:25:40 +01:00
Viktor Rådberg
0f4e896342 Merge pull request #31 from Vikeo/swipable-settings
Swipable settings
2024-01-27 16:23:54 +01:00
92 changed files with 13935 additions and 10760 deletions

View File

@@ -1,8 +1,12 @@
index.html,1705225256081,6ef0d7e2de82bf64addbb9294fb28845fd06daaa544b010a47422c12ae3ad97f
robots.txt,1705225255906,391d14b3c2f8c9143a27a28c7399585142228d4d1bdbe2c87ac946de411fa9a2
manifest.json,1705225255906,91ce94afb71f33a477f5d8d48c3f98bd7de422279c74f17b6500eec72003ac1a
assets/index-08359bdb.css,1705225256081,d2766260d28230d960d75362810713efaddf40687205e697432b52869f162af7
logo192.png,1705225255905,3b0fcf91fe2128f493de0bce2f6e2d35520a4260a04e05b8d855181359b3d3fe
favicon.ico,1705225255905,75661e6187b524767554b4f28ec09a64bc72b0bb102a0b453aaead88519d9ed3
logo512.png,1705225255906,cf49739c9e6890bbfcd4157f299dde425df60759b7320ae9188d7ab9dc51e8ca
assets/index-20658f4b.js,1705225256081,742f2c10740beea3a23f269aa6266b3c288d1fd9c7e20b6829034e8a898bf1e1
index.html,1711905710499,4b604b23faec8d63a58e07b96d724a1aea56a7c86d57c9af791832ce87a552e7
manifest.webmanifest,1711905710499,f2bf253209f6e292a6b0dbfa06fb4ac188eb5f2dba568c3ad5511b9ed52c1f51
manifest.json,1711905710294,7ff5111aa04a42adff3b38924ec467b6f345ed0309dba1486dc9b783b60c2a9d
sw.js,1711905711506,1ef2f4f40ec8dca15cc42d547462ade1e84314ea9722276f5994ccee7bbdf80f
robots.txt,1711905710294,391d14b3c2f8c9143a27a28c7399585142228d4d1bdbe2c87ac946de411fa9a2
registerSW.js,1711905710499,5b6445b5215737c53ef0d379c151d57de165a056de2d1c5812ed614f158ebcbd
workbox-3e911b1d.js,1711905711507,d5dbc868a5c07af633d29de7ba3ffe37542aaaabdf33713b4298df31f92f11ff
assets/index-7m_Zw4yH.css,1711905710499,37997d06b32b3d0c724c054913e3c0583b86f786358121cb1615e6646ff46b56
favicon.ico,1711905710294,8cefe5adbf00d337d8633fb744b9f2c4914f769b319be4bb7e184b7a4aa17160
logo192.png,1711905710294,3d1e2e6f064d4fd325828f21bb6493ff0dbf2390b0e7d2aba9f2b6def4829799
logo512.png,1711905710294,892a4da1cc5434929a83a71fcbcb0d0d80aa82f44e3c21e9b20ffe9267197133
assets/index-CLJVONOc.js,1711905710499,22f3835412f82bb3f8a62e74a7f4602a9c43b447224790365dbcc6cbffb4e665

View File

@@ -7,7 +7,8 @@ jobs:
build_and_deploy:
runs-on: ubuntu-latest
env:
REPO_READ_ACCESS_TOKEN: ${{ secrets.REPO_READ_ACCESS_TOKEN }}
VITE_REPO_READ_ACCESS_TOKEN: ${{ secrets.REPO_READ_ACCESS_TOKEN }}
VITE_FIREBASE_ANALYTICS_API_KEY: ${{ secrets.FIREBASE_ANALYTICS_API_KEY }}
steps:
- name: Checkout repository
uses: actions/checkout@v3

1
.npmrc Normal file
View File

@@ -0,0 +1 @@
node-linker=hoisted

BIN
bun.lockb

Binary file not shown.

1
env.d.ts vendored
View File

@@ -1 +0,0 @@
declare const APP_VERSION: string;

View File

@@ -1,11 +1,12 @@
{
"name": "life-trinket",
"private": true,
"version": "0.6.0",
"version": "0.9.93",
"type": "commonjs",
"engines": {
"node": ">=18",
"npm": "please use bun or yarn :) "
"node": ">=20",
"yarn": "use pnpm",
"npm": "please use pnpm"
},
"scripts": {
"dev": "vite",
@@ -16,7 +17,6 @@
"deploy": "bun run build && firebase deploy --only hosting"
},
"dependencies": {
"@mui/material": "^5.13.6",
"firebase": "^10.3.0",
"ga-4-react": "^0.1.281",
"react": "^18.2.0",
@@ -24,29 +24,32 @@
"react-screen-wake-lock": "^3.0.2",
"react-swipeable": "^7.0.1",
"react-twc": "^1.3.0",
"semver": "^7.6.2",
"zod": "^3.22.4"
},
"devDependencies": {
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@savvywombat/tailwindcss-grid-areas": "^3.1.0",
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@savvywombat/tailwindcss-grid-areas": "^4.0.0",
"@svgr/cli": "^8.1.0",
"@types/react": "^18.2.15",
"@types/react-dom": "^18.2.7",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"@vitejs/plugin-react-swc": "^3.3.2",
"autoprefixer": "^10.4.16",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.0",
"@types/semver": "^7.5.8",
"@typescript-eslint/eslint-plugin": "^7.8.0",
"@typescript-eslint/parser": "^7.8.0",
"@vitejs/plugin-react-swc": "^3.6.0",
"autoprefixer": "^10.4.19",
"eslint": "^8.45.0",
"eslint-plugin-react-hooks": "^4.6.0",
"eslint-plugin-react-refresh": "^0.4.3",
"firebase-tools": "^12.5.2",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.6",
"firebase-tools": "^13.7.5",
"install": "^0.13.0",
"postcss": "^8.4.32",
"postcss": "^8.4.38",
"prettier": "2.8.8",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3",
"vite": "^5.0.12",
"vite-plugin-pwa": "^0.17.4"
"prop-types": "^15.8.1",
"tailwindcss": "^3.4.3",
"typescript": "^5.4.5",
"vite": "^5.2.10",
"vite-plugin-pwa": "^0.20.0"
}
}

10506
pnpm-lock.yaml generated Normal file

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 9.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

@@ -1,18 +1,14 @@
import { ThemeProvider } from '@mui/material';
import { LifeTrinket } from './Components/LifeTrinket';
import { theme } from './Data/theme';
import { GlobalSettingsProvider } from './Providers/GlobalSettingsProvider';
import { PlayersProvider } from './Providers/PlayersProvider';
const App = () => {
return (
<ThemeProvider theme={theme}>
<PlayersProvider>
<GlobalSettingsProvider>
<LifeTrinket />
</GlobalSettingsProvider>
</PlayersProvider>
</ThemeProvider>
<PlayersProvider>
<GlobalSettingsProvider>
<LifeTrinket />
</GlobalSettingsProvider>
</PlayersProvider>
);
};

View File

@@ -17,6 +17,8 @@ export type RotationButtonProps = TwcComponentProps<'button'> & {
$rotation?: number;
};
export const MAX_TAP_MOVE_DISTANCE = 20;
const CommanderDamageContainer = twc.div<RotationDivProps>((props) => [
'flex flex-grow',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
@@ -38,7 +40,7 @@ const CommanderDamageTextContainer = twc.div<RotationDivProps>((props) => [
: '',
]);
const PartnerDamageSeperator = twc.div<RotationDivProps>((props) => [
const PartnerDamageSeparator = twc.div<RotationDivProps>((props) => [
'bg-black',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
? 'w-full h-px'
@@ -54,6 +56,7 @@ type CommanderDamageButtonComponentProps = {
type InputProps = {
opponentIndex: number;
isPartner: boolean;
event: React.PointerEvent<HTMLButtonElement>;
};
export const CommanderDamage = ({
@@ -63,8 +66,8 @@ export const CommanderDamage = ({
}: CommanderDamageButtonComponentProps) => {
const { updatePlayer } = usePlayers();
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
const [timeoutFinished, setTimeoutFinished] = useState(false);
const [hasPressedDown, setHasPressedDown] = useState(false);
const [downLongPressed, setDownLongPressed] = useState(false);
const downPositionRef = useRef({ x: 0, y: 0 });
const handleCommanderDamageChange = (
index: number,
@@ -103,28 +106,41 @@ export const CommanderDamage = ({
handleLifeChange(player.lifeTotal - increment);
};
const handleDownInput = ({ opponentIndex, isPartner }: InputProps) => {
setTimeoutFinished(false);
setHasPressedDown(true);
const handleDownInput = ({ opponentIndex, isPartner, event }: InputProps) => {
downPositionRef.current = { x: event.clientX, y: event.clientY };
setDownLongPressed(false);
timeoutRef.current = setTimeout(() => {
setTimeoutFinished(true);
setDownLongPressed(true);
handleCommanderDamageChange(opponentIndex, -1, isPartner);
}, decrementTimeoutMs);
};
const handleUpInput = ({ opponentIndex, isPartner }: InputProps) => {
if (!(hasPressedDown && !timeoutFinished)) {
const handleUpInput = ({ opponentIndex, isPartner, event }: InputProps) => {
if (downLongPressed) {
return;
}
const upPosition = { x: event.clientX, y: event.clientY };
const hasMoved =
Math.abs(upPosition.x - downPositionRef.current.x) >
MAX_TAP_MOVE_DISTANCE ||
Math.abs(upPosition.y - downPositionRef.current.y) >
MAX_TAP_MOVE_DISTANCE;
if (hasMoved) {
return;
}
clearTimeout(timeoutRef.current);
handleCommanderDamageChange(opponentIndex, 1, isPartner);
setHasPressedDown(false);
};
const handleLeaveInput = () => {
setTimeoutFinished(true);
setDownLongPressed(true);
clearTimeout(timeoutRef.current);
setHasPressedDown(false);
};
const opponentIndex = opponent.index;
@@ -141,10 +157,12 @@ export const CommanderDamage = ({
<CommanderDamageButton
key={opponentIndex}
$rotation={player.settings.rotation}
onPointerDown={() =>
handleDownInput({ opponentIndex, isPartner: false })
onPointerDown={(e) =>
handleDownInput({ opponentIndex, isPartner: false, event: e })
}
onPointerUp={(e) =>
handleUpInput({ opponentIndex, isPartner: false, event: e })
}
onPointerUp={() => handleUpInput({ opponentIndex, isPartner: false })}
onPointerLeave={handleLeaveInput}
onContextMenu={(e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault();
@@ -167,15 +185,15 @@ export const CommanderDamage = ({
{opponent.settings.usePartner && (
<>
<PartnerDamageSeperator $rotation={player.settings.rotation} />
<PartnerDamageSeparator $rotation={player.settings.rotation} />
<CommanderDamageButton
key={opponentIndex}
$rotation={player.settings.rotation}
onPointerDown={() =>
handleDownInput({ opponentIndex, isPartner: true })
onPointerDown={(e) =>
handleDownInput({ opponentIndex, isPartner: true, event: e })
}
onPointerUp={() =>
handleUpInput({ opponentIndex, isPartner: true })
onPointerUp={(e) =>
handleUpInput({ opponentIndex, isPartner: true, event: e })
}
onPointerLeave={handleLeaveInput}
onContextMenu={(

View File

@@ -3,7 +3,7 @@ import { twc } from 'react-twc';
import { decrementTimeoutMs } from '../../Data/constants';
import { CounterType, Rotation } from '../../Types/Player';
import { OutlinedText } from '../Misc/OutlinedText';
import { RotationDivProps } from './CommanderDamage';
import { MAX_TAP_MOVE_DISTANCE, RotationDivProps } from './CommanderDamage';
const ExtraCounterContainer = twc.div`
flex
@@ -63,6 +63,7 @@ const ExtraCounter = ({
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
const [timeoutFinished, setTimeoutFinished] = useState(false);
const [hasPressedDown, setHasPressedDown] = useState(false);
const downPositionRef = useRef({ x: 0, y: 0 });
const handleCountChange = (increment: number) => {
if (!counterTotal) {
@@ -72,7 +73,8 @@ const ExtraCounter = ({
setCounterTotal(counterTotal + increment, type);
};
const handleDownInput = () => {
const handleDownInput = (event: React.PointerEvent<HTMLButtonElement>) => {
downPositionRef.current = { x: event.clientX, y: event.clientY };
setTimeoutFinished(false);
setHasPressedDown(true);
timeoutRef.current = setTimeout(() => {
@@ -81,10 +83,23 @@ const ExtraCounter = ({
}, decrementTimeoutMs);
};
const handleUpInput = () => {
const handleUpInput = (event: React.PointerEvent<HTMLButtonElement>) => {
if (!(hasPressedDown && !timeoutFinished)) {
return;
}
const upPosition = { x: event.clientX, y: event.clientY };
const hasMoved =
Math.abs(upPosition.x - downPositionRef.current.x) >
MAX_TAP_MOVE_DISTANCE ||
Math.abs(upPosition.y - downPositionRef.current.y) >
MAX_TAP_MOVE_DISTANCE;
if (hasMoved) {
return;
}
clearTimeout(timeoutRef.current);
handleCountChange(1);
setHasPressedDown(false);

View File

@@ -1,7 +1,9 @@
import { useRef, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { TwcComponentProps, twc } from 'react-twc';
import { lifeLongPressMultiplier } from '../../Data/constants';
import { Rotation } from '../../Types/Player';
import { Player, Rotation } from '../../Types/Player';
import { MAX_TAP_MOVE_DISTANCE } from './CommanderDamage';
import { checkContrast } from '../../Utils/checkContrast';
type RotationButtonProps = TwcComponentProps<'div'> & {
$align?: string;
@@ -12,7 +14,6 @@ const LifeCounterButtonTwc = twc.button`
h-full
w-full
flex
text-lifeCounter-text
font-semibold
bg-transparent
border-none
@@ -39,29 +40,41 @@ const TextContainer = twc.div<RotationButtonProps>((props) => [
]);
type LifeCounterButtonProps = {
lifeTotal: number;
player: Player;
setLifeTotal: (lifeTotal: number) => void;
rotation: number;
operation: 'add' | 'subtract';
increment: number;
};
const LifeCounterButton = ({
lifeTotal,
player,
setLifeTotal,
rotation,
operation,
increment,
}: LifeCounterButtonProps) => {
const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
const [timeoutFinished, setTimeoutFinished] = useState(false);
const [hasPressedDown, setHasPressedDown] = useState(false);
const downPositionRef = useRef({ x: 0, y: 0 });
const [iconColor, setIconColor] = useState<'dark' | 'light'>('dark');
useEffect(() => {
const contrast = checkContrast(player.color, '#00000080');
if (contrast === 'Fail') {
setIconColor('light');
} else {
setIconColor('dark');
}
}, [player.color]);
const handleLifeChange = (increment: number) => {
setLifeTotal(lifeTotal + increment);
setLifeTotal(player.lifeTotal + increment);
};
const handleDownInput = () => {
const handleDownInput = (event: React.PointerEvent<HTMLButtonElement>) => {
downPositionRef.current = { x: event.clientX, y: event.clientY };
setTimeoutFinished(false);
setHasPressedDown(true);
timeoutRef.current = setTimeout(() => {
@@ -70,10 +83,23 @@ const LifeCounterButton = ({
}, 500);
};
const handleUpInput = () => {
const handleUpInput = (event: React.PointerEvent<HTMLButtonElement>) => {
if (!(hasPressedDown && !timeoutFinished)) {
return;
}
const upPosition = { x: event.clientX, y: event.clientY };
const hasMoved =
Math.abs(upPosition.x - downPositionRef.current.x) >
MAX_TAP_MOVE_DISTANCE ||
Math.abs(upPosition.y - downPositionRef.current.y) >
MAX_TAP_MOVE_DISTANCE;
if (hasMoved) {
return;
}
clearTimeout(timeoutRef.current);
handleLifeChange(operation === 'add' ? 1 : -1);
setHasPressedDown(false);
@@ -86,7 +112,8 @@ const LifeCounterButton = ({
};
const fontSize =
rotation === Rotation.SideFlipped || rotation === Rotation.Side
player.settings.rotation === Rotation.SideFlipped ||
player.settings.rotation === Rotation.Side
? '8vmax'
: '12vmin';
@@ -102,8 +129,11 @@ const LifeCounterButton = ({
aria-label={`${operation === 'add' ? 'Add' : 'Subtract'} life`}
>
<TextContainer
$rotation={rotation}
$rotation={player.settings.rotation}
$align={operation === 'add' ? 'right' : 'left'}
data-contrast={iconColor}
className="data-[contrast=dark]:text-icons-dark
data-[contrast=light]:text-icons-light"
>
{operation === 'add' ? '\u002B' : '\u2212'}
</TextContainer>

View File

@@ -7,7 +7,7 @@ const LoseButton = twc.div<RotationDivProps>((props) => [
'absolute flex-grow border-none outline-none cursor-pointer bg-interface-loseButton-background rounded-lg select-none z-[1] webkit-user-select-none py-2 px-4 ',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
? `left-[19%]`
? `left-[21%]`
: 'top-[21%]',
]);

View File

@@ -1,30 +0,0 @@
import { twc } from 'react-twc';
import { Cog } from '../../Icons/generated';
import { Rotation } from '../../Types/Player';
import { RotationButtonProps } from './CommanderDamage';
const SettingsButtonTwc = twc.button<RotationButtonProps>((props) => [
'absolute flex-grow border-none outline-none cursor-pointer bg-transparent z-[1] select-none webkit-user-select-none',
props.$rotation === Rotation.Side || props.$rotation === Rotation.SideFlipped
? `right-auto top-[1vmax] left-[27%]`
: 'top-1/4 right-[1vmax]',
]);
type SettingsButtonProps = {
onClick: () => void;
rotation: Rotation;
};
const SettingsButton = ({ onClick, rotation }: SettingsButtonProps) => {
return (
<SettingsButtonTwc
onClick={onClick}
$rotation={rotation}
aria-label={`Settings`}
>
<Cog size="5vmin" color="black" opacity="0.3" />
</SettingsButtonTwc>
);
};
export default SettingsButton;

View File

@@ -10,6 +10,8 @@ import {
import { CounterType, Player, Rotation } from '../../Types/Player';
import { RotationDivProps } from '../Buttons/CommanderDamage';
import ExtraCounter from '../Buttons/ExtraCounter';
import { useEffect, useState } from 'react';
import { checkContrast } from '../../Utils/checkContrast';
const Container = twc.div<RotationDivProps>((props) => [
'flex',
@@ -19,9 +21,9 @@ const Container = twc.div<RotationDivProps>((props) => [
]);
export const ExtraCountersGrid = twc.div<RotationDivProps>((props) => [
'flex absolute flex-row flex-grow pointer-events-none',
'flex absolute flex-row flex-grow pointer-events-none overflow-x-scroll overflow-y-hidden',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
? 'flex-col-reverse h-full w-auto bottom-auto'
? 'flex-col-reverse h-full w-auto bottom-auto right-0'
: 'w-full bottom-0',
]);
@@ -31,6 +33,17 @@ type ExtraCountersBarProps = {
const ExtraCountersBar = ({ player }: ExtraCountersBarProps) => {
const { updatePlayer } = usePlayers();
const [iconColor, setIconColor] = useState<'dark' | 'light'>('dark');
useEffect(() => {
const contrast = checkContrast(player.color, '#00000080');
if (contrast === 'Fail') {
setIconColor('light');
} else {
setIconColor('dark');
}
}, [player.color]);
const handleCounterChange = (
updatedCounterTotal: number,
@@ -93,7 +106,13 @@ const ExtraCountersBar = ({ player }: ExtraCountersBarProps) => {
{useCommanderDamage && (
<ExtraCounter
rotation={player.settings.rotation}
Icon={<CommanderTax size={iconSize} opacity="0.5" color="black" />}
Icon={
<CommanderTax
size={iconSize}
data-contrast={iconColor}
className="data-[contrast=dark]:text-icons-dark data-[contrast=light]:text-icons-light"
/>
}
type={CounterType.CommanderTax}
counterTotal={
player.extraCounters?.find(
@@ -108,7 +127,13 @@ const ExtraCountersBar = ({ player }: ExtraCountersBarProps) => {
{Boolean(useCommanderDamage && usePartner) && (
<ExtraCounter
rotation={player.settings.rotation}
Icon={<PartnerTax size={iconSize} opacity="0.5" color="black" />}
Icon={
<PartnerTax
size={iconSize}
data-contrast={iconColor}
className="data-[contrast=dark]:text-icons-dark data-[contrast=light]:text-icons-light"
/>
}
type={CounterType.PartnerTax}
counterTotal={
player.extraCounters?.find(
@@ -123,7 +148,13 @@ const ExtraCountersBar = ({ player }: ExtraCountersBarProps) => {
{usePoison && (
<ExtraCounter
rotation={player.settings.rotation}
Icon={<Poison size={iconSize} opacity="0.5" color="black" />}
Icon={
<Poison
size={iconSize}
data-contrast={iconColor}
className="data-[contrast=dark]:text-icons-dark data-[contrast=light]:text-icons-light"
/>
}
type={CounterType.Poison}
counterTotal={
player.extraCounters?.find((counter) => counter.type === 'poison')
@@ -137,7 +168,13 @@ const ExtraCountersBar = ({ player }: ExtraCountersBarProps) => {
{useEnergy && (
<ExtraCounter
rotation={player.settings.rotation}
Icon={<Energy size={iconSize} opacity="0.5" color="black" />}
Icon={
<Energy
size={iconSize}
data-contrast={iconColor}
className="data-[contrast=dark]:text-icons-dark data-[contrast=light]:text-icons-light"
/>
}
type={CounterType.Energy}
counterTotal={
player.extraCounters?.find((counter) => counter.type === 'energy')
@@ -151,7 +188,13 @@ const ExtraCountersBar = ({ player }: ExtraCountersBarProps) => {
{useExperience && (
<ExtraCounter
rotation={player.settings.rotation}
Icon={<Experience size={iconSize} opacity="0.5" color="black" />}
Icon={
<Experience
size={iconSize}
data-contrast={iconColor}
className="data-[contrast=dark]:text-icons-dark data-[contrast=light]:text-icons-light"
/>
}
type={CounterType.Experience}
counterTotal={
player.extraCounters?.find(

View File

@@ -0,0 +1,64 @@
import { useEffect } from 'react';
import { Close } from '../../Icons/generated';
import { useAnalytics } from '../../Hooks/useAnalytics';
import { Separator } from '../Misc/Separator';
export const Dialog: React.FC<{
id: string;
title?: string;
children: React.ReactNode;
dialogRef: React.MutableRefObject<HTMLDialogElement | null>;
}> = ({ id, title, children, dialogRef }) => {
const analytics = useAnalytics();
useEffect(() => {
if (!dialogRef.current) {
return;
}
dialogRef.current.addEventListener('click', (e) => {
const dialogDimensions = dialogRef.current!.getBoundingClientRect();
if (
(e.clientX < dialogDimensions.left ||
e.clientX > dialogDimensions.right ||
e.clientY < dialogDimensions.top ||
e.clientY > dialogDimensions.bottom) &&
dialogRef.current?.open
) {
analytics.trackEvent(`${id}_outside_clicked`);
dialogRef.current?.close();
}
});
});
return (
<dialog
id={id}
ref={dialogRef}
className="backdrop:bg-background-backdrop border-none backdrop:backdrop-blur-[1px] open:visible invisible bg-transparent overflow-visible my-0 justify-self-center top-[10%]"
>
<button
onClick={() => {
analytics.trackEvent(`${id}_cross_clicked`);
dialogRef.current?.close();
}}
className="flex absolute -top-2 right-2 z-10 w-10 h-10 bg-background-default rounded-full"
>
<Close className="text-primary-main size-full" />
</button>
<div className="bg-background-default rounded-2xl max-w-[548px] max-h-[80vh] flex flex-col">
{title && (
<div className="text-2xl text-center text-text-primary px-8 pt-4">
<h2 className="">{title}</h2>
<Separator height="1px" />
</div>
)}
<div className="h-full overflow-auto text-text-primary show-scrollbar px-8 pb-8">
{children}
</div>
</div>
</dialog>
);
};

View File

@@ -0,0 +1,106 @@
import { useAnalytics } from '../../Hooks/useAnalytics';
import { BuyMeCoffee } from '../../Icons/generated/Support';
import { Separator } from '../Misc/Separator';
import { Paragraph } from '../Misc/TextComponents';
import { Dialog } from './Dialog';
export const InfoDialog = ({
dialogRef,
}: {
dialogRef: React.MutableRefObject<HTMLDialogElement | null>;
}) => {
const analytics = useAnalytics();
return (
<Dialog id="info" title="Info" dialogRef={dialogRef}>
<div className=" text-text-primary">
<h2 className="text-md underline">Contributors</h2>
<div className="flex flex-row items-center gap-1 text-sm">
{/* <Trinket className="size-4" /> */}
<a href="#">Elin:</a> Icon design
</div>
<Separator height="1px" />
</div>
<div className="text-text-primary mt-4">
<div className="text">
<h2 className="text-xl">📋 Usage Guide</h2>
<Separator height="1px" />
</div>
<div className="text-text-primary">
<Paragraph className="mb-4">
There are some controls that you might not know about, so here's a
short list of them.
</Paragraph>
<h3 className="text-lg font-bold mb-2">Life counter</h3>
<ul className="list-disc ml-6 mb-4">
<li>
<strong>Tap</strong> on a player's + or - button to add or
subtract <strong>1 life</strong>.
</li>
<li>
<strong>Long press</strong> on a player's + or - button to add or
subtract <strong>10 life</strong>.
</li>
</ul>
<h3 className="text-lg font-bold mb-2">
Commander damage and other counters
</h3>
<ul className="list-disc ml-6 mb-4">
<li>
<strong>Tap</strong> on the counter to add{' '}
<strong>1 counter</strong>.
</li>
<li>
<strong>Long press</strong> on the counter to subtract{' '}
<strong>1 counter</strong>.
</li>
</ul>
<h3 className="text-lg font-bold mb-2">Other functionality</h3>
<ul className="list-disc ml-6">
<li>
<Paragraph className="mb-1">
When a player is <strong>at or below 0 life</strong>, has taken{' '}
<strong>21 or more Commander Damage</strong> or has{' '}
<strong>10 or more poison counters</strong>, a button with a
skull will appear on that player's card. Tapping it will dim the
player's card.
</Paragraph>
</li>
<li>
<Paragraph className="mb-4">
Swiping <strong>down</strong> on a player's card will show that
player's settings menu.
</Paragraph>
</li>
</ul>
</div>
</div>
<div className="text-center mt-4 text-text-primary">
Visit my{' '}
<a
href="https://github.com/Vikeo/LifeTrinket"
target="_blank"
className="text-text-secondary underline"
>
GitHub
</a>{' '}
for more info about this web app.
</div>
<div className="flex justify-center mt-4">
<a
className="flex flex-row items-center self-center border-none cursor-pointer bg-primary-main rounded-md mx-4 pr-4 pl-3 py-2 transition-colors duration-200 ease-in-out shadow-[1px_2px_4px_0px_rgba(0,0,0,0.3)] hover:bg-primary-dark"
onClick={() => {
analytics.trackEvent('click_bmc');
}}
href="https://www.buymeacoffee.com/vikeo"
target="_blank"
>
<BuyMeCoffee height="1.5rem" width="1.5rem" className="mr-2" />
<Paragraph className="text-xs">Buy me a tea</Paragraph>
</a>
</div>
</Dialog>
);
};

View File

@@ -0,0 +1,278 @@
import { twc } from 'react-twc';
import { useAnalytics } from '../../Hooks/useAnalytics';
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { PreStartMode } from '../../Types/Settings';
import { Separator } from '../Misc/Separator';
import { Paragraph } from '../Misc/TextComponents';
import { ToggleButton } from '../Misc/ToggleButton';
import { Dialog } from './Dialog';
const SettingContainer = twc.div`w-full flex flex-col mb-2`;
const ToggleContainer = twc.div`flex flex-row justify-between items-center -mb-1`;
const Description = twc.p`mr-16 text-xs text-left text-text-secondary mt-1`;
const baseGithubReleasesUrl =
'https://github.com/Vikeo/LifeTrinket/releases/tag/';
export const SettingsDialog = ({
dialogRef,
}: {
dialogRef: React.MutableRefObject<HTMLDialogElement | null>;
}) => {
const { settings, setSettings, isPWA, version } = useGlobalSettings();
const analytics = useAnalytics();
return (
<Dialog id="settings" title="⚙️ Settings ⚙️" dialogRef={dialogRef}>
<div className="flex flex-col mb-2 w-full">
<div className="text-text-primary flex items-center gap-2">
Current version: {version.installedVersion}{' '}
{version.isLatest && (
<span className="text-sm text-text-secondary">(latest)</span>
)}
<div className="text-xs text-text-primary opacity-75">
(
<a
href={baseGithubReleasesUrl + version.installedVersion}
target="_blank"
className="underline"
onClick={() => {
analytics.trackEvent(
`current_change_log_clicked_v${version.installedVersion}`
);
}}
>
Release notes
</a>
)
</div>
</div>
{!version.isLatest && version.remoteVersion && (
<>
<div className="flex gap-2 items-center mt-2">
<Paragraph className="text-text-secondary">
{version.remoteVersion} available!
</Paragraph>
<div className="text-xs text-text-primary opacity-75">
(
<a
href={baseGithubReleasesUrl + version.remoteVersion}
target="_blank"
className="underline"
onClick={() => {
analytics.trackEvent(
`new_change_log_clicked_v${version.remoteVersion}`
);
}}
>
Release notes
</a>
)
</div>
</div>
<button
className="flex justify-center items-center self-start mt-2 bg-primary-main px-3 py-1 rounded-md"
onClick={() => {
{
analytics.trackEvent(`pressed_update`, {
toVersion: version.remoteVersion,
fromVersion: version.installedVersion,
});
window?.location?.reload();
}
}}
>
<span className="text-sm">Update</span>
<span className="text-xs">&nbsp;(reload app)</span>
</button>
</>
)}
</div>
<Separator height="1px" />
<SettingContainer>
<ToggleContainer>
<label>Show Player Menu Cog</label>
<ToggleButton
checked={settings.showPlayerMenuCog}
onChange={() => {
setSettings({
...settings,
showPlayerMenuCog: !settings.showPlayerMenuCog,
});
}}
/>
</ToggleContainer>
<Description>
A cog on the top right of each player's card will be shown if this is
enabled.
</Description>
</SettingContainer>
<SettingContainer>
<ToggleContainer>
<label>Show Start Player</label>
<ToggleButton
checked={settings.showStartingPlayer}
onChange={() => {
setSettings({
...settings,
showStartingPlayer: !settings.showStartingPlayer,
});
}}
/>
</ToggleContainer>
<Description>
On start or reset of game, will pick a random starting player,
according to the <b>Pre-Start mode</b>
</Description>
</SettingContainer>
<SettingContainer>
<div className="flex flex-row justify-between items-center mb-1">
<label htmlFor="pre-start-modes">Player selection style</label>
<select
name="pre-start-modes"
id="pre-start-modes"
value={settings.preStartMode}
className="bg-secondary-main border-none outline-none text-text-primary rounded-md p-1 text-xs disabled:saturate-50 font-semibold"
onChange={(e) => {
setSettings({
...settings,
preStartMode: e.target.value as PreStartMode,
});
}}
disabled={!settings.showStartingPlayer}
>
<option value={PreStartMode.None}>Instant</option>
<option value={PreStartMode.RandomKing}>Royal Shuffle</option>
<option value={PreStartMode.FingerGame}>Touch Roulette</option>
<option value={PreStartMode.Trivia}>Group Trivia</option>
</select>
</div>
<div className="text-xs text-left text-text-secondary">
Different ways to determine the starting player before the game
starts.
</div>
{settings.preStartMode === PreStartMode.None && (
<div className="text-xs text-left text-text-secondary mt-1">
<span className="text-text-primary">Instant:</span> A random
starting player will simply be shown on start.
</div>
)}
{settings.preStartMode === PreStartMode.RandomKing && (
<div className="text-xs text-left text-text-secondary mt-1">
<span className="text-text-primary">Royal Shuffle:</span> Randomly
pass a crown between all players, press the screen to stop it. The
player who has the crown when it stops gets to start.
</div>
)}
{settings.preStartMode === PreStartMode.FingerGame && (
<div className="text-xs text-left text-text-secondary mt-1">
<span className="text-text-primary">Touch Roulette:</span> All
players put a finger on the screen, one will be chosen at random.
</div>
)}
{settings.preStartMode === PreStartMode.Trivia && (
<div className="text-xs text-left text-text-secondary mt-1">
<span className="text-text-primary">Group Trivia:</span> A random
"who is the most ..." type question will be shown, the group decides
which player fits the question best.
</div>
)}
</SettingContainer>
<SettingContainer>
<ToggleContainer>
<label>Keep Awake</label>
<ToggleButton
checked={settings.keepAwake}
onChange={() => {
setSettings({
...settings,
keepAwake: !settings.keepAwake,
});
}}
/>
</ToggleContainer>
<Description>
Will prevent device from going to sleep while this app is open if this
is enabled.
</Description>
</SettingContainer>
<SettingContainer>
<ToggleContainer>
<label>
Fullscreen on start <span className="text-xs">(Android only)</span>
</label>
<ToggleButton
checked={settings.goFullscreenOnStart}
onChange={() => {
setSettings({
...settings,
goFullscreenOnStart: !settings.goFullscreenOnStart,
});
}}
/>
</ToggleContainer>
<Description>
Will enter fullscreen mode when starting a game if this is enabled.
</Description>
</SettingContainer>
<SettingContainer>
<ToggleContainer>
<label>Show animations</label>
<ToggleButton
checked={settings.showAnimations}
onChange={() => {
setSettings({
...settings,
showAnimations: !settings.showAnimations,
});
}}
/>
</ToggleContainer>
<Description>
Disables the following animation:
<ul className="pl-1 list-inside">
<li className="list-disc">Glow effect on start menu</li>
</ul>
</Description>
</SettingContainer>
<Separator height="1px" />
<div className="flex w-full justify-center">
<button
className="mt-1 mb-1 bg-primary-main px-3 py-1 rounded-md duration-200 ease-in-out shadow-[1px_2px_4px_0px_rgba(0,0,0,0.3)] hover:bg-primary-dark font-bold"
onClick={() => {
analytics.trackEvent('settings_save_clicked');
dialogRef.current?.close();
}}
>
<span className="text-sm">Save and Close</span>
</button>
</div>
{!isPWA && (
<>
<Separator height="1px" />
<SettingContainer>
<ToggleContainer>
<Paragraph>
<b>Tip:</b> You can{' '}
<b>add this webapp to your home page on iOS</b> or{' '}
<b>install it on Android</b> to have it act just like a normal
app!
</Paragraph>
</ToggleContainer>
<Description className="mt-1">
If you do, this app will work offline and the toolbar will be
automatically hidden.
</Description>
</SettingContainer>
</>
)}
<Separator height="1px" />
</Dialog>
);
};

View File

@@ -53,23 +53,9 @@ const Health = ({
differenceKey,
recentDifference,
}: HealthProps) => {
const [showStartingPlayer, setShowStartingPlayer] = useState(
localStorage.getItem('playing') === 'true'
);
const [fontSize, setFontSize] = useState(16);
const textContainerRef = useRef<HTMLDivElement | null>(null);
useEffect(() => {
if (!showStartingPlayer) {
const playingTimer = setTimeout(() => {
localStorage.setItem('playing', 'true');
setShowStartingPlayer(localStorage.getItem('playing') === 'true');
}, 3_000);
return () => clearTimeout(playingTimer);
}
}, [showStartingPlayer]);
useEffect(() => {
if (!textContainerRef.current) {
return;
@@ -118,9 +104,8 @@ const Health = ({
return (
<LifeContainer $rotation={player.settings.rotation}>
<LifeCounterButton
lifeTotal={player.lifeTotal}
player={player}
setLifeTotal={handleLifeChange}
rotation={player.settings.rotation}
operation="subtract"
increment={-1}
/>
@@ -148,9 +133,8 @@ const Health = ({
</LifeCounterTextContainer>
</TextWrapper>
<LifeCounterButton
lifeTotal={player.lifeTotal}
player={player}
setLifeTotal={handleLifeChange}
rotation={player.settings.rotation}
operation="add"
increment={1}
/>

View File

@@ -1,16 +1,64 @@
import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { useSwipeable } from 'react-swipeable';
import { twc } from 'react-twc';
import { useAnalytics } from '../../Hooks/useAnalytics';
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { usePlayers } from '../../Hooks/usePlayers';
import { Cog } from '../../Icons/generated';
import { Player, Rotation } from '../../Types/Player';
import { RotationDivProps } from '../Buttons/CommanderDamage';
import { checkContrast } from '../../Utils/checkContrast';
import {
RotationButtonProps,
RotationDivProps,
} from '../Buttons/CommanderDamage';
import { LoseGameButton } from '../Buttons/LoseButton';
import CommanderDamageBar from '../Counters/CommanderDamageBar';
import ExtraCountersBar from '../Counters/ExtraCountersBar';
import PlayerMenu from '../Player/PlayerMenu';
import PlayerMenu from '../Players/PlayerMenu';
import { StartingPlayerCard } from '../PreStartGame/StartingPlayerCard';
import Health from './Health';
const SettingsButtonTwc = twc.button<RotationButtonProps>((props) => [
'absolute flex-grow border-none outline-none cursor-pointer bg-transparent z-[1] select-none webkit-user-select-none',
props.$rotation === Rotation.Side || props.$rotation === Rotation.SideFlipped
? `right-auto top-[1vmax] left-[27%]`
: 'top-1/4 right-[1vmax]',
]);
type SettingsButtonProps = {
onClick: () => void;
rotation: Rotation;
color: string;
};
const SettingsButton = ({ onClick, rotation, color }: SettingsButtonProps) => {
const [iconColor, setIconColor] = useState<'dark' | 'light'>('dark');
useEffect(() => {
const contrast = checkContrast(color, '#00000080');
if (contrast === 'Fail') {
setIconColor('light');
} else {
setIconColor('dark');
}
}, [color]);
return (
<SettingsButtonTwc
onClick={onClick}
$rotation={rotation}
aria-label={`Settings`}
>
<Cog
size="5vmin"
data-contrast={iconColor}
className="data-[contrast=dark]:text-icons-dark data-[contrast=light]:text-icons-light"
/>
</SettingsButtonTwc>
);
};
const LifeCounterContentWrapper = twc.div`
relative flex flex-grow flex-col items-center w-full h-full overflow-hidden`;
@@ -21,8 +69,6 @@ const LifeCounterWrapper = twc.div<RotationDivProps>((props) => [
: `flex-col`,
]);
const StartingPlayerNoticeWrapper = twc.div`z-[1] flex absolute w-full h-full justify-center items-center pointer-events-none select-none webkit-user-select-none bg-primary-main`;
const PlayerLostWrapper = twc.div<RotationDivProps>((props) => [
'z-[1] flex absolute w-full h-full justify-center items-center pointer-events-none select-none webkit-user-select-none bg-lifeCounter-lostWrapper opacity-75',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
@@ -30,8 +76,6 @@ const PlayerLostWrapper = twc.div<RotationDivProps>((props) => [
: '',
]);
const DynamicText = twc.div`text-[8vmin] whitespace-nowrap`;
const hasCommanderDamageReached21 = (player: Player) => {
const commanderDamageTotals = player.commanderDamage.map(
(commanderDamage) => commanderDamage.damageTotal
@@ -62,11 +106,17 @@ const playerCanLose = (player: Player) => {
type LifeCounterProps = {
player: Player;
opponents: Player[];
isStartingPlayer?: boolean;
};
const RECENT_DIFFERENCE_TTL = 3_000;
const LifeCounter = ({ player, opponents }: LifeCounterProps) => {
const { updatePlayer, updateLifeTotal } = usePlayers();
const { settings } = useGlobalSettings();
const { settings, playing } = useGlobalSettings();
const recentDifferenceTimerRef = useRef<NodeJS.Timeout | undefined>(
undefined
);
const [showPlayerMenu, setShowPlayerMenu] = useState(false);
const [recentDifference, setRecentDifference] = useState(0);
@@ -81,54 +131,56 @@ const LifeCounter = ({ player, opponents }: LifeCounterProps) => {
const handlers = useSwipeable({
trackMouse: true,
onSwipedDown: () => {
console.log(`User DOWN Swiped on player ${player.index}`);
onSwipedDown: (e) => {
e.event.stopPropagation();
analytics.trackEvent('open_player_menu_swipe');
setShowPlayerMenu(true);
},
onSwipedUp: () => {
console.log(`User UP Swiped on player ${player.index}`);
onSwipedUp: (e) => {
e.event.stopPropagation();
analytics.trackEvent('close_player_menu_swipe');
setShowPlayerMenu(false);
},
swipeDuration: 500,
onSwiping: (eventData) => console.log(eventData),
onSwiping: (e) => e.event.stopPropagation(),
rotationAngle,
});
const analytics = useAnalytics();
useEffect(() => {
const timer = setTimeout(() => {
setRecentDifference(0);
}, 3_000);
if (recentDifference === 0) {
clearTimeout(recentDifferenceTimerRef.current);
return;
}
recentDifferenceTimerRef.current = setTimeout(() => {
analytics.trackEvent('life_changed', {
lifeChangedAmount: recentDifference,
});
setRecentDifference(0);
}, RECENT_DIFFERENCE_TTL);
return () => {
clearTimeout(recentDifferenceTimerRef.current);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [recentDifference]);
useEffect(() => {
const resizeObserver = new ResizeObserver(() => {
if (document.body.clientWidth > document.body.clientHeight)
setIsLandscape(true);
else setIsLandscape(false);
return;
return () => {
// Cleanup: disconnect the ResizeObserver when the component unmounts.
resizeObserver.disconnect();
};
});
resizeObserver.observe(document.body);
return () => {
clearTimeout(timer);
// Cleanup: disconnect the ResizeObserver when the component unmounts.
resizeObserver.disconnect();
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [recentDifference, document.body.clientHeight, document.body.clientWidth]);
useEffect(() => {
if (player.showStartingPlayer) {
const playingTimer = setTimeout(() => {
localStorage.setItem('playing', 'true');
player.showStartingPlayer = false;
updatePlayer(player);
}, 3_000);
return () => clearTimeout(playingTimer);
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [player.showStartingPlayer]);
}, [document.body.clientHeight, document.body.clientWidth]);
player.settings.rotation === Rotation.SideFlipped ||
player.settings.rotation === Rotation.Side;
@@ -150,11 +202,7 @@ const LifeCounter = ({ player, opponents }: LifeCounterProps) => {
? player.settings.rotation - 90
: player.settings.rotation;
const calcTextRotation =
player.settings.rotation === Rotation.SideFlipped ||
player.settings.rotation === Rotation.Side
? player.settings.rotation - 180
: player.settings.rotation;
const amountOfPlayers = opponents.length + 1;
return (
<LifeCounterContentWrapper style={{ background: player.color }}>
@@ -163,31 +211,31 @@ const LifeCounter = ({ player, opponents }: LifeCounterProps) => {
style={{ rotate: `${calcRotation}deg` }}
{...handlers}
>
{settings.showStartingPlayer &&
player.isStartingPlayer &&
player.showStartingPlayer && (
<StartingPlayerNoticeWrapper
style={{ rotate: `${calcRotation}deg` }}
>
<DynamicText
style={{
rotate: `${calcTextRotation}deg`,
}}
>
You start!
</DynamicText>
</StartingPlayerNoticeWrapper>
)}
{amountOfPlayers > 1 &&
!playing &&
settings.showStartingPlayer &&
player.isStartingPlayer && <StartingPlayerCard player={player} />}
{player.hasLost && (
<PlayerLostWrapper $rotation={player.settings.rotation} />
)}
<CommanderDamageBar
opponents={opponents}
player={player}
key={player.index}
handleLifeChange={handleLifeChange}
/>
{settings.showPlayerMenuCog && (
<SettingsButton
onClick={() => {
analytics.trackEvent('open_player_menu_button');
setShowPlayerMenu(!showPlayerMenu);
}}
rotation={player.settings.rotation}
color={player.color}
/>
)}
{playerCanLose(player) && (
<LoseGameButton
rotation={player.settings.rotation}

View File

@@ -0,0 +1,31 @@
export const IconCheckbox = ({
name,
icon,
checkedIcon,
checked,
onChange,
className,
}: {
name: string;
icon: JSX.Element;
checkedIcon: JSX.Element;
checked: boolean;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
className?: string;
}) => {
return (
<div className={className}>
<label>
<input
name={name}
type="checkbox"
checked={checked}
onChange={onChange}
className="sr-only peer"
/>
<div className="peer-checked:hidden block">{icon}</div>
<div className="peer-checked:block hidden">{checkedIcon}</div>
</label>
</div>
);
};

View File

@@ -1,88 +0,0 @@
import { Modal } from '@mui/material';
import { twc } from 'react-twc';
import { Separator } from './Separator';
import { Paragraph } from './TextComponents';
export const ModalWrapper = twc.div`absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 h-[85vh] bg-background-default p-4 overflow-scroll rounded-2xl border-none text-text-primary w-[95vw] max-w-[548px]`;
type InfoModalProps = {
isOpen: boolean;
closeModal: () => void;
};
export const InfoModal = ({ isOpen, closeModal }: InfoModalProps) => {
return (
<Modal
open={isOpen}
onClose={closeModal}
style={{ display: 'flex', justifyContent: 'center' }}
>
<>
<div className="flex relative w-full max-w-[548px]">
<button
onClick={closeModal}
className="flex absolute top-10 right-0 z-10 w-10 h-10 text-common-white bg-primary-main items-center justify-center rounded-full border-solid border-primary-dark border-2"
>
X
</button>
</div>
<ModalWrapper>
<div>
<h2 className="text-2xl text-center mb-4">📋 Usage Guide</h2>
<Separator height="1px" />
<Paragraph className="my-4">
There are some controls that you might not know about, so here's a
short list of them.
</Paragraph>
<h3 className="text-lg font-bold mb-2">Life counter</h3>
<ul className="list-disc ml-6 mb-4">
<li>
<strong>Tap</strong> on a player's + or - button to add or
subtract <strong>1 life</strong>.
</li>
<li>
<strong>Long press</strong> on a player's + or - button to add
or subtract <strong>10 life</strong>.
</li>
</ul>
<h3 className="text-lg font-bold mb-2">
Commander damage and other counters
</h3>
<ul className="list-disc ml-6 mb-4">
<li>
<strong>Tap</strong> on the counter to add{' '}
<strong>1 counter</strong>.
</li>
<li>
<strong>Long press</strong> on the counter to subtract{' '}
<strong>1 counter</strong>.
</li>
</ul>
<h3 className="text-lg font-bold mb-2">Other</h3>
<Paragraph className="mb-4">
When a player is <strong>at or below 0 life</strong>, has taken{' '}
<strong>21 or more Commander Damage</strong> or has{' '}
<strong>10 or more poison counters</strong>, a button with a skull
will appear on that player's card. Tapping it will dim the
player's card.
</Paragraph>
</div>
<div className="text-center mt-4">
Visit my
<a
href="https://github.com/Vikeo/LifeTrinket"
target="_blank"
className="text-text-secondary underline"
>
{' '}
GitHub{' '}
</a>
for more info about this web app.
</div>
</ModalWrapper>
</>
</Modal>
);
};

View File

@@ -1,195 +0,0 @@
import { Button, FormLabel, Modal, Switch } from '@mui/material';
import { twc } from 'react-twc';
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { ModalWrapper } from './InfoModal';
import { Separator } from './Separator';
import { Paragraph } from './TextComponents';
import { useEffect, useState } from 'react';
const SettingContainer = twc.div`w-full flex flex-col`;
const ToggleContainer = twc.div`flex flex-row justify-between items-center`;
const Container = twc.div`flex flex-col items-center w-full`;
const Description = twc.p`mr-16 text-xs text-left text-text-secondary`;
type SettingsModalProps = {
isOpen: boolean;
closeModal: () => void;
};
export const SettingsModal = ({ isOpen, closeModal }: SettingsModalProps) => {
const { settings, setSettings, isPWA } = useGlobalSettings();
const [isLatestVersion, setIsLatestVersion] = useState(false);
const [newVersion, setNewVersion] = useState<string | undefined>(undefined);
useEffect(() => {
if (!isOpen) {
return;
}
async function checkIfLatestVersion() {
try {
const result = await fetch(
'https://api.github.com/repos/Vikeo/LifeTrinket/releases/latest',
{
headers: {
/* @ts-expect-error is defined in vite.config.ts*/
Authorization: `Bearer ${REPO_READ_ACCESS_TOKEN}`,
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
},
}
);
const data = await result.json();
if (!data.name) {
setNewVersion(undefined);
setIsLatestVersion(false);
return;
}
setNewVersion(data.name);
/* @ts-expect-error is defined in vite.config.ts*/
if (data.name === APP_VERSION) {
setIsLatestVersion(true);
return;
}
setIsLatestVersion(false);
} catch (error) {
console.error('error getting latest version string', error);
}
}
checkIfLatestVersion();
}, [isOpen]);
return (
<Modal open={isOpen} onClose={closeModal}>
<>
<div className="flex relative w-full max-w-[548px]">
<button
onClick={closeModal}
className="flex absolute top-10 right-0 z-10 w-10 h-10 text-common-white bg-primary-main items-center justify-center rounded-full border-solid border-primary-dark border-2"
>
X
</button>
</div>
<ModalWrapper>
<Container>
<h2 className="text-center text-2xl mb-2"> Settings </h2>
<Separator height="1px" />
<SettingContainer>
<ToggleContainer>
<FormLabel>Show Start Player</FormLabel>
<Switch
checked={settings.showStartingPlayer}
onChange={() => {
setSettings({
...settings,
showStartingPlayer: !settings.showStartingPlayer,
});
}}
/>
</ToggleContainer>
<Description>
On start or reset of game, will pick a random player who will
start first if this is enabled.
</Description>
</SettingContainer>
<SettingContainer>
<ToggleContainer>
<FormLabel>Keep Awake</FormLabel>
<Switch
checked={settings.keepAwake}
onChange={() => {
setSettings({
...settings,
keepAwake: !settings.keepAwake,
});
}}
/>
</ToggleContainer>
<Description>
Will prevent device from going to sleep while this app is open
if this is enabled.
</Description>
</SettingContainer>
<SettingContainer>
<ToggleContainer>
<FormLabel>Go fullscreen on start (Android only)</FormLabel>
<Switch
checked={settings.goFullscreenOnStart}
onChange={() => {
setSettings({
...settings,
goFullscreenOnStart: !settings.goFullscreenOnStart,
});
}}
/>
</ToggleContainer>
<Description>
Will enter fullscreen mode when starting a game if this is
enabled.
</Description>
</SettingContainer>
{!isPWA && (
<>
<Separator height="1px" />
<SettingContainer>
<ToggleContainer>
<Paragraph>
<b>Tip:</b> You can{' '}
<b>add this webapp to your home page on iOS</b> or{' '}
<b>install it on Android</b> to have it act just like a
normal app!
</Paragraph>
</ToggleContainer>
<Description className="mt-1">
If you do, this app will work offline and the toolbar will
be automatically hidden.
</Description>
</SettingContainer>
</>
)}
<Separator height="1px" />
<SettingContainer>
<Paragraph>
{/* @ts-expect-error is defined in vite.config.ts*/}
Current version: {APP_VERSION}{' '}
{isLatestVersion && (
<span className="text-sm text-text-secondary">(latest)</span>
)}
</Paragraph>
{!isLatestVersion && newVersion && (
<Paragraph className="text-text-secondary text-lg text-center">
New version ({newVersion}) is available!{' '}
</Paragraph>
)}
</SettingContainer>
{!isLatestVersion && newVersion && (
<Button
variant="contained"
style={{ marginTop: '0.25rem', marginBottom: '0.25rem' }}
onClick={() => window?.location?.reload()}
>
<span>Update</span>
<span className="text-xs">&nbsp;(reload app)</span>
</Button>
)}
<Separator height="1px" />
<Button
variant="contained"
onClick={closeModal}
style={{ marginTop: '0.25rem' }}
>
Save and Close
</Button>
</Container>
</ModalWrapper>
</>
</Modal>
);
};

View File

@@ -1,99 +0,0 @@
import { Button, Drawer } from '@mui/material';
import { useState } from 'react';
import { BuyMeCoffee, KoFi } from '../../Icons/generated/Support';
import { Paragraph } from './TextComponents';
import LittleGuy from '../../Icons/generated/LittleGuy';
import { useAnalytics } from '../../Hooks/useAnalytics';
import { twc } from 'react-twc';
const SupportContainer = twc.div`flex flex-col items-center justify-center gap-4 mt-4 mb-4`;
const SupportButton = twc.button`
flex
flex-row
items-center
justify-left
border-none
cursor-pointer
bg-primary-main
rounded-md
w-10/12
mx-4
px-4
py-2
transition-colors duration-200 ease-in-out
shadow-[1px_2px_4px_0px_rgba(0,0,0,0.3)]
hover:bg-primary-dark
`;
export const SupportMe = () => {
const analytics = useAnalytics();
const [isDrawerOpen, setIsDrawerOpen] = useState(false);
const handleOpenBuyMeCoffee = () => {
analytics.trackEvent('click_bmc');
window.open('https://www.buymeacoffee.com/vikeo');
};
const handleOpenKoFi = () => {
analytics.trackEvent('click_kofi');
window.open('https://ko-fi.com/vikeo');
};
const toggleDrawer =
(open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => {
analytics.trackEvent('toggle_support_drawer');
if (
event.type === 'keydown' &&
((event as React.KeyboardEvent).key === 'Tab' ||
(event as React.KeyboardEvent).key === 'Shift')
) {
return;
}
setIsDrawerOpen(open);
};
return (
<>
<Button
onClick={toggleDrawer(true)}
size="small"
variant="contained"
style={{
position: 'absolute',
top: '1rem',
right: '1rem',
fontSize: '0.5rem',
}}
>
Nourish <br /> this guy {'->'}
</Button>
<LittleGuy
height={'4rem'}
width={'2.5rem'}
className="pointer-events-none absolute top-10 right-0 text-text-primary"
/>
<Drawer
anchor={'right'}
open={isDrawerOpen}
onClose={toggleDrawer(false)}
variant="temporary"
>
<SupportContainer>
<SupportButton onClick={handleOpenBuyMeCoffee}>
<BuyMeCoffee height="1.5rem" width="1.5rem" className="mr-2" />
<Paragraph className="text-xs">Buy him a tea</Paragraph>
</SupportButton>
<SupportButton onClick={handleOpenKoFi}>
<KoFi height="1.5rem" width="1.5rem" className="mr-2" />
<Paragraph className="text-xs">Buy him a ko-fi</Paragraph>
</SupportButton>
</SupportContainer>
</Drawer>
</>
);
};

View File

@@ -0,0 +1,29 @@
import { LabelText } from '../Views/StartMenu/StartMenu';
export const ToggleButton = ({
label,
checked,
onChange,
}: {
label?: string;
checked: boolean;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}) => {
return (
<div className="flex flex-col items-center">
{label && <LabelText>{label}</LabelText>}
<label className="inline-flex items-center cursor-pointer relative h-6 w-10">
<input
type="checkbox"
value=""
checked={checked}
onChange={onChange}
className="sr-only peer"
/>
<div className="relative mx-1 w-10 h-[0.875rem] bg-gray-900 rounded-full peer peer-checked:bg-primary-dark" />
<div className="absolute peer-checked:translate-x-full rtl:peer-checked:-translate-x-full bg-secondary-main peer-checked:bg-primary-main rounded-full h-5 w-5 transition-all" />
</label>
</div>
);
};

View File

@@ -1,370 +0,0 @@
import { Button, Checkbox } from '@mui/material';
import { useRef } from 'react';
import { twc } from 'react-twc';
import { theme } from '../../Data/theme';
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { usePlayers } from '../../Hooks/usePlayers';
import { useSafeRotate } from '../../Hooks/useSafeRotate';
import {
Energy,
Exit,
Experience,
FullscreenOff,
FullscreenOn,
PartnerTax,
Poison,
ResetGame,
} from '../../Icons/generated';
import { Player, Rotation } from '../../Types/Player';
import { RotationDivProps } from '../Buttons/CommanderDamage';
const CheckboxContainer = twc.div``;
const PlayerMenuWrapper = twc.div`
flex
flex-col
absolute
w-full
h-full
bg-background-settings
items-center
justify-center
z-[2]
webkit-user-select-none
transition-all
`;
const BetterRowContainer = twc.div`
flex
flex-col
flex-grow
w-full
h-full
justify-end
items-stretch
`;
const TogglesSection = twc.div`
flex
relative
flex-row
gap-2
justify-evenly
`;
const ButtonsSections = twc.div`
flex
max-w-full
gap-4
justify-between
p-[3%]
items-center
`;
const ColorPicker = twc.input`
absolute
top-[5%]
left-[5%]
h-[8vmax]
w-[8vmax]
border-none
outline-none
cursor-pointer
bg-transparent
user-select-none
text-common-white
`;
const SettingsContainer = twc.div<RotationDivProps>((props) => [
'flex flex-wrap h-full w-full',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
? 'flex-col'
: 'flex-row',
]);
type PlayerMenuProps = {
player: Player;
setShowPlayerMenu: (showPlayerMenu: boolean) => void;
isShown: boolean;
};
const PlayerMenu = ({
player,
setShowPlayerMenu,
isShown,
}: PlayerMenuProps) => {
const settingsContainerRef = useRef<HTMLDivElement | null>(null);
const dialogRef = useRef<HTMLDialogElement | null>(null);
const { isSide } = useSafeRotate({
rotation: player.settings.rotation,
containerRef: settingsContainerRef,
});
const { fullscreen, wakeLock, goToStart } = useGlobalSettings();
const { updatePlayer, resetCurrentGame } = usePlayers();
const handleColorChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const updatedPlayer = { ...player, color: event.target.value };
updatePlayer(updatedPlayer);
};
const handleSettingsChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name, checked } = event.target;
const updatedSettings = { ...player.settings, [name]: checked };
const updatedPlayer = { ...player, settings: updatedSettings };
updatePlayer(updatedPlayer);
};
const handleResetGame = () => {
resetCurrentGame();
setShowPlayerMenu(false);
};
const toggleFullscreen = () => {
if (fullscreen.isFullscreen) {
fullscreen.disableFullscreen();
} else {
fullscreen.enableFullscreen();
}
};
const buttonFontSize = isSide ? '1.5vmax' : '3vmin';
const iconSize = isSide ? '6vmin' : '3vmax';
const extraCountersSize = isSide ? '8vmin' : '4vmax';
const calcRotation =
player.settings.rotation === Rotation.Side
? `${player.settings.rotation - 180}deg`
: player.settings.rotation === Rotation.SideFlipped
? `${player.settings.rotation - 180}deg`
: '';
return (
<PlayerMenuWrapper
//TODO: Fix hacky solution to rotation for SideFlipped
style={{
rotate:
player.settings.rotation === Rotation.SideFlipped ? `180deg` : '',
translate: isShown ? '' : player.isSide ? `-100%` : `0 -100%`,
}}
>
<SettingsContainer
$rotation={player.settings.rotation}
style={{
rotate: calcRotation,
}}
ref={settingsContainerRef}
>
<ColorPicker
type="color"
value={player.color}
onChange={handleColorChange}
role="button"
aria-label="Color picker"
/>
<BetterRowContainer>
<TogglesSection>
{player.settings.useCommanderDamage && (
<CheckboxContainer>
<Checkbox
name="usePartner"
checked={player.settings.usePartner}
icon={
<PartnerTax
size={extraCountersSize}
color="black"
stroke="white"
strokeWidth="30"
/>
}
checkedIcon={
<PartnerTax
size={extraCountersSize}
color={player.color}
stroke="white"
strokeWidth="30"
/>
}
onChange={handleSettingsChange}
role="checkbox"
aria-checked={player.settings.usePartner}
aria-label="Partner"
/>
</CheckboxContainer>
)}
<CheckboxContainer>
<Checkbox
name="usePoison"
checked={player.settings.usePoison}
icon={
<Poison
size={extraCountersSize}
color="black"
stroke="white"
strokeWidth="30"
/>
}
checkedIcon={
<Poison
size={extraCountersSize}
color={player.color}
stroke="white"
strokeWidth="30"
/>
}
onChange={handleSettingsChange}
role="checkbox"
aria-checked={player.settings.usePoison}
aria-label="Poison"
/>
</CheckboxContainer>
<CheckboxContainer>
<Checkbox
name="useEnergy"
checked={player.settings.useEnergy}
icon={
<Energy
size={extraCountersSize}
color="black"
stroke="white"
strokeWidth="15"
/>
}
checkedIcon={
<Energy
size={extraCountersSize}
color={player.color}
stroke="white"
strokeWidth="15"
/>
}
onChange={handleSettingsChange}
role="checkbox"
aria-checked={player.settings.useEnergy}
aria-label="Energy"
/>
</CheckboxContainer>
<CheckboxContainer>
<Checkbox
name="useExperience"
checked={player.settings.useExperience}
icon={
<Experience
size={extraCountersSize}
color="black"
stroke="white"
strokeWidth="15"
/>
}
checkedIcon={
<Experience
size={extraCountersSize}
color={player.color}
stroke="white"
strokeWidth="15"
/>
}
onChange={handleSettingsChange}
role="checkbox"
aria-checked={player.settings.useExperience}
aria-label="Experience"
/>
</CheckboxContainer>
</TogglesSection>
<ButtonsSections className="mt-4">
<Button
variant="text"
style={{
cursor: 'pointer',
userSelect: 'none',
}}
onClick={goToStart}
aria-label="Back to start"
>
<Exit size={iconSize} style={{ rotate: '180deg' }} />
</Button>
<CheckboxContainer>
<Checkbox
name="fullscreen"
checked={document.fullscreenElement ? true : false}
icon={
<FullscreenOff
size={iconSize}
color={theme.palette.primary.main}
/>
}
checkedIcon={<FullscreenOn size={iconSize} />}
onChange={toggleFullscreen}
role="checkbox"
aria-checked={document.fullscreenElement ? true : false}
aria-label="Fullscreen"
/>
</CheckboxContainer>
<Button
variant={wakeLock.active ? 'contained' : 'outlined'}
style={{
cursor: 'pointer',
userSelect: 'none',
fontSize: buttonFontSize,
padding: '0 4px 0 4px',
}}
onClick={wakeLock.toggleWakeLock}
role="checkbox"
aria-checked={wakeLock.active}
aria-label="Keep awake"
>
Keep Awake
</Button>
<Button
style={{
cursor: 'pointer',
userSelect: 'none',
fontSize: buttonFontSize,
padding: '4px',
}}
onClick={() => dialogRef.current?.show()}
role="checkbox"
aria-checked={wakeLock.active}
aria-label="Reset Game"
>
<ResetGame size={iconSize} />
</Button>
</ButtonsSections>
</BetterRowContainer>
<dialog
ref={dialogRef}
className="z-[9999] min-h-2/4 bg-background-default text-text-primary rounded-2xl border-none absolute bottom-[20%]"
>
<div className="h-full flex flex-col p-4 gap-2">
<h1 className="text-center">Reset Game?</h1>
<div className="flex justify-evenly gap-4">
<Button
variant="contained"
onClick={() => dialogRef.current?.close()}
>
No
</Button>
<Button
variant="contained"
onClick={() => {
handleResetGame();
dialogRef.current?.close();
}}
>
Yes
</Button>
</div>
</div>
</dialog>
</SettingsContainer>
</PlayerMenuWrapper>
);
};
export default PlayerMenu;

View File

@@ -0,0 +1,490 @@
import { useRef } from 'react';
import { twc } from 'react-twc';
import { useAnalytics } from '../../Hooks/useAnalytics';
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { usePlayers } from '../../Hooks/usePlayers';
import { useSafeRotate } from '../../Hooks/useSafeRotate';
import {
Close,
Energy,
Exit,
Experience,
FullscreenOff,
FullscreenOn,
PartnerTax,
Poison,
ResetGame,
} from '../../Icons/generated';
import { Player, Rotation } from '../../Types/Player';
import { PreStartMode } from '../../Types/Settings';
import { RotationDivProps } from '../Buttons/CommanderDamage';
import { IconCheckbox } from '../Misc/IconCheckbox';
const PlayerMenuWrapper = twc.div`
flex
flex-col
absolute
w-full
h-full
bg-background-settings
backdrop-blur-[3px]
items-center
justify-center
z-[2]
webkit-user-select-none
transition-all
`;
const BetterRowContainer = twc.div`
flex
flex-col
flex-grow
w-full
h-full
justify-between
items-stretch
`;
const TogglesSection = twc.div`
flex
flex-row
flex-wrap
relative
h-full
justify-evenly
items-center
`;
const ButtonsSections = twc.div`
flex
max-w-full
justify-evenly
items-center
flex-wrap
h-full
mt-0
px-2
`;
const ColorPickerButton = twc.div`
h-[8vmax]
w-[8vmax]
relative
max-h-12
max-w-12
rounded-full
cursor-pointer
overflow-hidden
`;
const SettingsContainer = twc.div<RotationDivProps>((props) => [
'flex flex-wrap h-full w-full overflow-y-scroll',
props.$rotation === Rotation.SideFlipped || props.$rotation === Rotation.Side
? 'flex-col'
: 'flex-row',
]);
type PlayerMenuProps = {
player: Player;
setShowPlayerMenu: (showPlayerMenu: boolean) => void;
isShown: boolean;
};
const PlayerMenu = ({
player,
setShowPlayerMenu,
isShown,
}: PlayerMenuProps) => {
const settingsContainerRef = useRef<HTMLDivElement | null>(null);
const resetGameDialogRef = useRef<HTMLDialogElement | null>(null);
const endGameDialogRef = useRef<HTMLDialogElement | null>(null);
const { isSide } = useSafeRotate({
rotation: player.settings.rotation,
containerRef: settingsContainerRef,
});
const {
fullscreen,
wakeLock,
goToStart,
settings,
setPlaying,
setRandomizingPlayer,
saveCurrentGame,
initialGameSettings,
setPreStartCompleted,
} = useGlobalSettings();
const analytics = useAnalytics();
const { updatePlayer, resetCurrentGame, players } = usePlayers();
const handleColorChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const updatedPlayer = { ...player, color: event.target.value };
updatePlayer(updatedPlayer);
};
const handleSettingsChange = (event: React.ChangeEvent<HTMLInputElement>) => {
const { name, checked } = event.target;
const updatedSettings = { ...player.settings, [name]: checked };
const updatedPlayer = { ...player, settings: updatedSettings };
updatePlayer(updatedPlayer);
};
const handleResetGame = () => {
resetCurrentGame();
setShowPlayerMenu(false);
setPlaying(false);
if (settings.preStartMode === PreStartMode.RandomKing) {
setRandomizingPlayer(true);
setPreStartCompleted(false);
}
analytics.trackEvent('reset_game');
};
const handleGoToStart = () => {
saveCurrentGame({ players, initialGameSettings });
goToStart();
setRandomizingPlayer(true);
};
const toggleFullscreen = () => {
if (fullscreen.isFullscreen) {
fullscreen.disableFullscreen();
} else {
fullscreen.enableFullscreen();
}
};
const buttonFontSize = isSide ? '1.5vmax' : '3vmin';
const iconSize = isSide ? '6vmin' : '3vmax';
const extraCountersSize = isSide ? '8vmin' : '4vmax';
const calcRotation =
player.settings.rotation === Rotation.Side
? `${player.settings.rotation - 180}deg`
: player.settings.rotation === Rotation.SideFlipped
? `${player.settings.rotation - 180}deg`
: '';
return (
<PlayerMenuWrapper
//TODO: Fix hacky solution to rotation for SideFlipped
style={{
rotate:
player.settings.rotation === Rotation.SideFlipped ? `180deg` : '',
translate: isShown ? '' : player.isSide ? `-100%` : `0 -100%`,
}}
>
<SettingsContainer
$rotation={player.settings.rotation}
style={{
rotate: calcRotation,
}}
ref={settingsContainerRef}
>
<button
onClick={() => {
analytics.trackEvent('close_player_menu_button');
setShowPlayerMenu(false);
}}
className="flex absolute top-2 right-2 z-10"
>
<Close size={buttonFontSize} className="text-primary-main " />
</button>
<BetterRowContainer>
<TogglesSection>
<ColorPickerButton aria-label="Color picker">
<input
onChange={handleColorChange}
type="color"
className="size-[200%] absolute -left-2 -top-2"
value={player.color}
onClick={() => {
analytics.trackEvent('color_picker_opened', {
player: player.index,
});
}}
/>
</ColorPickerButton>
{player.settings.useCommanderDamage && (
<div className="flex flex-col items-center">
<IconCheckbox
name="usePartner"
checked={player.settings.usePartner}
icon={
<PartnerTax
size={extraCountersSize}
color="black"
stroke="white"
strokeWidth="30"
/>
}
checkedIcon={
<PartnerTax
size={extraCountersSize}
color={player.color}
stroke="white"
strokeWidth="30"
/>
}
onChange={(e) => {
analytics.trackEvent('toggle_partner', {
checked: e.target.checked,
});
handleSettingsChange(e);
}}
aria-checked={player.settings.usePartner}
aria-label="Partner"
/>
</div>
)}
<div>
<IconCheckbox
name="usePoison"
checked={player.settings.usePoison}
icon={
<Poison
size={extraCountersSize}
color="black"
stroke="white"
strokeWidth="30"
/>
}
checkedIcon={
<Poison
size={extraCountersSize}
color={player.color}
stroke="white"
strokeWidth="30"
/>
}
onChange={(e) => {
analytics.trackEvent('toggle_poison', {
checked: e.target.checked,
});
handleSettingsChange(e);
}}
aria-checked={player.settings.usePoison}
aria-label="Poison"
/>
</div>
<div>
<IconCheckbox
name="useEnergy"
checked={player.settings.useEnergy}
icon={
<Energy
size={extraCountersSize}
color="black"
stroke="white"
strokeWidth="15"
/>
}
checkedIcon={
<Energy
size={extraCountersSize}
color={player.color}
stroke="white"
strokeWidth="15"
/>
}
onChange={(e) => {
analytics.trackEvent('toggle_energy', {
checked: e.target.checked,
});
handleSettingsChange(e);
}}
aria-checked={player.settings.useEnergy}
aria-label="Energy"
/>
</div>
<div>
<IconCheckbox
name="useExperience"
checked={player.settings.useExperience}
icon={
<Experience
size={extraCountersSize}
color="black"
stroke="white"
strokeWidth="15"
/>
}
checkedIcon={
<Experience
size={extraCountersSize}
color={player.color}
stroke="white"
strokeWidth="15"
/>
}
onChange={(e) => {
analytics.trackEvent('toggle_experience', {
checked: e.target.checked,
});
handleSettingsChange(e);
}}
aria-checked={player.settings.useExperience}
aria-label="Experience"
/>
</div>
</TogglesSection>
<ButtonsSections>
<button
className="text-primary-main cursor-pointer webkit-user-select-none"
onClick={() => endGameDialogRef.current?.show()}
aria-label="Back to start"
>
<Exit size={iconSize} style={{ rotate: '180deg' }} />
</button>
<div
data-fullscreen={document.fullscreenElement ? true : false}
className="flex
data-[fullscreen=true]:bg-secondary-dark rounded-lg border border-transparent
data-[fullscreen=true]:border-primary-main"
>
<IconCheckbox
className="p-1"
name="fullscreen"
checked={document.fullscreenElement ? true : false}
icon={
<FullscreenOff
size={iconSize}
className="text-primary-main"
/>
}
checkedIcon={
<FullscreenOn size={iconSize} className="text-primary-main" />
}
onChange={toggleFullscreen}
aria-checked={document.fullscreenElement ? true : false}
aria-label="Fullscreen"
/>
</div>
<button
data-wake-lock-active={settings.keepAwake}
style={{
fontSize: buttonFontSize,
}}
className="text-primary-main px-1 webkit-user-select-none cursor-pointer
data-[wake-lock-active=true]:bg-secondary-dark rounded-lg border border-transparent
data-[wake-lock-active=true]:border-primary-main
"
onClick={() => {
wakeLock.toggleWakeLock();
}}
role="checkbox"
aria-checked={settings.keepAwake}
aria-label="Keep awake"
>
Keep Awake
</button>
<button
style={{
cursor: 'pointer',
userSelect: 'none',
fontSize: buttonFontSize,
padding: '2px',
}}
className="text-primary-main"
onClick={() => resetGameDialogRef.current?.show()}
role="checkbox"
aria-label="Reset Game"
>
<ResetGame size={iconSize} />
</button>
</ButtonsSections>
</BetterRowContainer>
<dialog
ref={resetGameDialogRef}
className="z-[999] size-full bg-background-settings overflow-y-scroll"
onClick={() => resetGameDialogRef.current?.close()}
>
<div className="flex size-full items-center justify-center">
<div className="flex flex-col justify-center p-4 gap-2 bg-background-default rounded-xl border-none">
<h1
className="text-center text-text-primary"
style={{ fontSize: extraCountersSize }}
>
Reset Game?
</h1>
<div className="flex justify-evenly gap-2">
<button
className="bg-primary-main border border-primary-dark text-text-primary rounded-lg flex-grow"
style={{ fontSize: iconSize }}
onClick={() => resetGameDialogRef.current?.close()}
>
No
</button>
<button
className="bg-primary-main border border-primary-dark text-text-primary rounded-lg flex-grow"
onClick={() => {
handleResetGame();
resetGameDialogRef.current?.close();
}}
style={{ fontSize: iconSize }}
>
Yes
</button>
</div>
</div>
</div>
</dialog>
<dialog
ref={endGameDialogRef}
className="z-[999] size-full bg-background-settings overflow-y-scroll"
onClick={() => endGameDialogRef.current?.close()}
>
<div className="flex size-full items-center justify-center">
<div className="flex flex-col justify-center p-4 gap-2 bg-background-default rounded-xl border-none">
<h1
className="text-center text-text-primary"
style={{ fontSize: extraCountersSize }}
>
Go to start?
</h1>
<div
style={{ fontSize: iconSize }}
className="text-center text-text-primary"
>
(Game will be saved)
</div>
<div className="flex justify-evenly gap-2">
<button
className="bg-primary-main border border-primary-dark text-text-primary rounded-lg flex-grow"
style={{ fontSize: iconSize }}
onClick={() => endGameDialogRef.current?.close()}
>
No
</button>
<button
className="bg-primary-main border border-primary-dark text-text-primary rounded-lg flex-grow"
onClick={() => {
handleGoToStart();
endGameDialogRef.current?.close();
}}
style={{ fontSize: iconSize }}
>
Yes
</button>
</div>
</div>
</div>
</dialog>
</SettingsContainer>
</PlayerMenuWrapper>
);
};
export default PlayerMenu;

View File

@@ -1,6 +1,8 @@
import LifeCounter from '../LifeCounter/LifeCounter';
import { Player as PlayerType } from '../../Types/Player';
import { twc } from 'react-twc';
import { usePlayers } from '../../Hooks/usePlayers';
import { Player as PlayerType } from '../../Types/Player';
import LifeCounter from '../LifeCounter/LifeCounter';
import { GridLayout } from '../Views/Play';
const getGridArea = (player: PlayerType) => {
switch (player.index) {
@@ -21,15 +23,16 @@ const getGridArea = (player: PlayerType) => {
}
};
const PlayerWrapper = twc.div`w-full h-full bg-black`;
const PlayersWrapper = twc.div`w-full h-full bg-black`;
export const Players = ({ gridLayout }: { gridLayout: GridLayout }) => {
const { players } = usePlayers();
export const Player = (players: PlayerType[], gridClasses: string) => {
return (
<PlayerWrapper>
<div className={`grid w-full h-full gap-1 box-border ${gridClasses} `}>
<PlayersWrapper>
<div className={`grid w-full h-full gap-1 box-border ${gridLayout} `}>
{players.map((player) => {
const gridArea = getGridArea(player);
return (
<div
key={player.index}
@@ -45,6 +48,6 @@ export const Player = (players: PlayerType[], gridClasses: string) => {
);
})}
</div>
</PlayerWrapper>
</PlayersWrapper>
);
};

View File

@@ -0,0 +1,202 @@
import { useEffect, useRef, useState } from 'react';
import { useGlobalSettings } from '../../../Hooks/useGlobalSettings';
import { usePlayers } from '../../../Hooks/usePlayers';
type TouchPoint = {
x: number;
y: number;
id: number;
};
const getOrientation = () => {
return window.matchMedia('(orientation: portrait)').matches
? 'portrait'
: 'landscape';
};
const ANIMATION_INTRO_LENGTH = 500;
const BEFORE_INTRO_TIMER_LENGTH = 100;
export const FingerGame = () => {
const { players } = usePlayers();
const aboutToStartTimerRef = useRef<NodeJS.Timeout | null>(null);
const selectingPlayerTimerRef = useRef<NodeJS.Timeout | null>(null);
const [touchPoints, setTouchPoints] = useState<TouchPoint[]>([]);
const [selectedTouchPoint, setSelectedTouchPoint] = useState<
TouchPoint | undefined
>();
const [timerStarted, setTimerStarted] = useState(false);
const { setPlaying, goToStart } = useGlobalSettings();
useEffect(() => {
//Start playing when someone is selected and any touch point is released
if (selectedTouchPoint && touchPoints.length !== players.length) {
aboutToStartTimerRef.current = setTimeout(() => {
setSelectedTouchPoint(undefined);
setPlaying(true);
}, ANIMATION_INTRO_LENGTH);
setTimerStarted(true);
return;
}
// If no touch point is selected, select one with a delay
if (touchPoints.length === players.length && !selectedTouchPoint) {
selectingPlayerTimerRef.current = setTimeout(() => {
const randomIndex = Math.floor(Math.random() * touchPoints.length);
const randomTouchPoint = touchPoints[randomIndex];
setSelectedTouchPoint(randomTouchPoint);
}, BEFORE_INTRO_TIMER_LENGTH);
return;
}
if (selectingPlayerTimerRef.current) {
clearTimeout(selectingPlayerTimerRef.current);
}
return () => {
if (aboutToStartTimerRef.current) {
clearTimeout(aboutToStartTimerRef.current);
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [touchPoints, players.length]);
const handleOnTouchStart = (e: React.TouchEvent) => {
if (selectedTouchPoint) {
return;
}
//Get the first touch point id that isn't already in the touchPoints array
const touch = Array.from(e.changedTouches).find(
(t) => !touchPoints.find((p) => p.id === t.identifier)
);
if (!touch) {
console.error('No touch found');
return;
}
let { clientX, clientY } = touch;
// Adjust coordinates for portrait mode
if (getOrientation() === 'portrait') {
const tempX = clientX;
clientX = clientY;
clientY = window.innerWidth - tempX;
}
const newTouchPoints = {
x: clientX,
y: clientY,
id: touch.identifier,
};
setTouchPoints([...touchPoints, newTouchPoints]);
};
const handleOnTouchEnd = (e: React.TouchEvent) => {
if (selectedTouchPoint) {
aboutToStartTimerRef.current = setTimeout(() => {
setSelectedTouchPoint(undefined);
setPlaying(true);
}, ANIMATION_INTRO_LENGTH);
setTimerStarted(true);
return;
}
// Get the touch point that was just released
const touch = e.changedTouches[e.changedTouches.length - 1];
// Get the index of the touch point that was just released
const index = touchPoints.findIndex((p) => p.id === touch.identifier);
// Remove the touch point that was just released
setTouchPoints([
...touchPoints.slice(0, index),
...touchPoints.slice(index + 1),
]);
};
return (
<div
className="absolute flex justify-center items-center w-full h-full portrait:h-[100dvw] portrait:w-[100dvh] z-50 bg-secondary-main overflow-hidden"
onTouchStart={handleOnTouchStart}
onTouchEnd={handleOnTouchEnd}
// FIXEME: This code is not performant, but updates a touch point's position when it moves
// onTouchMove={(e) => {
// e.preventDefault();
// // Get the touch point that was just moved
// const touch = Array.from(e.changedTouches).find((t) =>
// touchPoints.find((p) => p.id === t.identifier)
// );
// if (!touch) {
// console.error('No touch found');
// return;
// }
// let { clientX, clientY } = touch;
// // Adjust coordinates for portrait mode
// if (getOrientation() === 'portrait') {
// const tempX = clientX;
// clientX = clientY;
// clientY = window.innerWidth - tempX;
// }
// // Get the index of the touch point that was just moved
// const index = touchPoints.findIndex(
// (p) => p.id === touch.identifier
// );
// // Update the touch point that was just moved
// setTouchPoints([
// ...touchPoints.slice(0, index),
// { x: clientX, y: clientY, id: touch.identifier },
// ...touchPoints.slice(index + 1),
// ]);
// }}
>
<button
className="absolute flex top-4 left-4 rounded-lg px-2 py-1 justify-center bg-primary-main text-text-primary text-xs duration-200 ease-in-out shadow-[1px_2px_4px_0px_rgba(0,0,0,0.3)] hover:bg-primary-dark"
onClick={goToStart}
>
<div className="text-xl leading-4">{'<'}&nbsp;</div>
Back
</button>
{touchPoints.length !== players.length && (
<div className="flex flex-col items-center text-[13vmin] whitespace-nowrap pointer-events-none webkit-user-select-none">
Waiting for fingers <br />
<div className="tabular-nums">
{touchPoints.length}/{players.length}
</div>
</div>
)}
{touchPoints.map((point, index) => (
<div
key={`touch-point-${index}`}
data-is-selected={selectedTouchPoint?.id === point.id}
data-unloading={timerStarted}
className="absolute rounded-full translate-x-[-50%] translate-y-[-50%] transition-all duration-500
h-[75px] w-[75px]
data-[unloading=false]:data-[is-selected=true]:h-[250px] data-[unloading=false]:data-[is-selected=true]:w-[250px]
data-[unloading=true]:h-[0px] data-[unloading=true]:w-[0px] data-[unloading=true]:duration-[400ms]
pointer-events-none
"
style={{
left: point.x,
top: point.y,
backgroundColor: players[index]?.color ?? 'red',
}}
/>
))}
</div>
);
};

View File

@@ -0,0 +1,49 @@
import { usePlayers } from '../../../../Hooks/usePlayers';
import { Player } from '../../../../Types/Player';
import { GridLayout } from '../../../Views/Play';
import { RoulettePlayerCard } from './RoulettePlayerCard';
const getGridArea = (player: Player) => {
switch (player.index) {
case 0:
return 'grid-in-player0';
case 1:
return 'grid-in-player1';
case 2:
return 'grid-in-player2';
case 3:
return 'grid-in-player3';
case 4:
return 'grid-in-player4';
case 5:
return 'grid-in-player5';
default:
throw new Error('Invalid player index');
}
};
export const RandomKingPlayers = ({
gridLayout,
}: {
gridLayout: GridLayout;
}) => {
const { players } = usePlayers();
return (
<div className="w-full h-full bg-black">
<div className={`grid w-full h-full gap-1 box-border ${gridLayout} `}>
{players.map((player) => {
const gridArea = getGridArea(player);
return (
<div
key={player.index}
className={`flex justify-center items-center align-middle ${gridArea}`}
>
<RoulettePlayerCard player={player} />
</div>
);
})}
</div>
</div>
);
};

View File

@@ -0,0 +1,94 @@
import { useEffect, useRef } from 'react';
import { useGlobalSettings } from '../../../../Hooks/useGlobalSettings';
import { usePlayers } from '../../../../Hooks/usePlayers';
export const RandomKingSelectWrapper = () => {
const { setRandomizingPlayer } = useGlobalSettings();
const randomIntervalRef = useRef<NodeJS.Timeout | null>(null);
const prevRandomIndexRef = useRef<number>(-1);
const { settings, randomizingPlayer, setPreStartCompleted } =
useGlobalSettings();
const { players, setPlayers } = usePlayers();
useEffect(() => {
if (
players.length > 1 &&
settings.showStartingPlayer &&
randomizingPlayer
) {
randomIntervalRef.current = setInterval(() => {
let randomIndex: number;
do {
randomIndex = Math.floor(Math.random() * players.length);
} while (randomIndex === prevRandomIndexRef.current);
prevRandomIndexRef.current = randomIndex;
setPlayers(
players.map((p) =>
p.index === prevRandomIndexRef.current
? {
...p,
isStartingPlayer: true,
}
: {
...p,
isStartingPlayer: false,
}
)
);
}, 100);
}
const randomPlayerIndex = Math.floor(Math.random() * players.length);
setPlayers(
players.map((p) =>
p.index === randomPlayerIndex
? {
...p,
isStartingPlayer: true,
}
: {
...p,
isStartingPlayer: false,
}
)
);
return () => {
if (randomIntervalRef.current) {
clearInterval(randomIntervalRef.current);
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [players.length, setPlayers, randomizingPlayer]);
const gradientColors = players.map((player) => player.color).join(', ');
return (
<div
className="absolute flex justify-center items-center h-screen w-screen portrait:h-[100vw] portrait:w-[100vh] z-40 cursor-pointer text-5xl"
onClick={() => {
if (randomIntervalRef.current) {
clearInterval(randomIntervalRef.current);
randomIntervalRef.current = null;
}
setRandomizingPlayer(false);
setPreStartCompleted(true);
}}
>
<div className="absolute flex top-[30%] justify-center items-center px-8 py-4">
<div
className="absolute size-full blur-[3px] rounded-2xl opacity-90 saturate-150"
style={{
backgroundImage: `linear-gradient(60deg, ${gradientColors})`,
}}
/>
<p className="relative z-10 text-[5vmax]">PRESS TO SELECT PLAYER</p>
</div>
</div>
);
};

View File

@@ -0,0 +1,58 @@
import { useEffect, useRef } from 'react';
import { useGlobalSettings } from '../../../../Hooks/useGlobalSettings';
import { Player, Rotation } from '../../../../Types/Player';
import { Paragraph } from '../../../Misc/TextComponents';
import { DynamicText } from '../../StartingPlayerCard';
export const RoulettePlayerCard = ({ player }: { player: Player }) => {
const startPlayingTimerRef = useRef<NodeJS.Timeout | undefined>(undefined);
const { settings, randomizingPlayer, playing, setPlaying } =
useGlobalSettings();
useEffect(() => {
if (
player.isStartingPlayer &&
((!playing && randomizingPlayer) || !playing)
) {
startPlayingTimerRef.current = setTimeout(() => {
setPlaying(true);
}, 10_000);
}
return () => clearTimeout(startPlayingTimerRef.current);
}, [
player.isStartingPlayer,
playing,
setPlaying,
settings.preStartMode,
randomizingPlayer,
]);
const calcTextRotation =
player.settings.rotation === Rotation.SideFlipped ||
player.settings.rotation === Rotation.Side
? player.settings.rotation - 180
: player.settings.rotation;
return (
<div className="relative flex flex-grow flex-col items-center w-full h-full overflow-hidden">
<div
className="flex absolute w-full h-full justify-center items-center pointer-events-none select-none webkit-user-select-none z-10"
style={{ backgroundColor: player.color }}
>
{player.isStartingPlayer && (
<DynamicText
style={{
rotate: `${calcTextRotation}deg`,
}}
>
<div className="flex flex-col justify-center items-center">
<Paragraph>👑</Paragraph>
</div>
</DynamicText>
)}
</div>
</div>
);
};

View File

@@ -0,0 +1,159 @@
import { useState } from 'react';
import { useGlobalSettings } from '../../../Hooks/useGlobalSettings';
const questions = [
'Who has the most siblings?',
'Who has the most pets?',
'Who has the most tattoos?',
'Who has the most piercings?',
'Who has the most expensive shoes?',
'Who has the most most amount of teeth?',
'Who has the least amount of teeth?',
'Who lives closest to the equator?',
'Who is the tallest person in the group?',
'Who is the shortest person in the group?',
'Who speaks the most languages?',
'Who has traveled to the most countries?',
'Who has the earliest birthday in the year?',
'Who has won the most awards or trophies?',
'Who is the best cook among you?',
'Who is the fastest runner?',
'Who has the most unique hobby?',
'Who is the biggest movie buff?',
'Who is the most tech-savvy?',
'Who is the best at solving puzzles?',
'Who has the most extensive music collection?',
'Who has the most impressive collection of books?',
'Who has the most experience in a particular sport or activity?',
'Who has the most interesting job or profession?',
'Who has the most artistic talent?',
'Who is the most organized person?',
'Who is the best at keeping secrets?',
'Who has the most fascinating family history?',
'Who has the most embarrassing childhood nickname?',
'Who has the most unusual talent or skill?',
'Who has the most interesting family tradition?',
'Who has the most impressive celebrity encounter?',
'Who has the most unusual phobia?',
'Who has the most adventurous spirit?',
'Who has the most unique item in their wallet/purse?',
'Who has the most daring fashion sense?',
'Who has the most impressive party trick?',
'Who has the most memorable encounter with a wild animal?',
'Who has the most adventurous palate?',
'Who has the most unusual collection?',
'Who has the most unique bucket list item?',
'Who has the most inspiring life motto or mantra?',
'Who is the most likely to break out into song or dance in public?',
'Who is the most likely to be found binge-watching TV shows?',
'Who is the biggest procrastinator?',
'Who is the most likely to cry during a movie?',
'Who is the most adventurous when it comes to trying new foods?',
"Who is the most likely to forget someone's birthday?",
'Who is the best at giving advice?',
'Who is the worst at giving advice?',
'Who is the most likely to be found reading a book at a party?',
'Who is the most likely to win in a game of charades?',
'Who is the most likely to get lost in their own neighborhood?',
'Who is the most sentimental?',
'Who is the most likely to become famous?',
'Who is the most likely to become a millionaire?',
'Who is the most likely to start their own business?',
'Who is the most likely to become president?',
'Who is the most likely to go viral on social media?',
'Who is the most likely to win a Nobel Prize?',
'Who is the most likely to be a superhero in disguise?',
'Who is the most likely to survive a zombie apocalypse?',
'Who is the most likely to believe in aliens?',
'Who is the most likely to spend all their money on something silly?',
'Who is the most likely to write a bestselling novel?',
'Who is the most likely to be a secret agent?',
'Who is the most likely to be a professional athlete?',
'Who is the most likely to win a game of trivia?',
'Who is the most likely to win the upcoming game?',
'Who is the most likely to win at a game of Pokémon TCG?',
'Who has the most valuable card in their collection?',
'Who is the best at building decks?',
'Who has won the most games?',
'Who has the largest collection of cards?',
'Who is the most knowledgeable about Magic the Gathering lore?',
'Who is the most strategic?',
'Who is the most likely to trade away their most valuable card for something silly?',
'Who is the most competitive?',
'Who would be the most creative when it comes to making up new Magic the Gathering rules?',
'Who is the most likely to organize a Magic the Gathering draft tournament?',
'Who is the most enthusiastic about opening booster packs?',
'Who has the most unique and unusual Magic the Gathering deck?',
'Who is the most likely to cosplay as their favorite Magic the Gathering character?',
'Who is the most likely to forget to bring their Magic the Gathering deck to a game night?',
'Who is the most generous when it comes to lending out their decks?',
'Who is the most likely to start their own Magic the Gathering YouTube channel?',
'Who is the most skilled at bluffing during a game of Magic the Gathering?',
'Who is the most likely to spend all their money on Magic the Gathering cards?',
'Who is the most likely to rage quit during a game of Magic the Gathering?',
'Who is the most likely to win in a Magic the Gathering trivia contest?',
'Who is the most likely to build a themed Magic the Gathering deck?',
'Who is the most likely to organize a Magic the Gathering cube draft?',
'Who is the most likely to teach new players how to play Magic the Gathering?',
'Who is the most likely to build a commander deck with a ridiculous theme?',
'Who is the most likely to collect foreign-language Magic the Gathering cards?',
'Who is the most likely to participate in a Magic the Gathering charity event?',
'Who is the most likely to cosplay as their Magic the Gathering commander?',
'Who is the most likely to organize a Magic the Gathering charity tournament?',
];
export const Trivia = () => {
const { setPlaying, goToStart } = useGlobalSettings();
const [randomQuestion, setRandomQuestion] = useState(
questions[Math.floor(Math.random() * questions.length)]
);
const setUniqueRandomQuestion = () => {
let newRandomQuestion =
questions[Math.floor(Math.random() * questions.length)];
while (newRandomQuestion === randomQuestion) {
newRandomQuestion =
questions[Math.floor(Math.random() * questions.length)];
}
setRandomQuestion(newRandomQuestion);
};
return (
<div
className="absolute flex justify-center items-center w-full h-full portrait:h-[100dvw] portrait:w-[100dvh] z-50 bg-primary-dark overflow-hidden"
onClick={() => setPlaying(true)}
>
<button
className="absolute flex top-4 left-4 rounded-lg px-2 py-1 justify-center bg-primary-main text-text-primary text-xs duration-200 ease-in-out shadow-[1px_2px_4px_0px_rgba(0,0,0,0.3)] hover:bg-primary-dark"
onClick={goToStart}
>
<div className="text-xl leading-[0.80rem]">{'<'}&nbsp;</div>
Back
</button>
<button
className="absolute flex top-4 right-4 rounded-lg px-2 py-1 justify-center bg-primary-main text-text-primary text-xs duration-200 ease-in-out shadow-[1px_2px_4px_0px_rgba(0,0,0,0.3)] hover:bg-primary-dark"
onClick={(e) => {
e.stopPropagation();
setUniqueRandomQuestion();
}}
>
Reroll
</button>
<div className="size-full flex flex-col justify-between items-center whitespace-nowrap pointer-events-none webkit-user-select-none text-wrap text-center py-[10vmin] px-[10vmax]">
<div className="text-[6vmin]">Decide who starts by answering:</div>
<div className="flex flex-col">
<div className="text-[8vmin] rotate-180 text-text-primary opacity-60">
{randomQuestion}
</div>
<div className="text-[8vmin]">{randomQuestion}</div>
</div>
<div className="text-[6vmin]">(Tap the screen to dismiss)</div>
</div>
</div>
);
};

View File

@@ -0,0 +1,35 @@
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { PreStartMode } from '../../Types/Settings';
import { GridLayout } from '../Views/Play';
import { FingerGame } from './Games/FingerGame';
import { RandomKingPlayers } from './Games/RandomKing/RandomKingPlayers';
import { RandomKingSelectWrapper } from './Games/RandomKing/RandomKingSelectWrapper';
import { Trivia } from './Games/Trivia';
export const PreStart = ({ gridLayout }: { gridLayout: GridLayout }) => {
const { settings, randomizingPlayer, goToStart } = useGlobalSettings();
if (settings.preStartMode === PreStartMode.RandomKing) {
if (!randomizingPlayer) {
return null;
}
return (
<>
<RandomKingSelectWrapper />
<RandomKingPlayers gridLayout={gridLayout} />
</>
);
}
if (settings.preStartMode === PreStartMode.FingerGame) {
return <FingerGame />;
}
if (settings.preStartMode === PreStartMode.Trivia) {
return <Trivia />;
}
goToStart();
return null;
};

View File

@@ -0,0 +1,60 @@
import { twc } from 'react-twc';
import { baseColors } from '../../../tailwind.config';
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { Player, Rotation } from '../../Types/Player';
import { PreStartMode } from '../../Types/Settings';
import { Paragraph } from '../Misc/TextComponents';
export const DynamicText = twc.div`text-[8vmin] whitespace-nowrap`;
export const StartingPlayerCard = ({ player }: { player: Player }) => {
const { settings, setPlaying, randomizingPlayer } = useGlobalSettings();
const calcTextRotation =
player.settings.rotation === Rotation.SideFlipped ||
player.settings.rotation === Rotation.Side
? player.settings.rotation - 180
: player.settings.rotation;
const calcRotation =
player.settings.rotation === Rotation.SideFlipped ||
player.settings.rotation === Rotation.Side
? player.settings.rotation - 90
: player.settings.rotation;
return (
<div
className="z-20 flex absolute w-full h-full justify-center items-center select-none cursor-pointer webkit-user-select-none"
style={{
rotate: `${calcRotation}deg`,
backgroundImage:
!randomizingPlayer ||
(settings.preStartMode !== PreStartMode.None &&
settings.preStartMode !== PreStartMode.FingerGame)
? `radial-gradient(circle at center, ${player.color}, ${baseColors.primary.main})`
: 'none',
}}
onClick={() => {
setPlaying(true);
}}
>
<DynamicText
style={{
rotate: `${calcTextRotation}deg`,
}}
>
<div className="flex flex-col justify-center items-center">
<Paragraph>👑</Paragraph>
{(!randomizingPlayer ||
(settings.preStartMode !== PreStartMode.None &&
settings.preStartMode !== PreStartMode.FingerGame)) && (
<>
<Paragraph>You start!</Paragraph>
<Paragraph className="text-xl">(Press to hide)</Paragraph>
</>
)}
</div>
</DynamicText>
</div>
);
};

View File

@@ -1,67 +1,116 @@
import { useEffect } from 'react';
import { twc } from 'react-twc';
import { twGridTemplateAreas } from '../../../tailwind.config';
import { useGlobalSettings } from '../../Hooks/useGlobalSettings';
import { usePlayers } from '../../Hooks/usePlayers';
import { Orientation } from '../../Types/Settings';
import { Player } from '../Player/Player';
import { twc } from 'react-twc';
import { Orientation, PreStartMode } from '../../Types/Settings';
import { Players } from '../Players/Players';
import { PreStart } from '../PreStartGame/PreStart';
const MainWrapper = twc.div`w-[100dvmax] h-[100dvmin] overflow-hidden`;
const MainWrapper = twc.div`w-[100dvmax] h-[100dvmin] overflow-hidden, setPlayers`;
type GridTemplateAreasKeys = keyof typeof twGridTemplateAreas;
export type GridLayout = `grid-areas-${GridTemplateAreasKeys}`;
export const Play = () => {
const { players } = usePlayers();
const { initialGameSettings } = useGlobalSettings();
const { players, setPlayers } = usePlayers();
const { initialGameSettings, playing, settings, preStartCompleted } =
useGlobalSettings();
let Layout: JSX.Element;
let gridLayout: GridLayout;
switch (players.length) {
case 1:
if (initialGameSettings?.orientation === Orientation.Portrait) {
Layout = Player(players, 'grid-areas-onePlayerPortrait');
gridLayout = 'grid-areas-onePlayerPortrait';
}
Layout = Player(players, 'grid-areas-onePlayerLandscape');
gridLayout = 'grid-areas-onePlayerLandscape';
break;
case 2:
switch (initialGameSettings?.orientation) {
case Orientation.Portrait:
Layout = Player(players, 'grid-areas-twoPlayersOppositePortrait');
gridLayout = 'grid-areas-twoPlayersOppositePortrait';
break;
default:
case Orientation.Landscape:
Layout = Player(players, 'grid-areas-twoPlayersSameSideLandscape');
gridLayout = 'grid-areas-twoPlayersSameSideLandscape';
break;
case Orientation.OppositeLandscape:
Layout = Player(players, 'grid-areas-twoPlayersOppositeLandscape');
gridLayout = 'grid-areas-twoPlayersOppositeLandscape';
break;
}
break;
case 3:
if (initialGameSettings?.orientation === Orientation.Portrait) {
Layout = Player(players, 'grid-areas-threePlayersSide');
gridLayout = 'grid-areas-threePlayersSide';
break;
}
Layout = Player(players, 'grid-areas-threePlayers');
gridLayout = 'grid-areas-threePlayers';
break;
default:
case 4:
if (initialGameSettings?.orientation === Orientation.Portrait) {
Layout = Player(players, 'grid-areas-fourPlayerPortrait');
gridLayout = 'grid-areas-fourPlayerPortrait';
break;
}
Layout = Player(players, 'grid-areas-fourPlayer');
gridLayout = 'grid-areas-fourPlayer';
break;
case 5:
if (initialGameSettings?.orientation === Orientation.Portrait) {
Layout = Player(players, 'grid-areas-fivePlayersSide');
gridLayout = 'grid-areas-fivePlayersSide';
break;
}
Layout = Player(players, 'grid-areas-fivePlayers');
gridLayout = 'grid-areas-fivePlayers';
break;
case 6:
if (initialGameSettings?.orientation === Orientation.Portrait) {
Layout = Player(players, 'grid-areas-sixPlayersSide');
gridLayout = 'grid-areas-sixPlayersSide';
break;
}
Layout = Player(players, 'grid-areas-sixPlayers');
gridLayout = 'grid-areas-sixPlayers';
break;
}
return <MainWrapper>{Layout}</MainWrapper>;
useEffect(() => {
if (settings.preStartMode !== PreStartMode.None) {
return;
}
const randomIndex = Math.floor(Math.random() * players.length);
setPlayers(
players.map((p) =>
p.index === randomIndex
? {
...p,
isStartingPlayer: true,
}
: {
...p,
isStartingPlayer: false,
}
)
);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
if (
players.length > 1 &&
!preStartCompleted &&
settings.preStartMode !== PreStartMode.None &&
!playing &&
settings.showStartingPlayer
) {
return (
<MainWrapper>
<PreStart gridLayout={gridLayout} />
</MainWrapper>
);
}
return (
<MainWrapper>
<Players gridLayout={gridLayout} />
</MainWrapper>
);
};

View File

@@ -1,24 +1,30 @@
import { FormControlLabel, Radio, RadioGroup } from '@mui/material';
import React from 'react';
import { theme } from '../../../Data/theme';
import { twc } from 'react-twc';
import {
FivePlayers,
FivePlayersSide,
FourPlayers,
FourPlayersSide,
OnePlayerPortrait,
SixPlayers,
SixPlayersSide,
ThreePlayers,
ThreePlayersSide,
TwoPlayersOppositeLandscape,
TwoPlayersOppositePortrait,
TwoPlayersSameSide,
} from '../../../Icons/generated/Layouts';
import { twc } from 'react-twc';
import OnePlayerLandscape from '../../../Icons/generated/Layouts/OnePlayerLandscape';
import { Orientation } from '../../../Types/Settings';
const LayoutWrapper = twc.div`flex flex-row justify-center items-center self-center w-full`;
const LayoutsRadioGroup = twc.div`flex flex-row justify-center items-center gap-4 self-center w-full`;
const Label = twc.label`flex flex-row relative max-w-[118px] hover:bg-primary-main hover:bg-opacity-5 rounded-2xl cursor-pointer`;
const Input = twc.input`peer sr-only`;
const IconWrapper = twc(
'div'
)`peer-checked:fill-primary-main fill-primary-dark max-h-[200px] h-[40vmin] w-[21vmin]`;
type LayoutOptionsProps = {
numberOfPlayers: number;
@@ -26,379 +32,212 @@ type LayoutOptionsProps = {
onChange: (orientation: Orientation) => void;
};
export const LayoutOptions: React.FC<LayoutOptionsProps> = ({
export const LayoutOptions = ({
numberOfPlayers,
selectedOrientation,
onChange,
}) => {
const iconWidth = '21vmin';
const iconHeight = '40vmin';
const iconMaxWidth = '124px';
const iconMaxHeight = '196px';
}: LayoutOptionsProps) => {
switch (numberOfPlayers) {
case 1:
return (
<LayoutsRadioGroup>
<Label htmlFor={`${numberOfPlayers}p-${Orientation.Landscape}`}>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.Landscape}`}
checked={selectedOrientation === Orientation.Landscape}
value={Orientation.Landscape}
onChange={(e) => onChange(e.target.value as Orientation)}
/>
<IconWrapper>
<OnePlayerLandscape className="w-full h-full" />
</IconWrapper>
</Label>
const renderLayoutOptions = () => {
switch (numberOfPlayers) {
case 1:
return (
<div>
<FormControlLabel
value={Orientation.Landscape}
control={
<Radio
icon={
<OnePlayerLandscape
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<OnePlayerLandscape
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
style={{ maxWidth: iconMaxWidth, maxHeight: iconMaxHeight }}
/>
}
label=""
/>
<FormControlLabel
<Label htmlFor={`${numberOfPlayers}p-${Orientation.Portrait}`}>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.Portrait}`}
checked={selectedOrientation === Orientation.Portrait}
value={Orientation.Portrait}
control={
<Radio
icon={
<OnePlayerPortrait
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<OnePlayerPortrait
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
style={{ maxWidth: iconMaxWidth, maxHeight: iconMaxHeight }}
/>
}
label=""
onChange={(e) => onChange(e.target.value as Orientation)}
/>
</div>
);
case 2:
return (
<>
<FormControlLabel
<IconWrapper>
<OnePlayerPortrait className="w-full h-full" />
</IconWrapper>
</Label>
</LayoutsRadioGroup>
);
case 2:
return (
<LayoutsRadioGroup>
<Label htmlFor={`${numberOfPlayers}p-${Orientation.Landscape}`}>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.Landscape}`}
checked={selectedOrientation === Orientation.Landscape}
value={Orientation.Landscape}
control={
<Radio
style={{ maxWidth: iconMaxWidth, maxHeight: iconMaxHeight }}
icon={
<TwoPlayersSameSide
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<TwoPlayersSameSide
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
/>
}
label=""
onChange={(e) => onChange(e.target.value as Orientation)}
/>
<FormControlLabel
<IconWrapper>
<TwoPlayersSameSide className="w-full h-full" />
</IconWrapper>
</Label>
<Label htmlFor={`${numberOfPlayers}p-${Orientation.Portrait}`}>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.Portrait}`}
checked={selectedOrientation === Orientation.Portrait}
value={Orientation.Portrait}
control={
<Radio
style={{ maxWidth: iconMaxWidth, maxHeight: iconMaxHeight }}
icon={
<TwoPlayersOppositePortrait
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<TwoPlayersOppositePortrait
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
/>
}
label=""
onChange={(e) => onChange(e.target.value as Orientation)}
/>
<FormControlLabel
<IconWrapper>
<TwoPlayersOppositePortrait className="w-full h-full" />
</IconWrapper>
</Label>
<Label
htmlFor={`${numberOfPlayers}p-${Orientation.OppositeLandscape}`}
>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.OppositeLandscape}`}
checked={selectedOrientation === Orientation.OppositeLandscape}
value={Orientation.OppositeLandscape}
control={
<Radio
style={{ maxWidth: iconMaxWidth, maxHeight: iconMaxHeight }}
icon={
<TwoPlayersOppositeLandscape
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<TwoPlayersOppositeLandscape
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
/>
}
label=""
onChange={(e) => onChange(e.target.value as Orientation)}
/>
</>
);
case 3:
return (
<>
<FormControlLabel
<IconWrapper>
<TwoPlayersOppositeLandscape className="w-full h-full" />
</IconWrapper>
</Label>
</LayoutsRadioGroup>
);
case 3:
return (
<LayoutsRadioGroup>
<Label htmlFor={`${numberOfPlayers}p-${Orientation.Landscape}`}>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.Landscape}`}
checked={selectedOrientation === Orientation.Landscape}
value={Orientation.Landscape}
control={
<Radio
style={{ maxWidth: iconMaxWidth, maxHeight: iconMaxHeight }}
icon={
<ThreePlayers
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<ThreePlayers
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
/>
}
label=""
onChange={(e) => onChange(e.target.value as Orientation)}
/>
<FormControlLabel
<IconWrapper>
<ThreePlayers className="w-full h-full" />
</IconWrapper>
</Label>
<Label htmlFor={`${numberOfPlayers}p-${Orientation.Portrait}`}>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.Portrait}`}
checked={selectedOrientation === Orientation.Portrait}
value={Orientation.Portrait}
control={
<Radio
style={{ maxWidth: iconMaxWidth, maxHeight: iconMaxHeight }}
icon={
<ThreePlayersSide
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<ThreePlayersSide
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
/>
}
label=""
onChange={(e) => onChange(e.target.value as Orientation)}
/>
</>
);
<IconWrapper>
<ThreePlayersSide className="w-full h-full" />
</IconWrapper>
</Label>
</LayoutsRadioGroup>
);
case 4:
return (
<>
<FormControlLabel
case 4:
return (
<LayoutsRadioGroup>
<Label htmlFor={`${numberOfPlayers}p-${Orientation.Landscape}`}>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.Landscape}`}
checked={selectedOrientation === Orientation.Landscape}
value={Orientation.Landscape}
control={
<Radio
style={{ maxWidth: iconMaxWidth, maxHeight: iconMaxHeight }}
icon={
<FourPlayers
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<FourPlayers
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
/>
}
label=""
onChange={(e) => onChange(e.target.value as Orientation)}
/>
<FormControlLabel
<IconWrapper>
<FourPlayers className="w-full h-full" />
</IconWrapper>
</Label>
<Label htmlFor={`${numberOfPlayers}p-${Orientation.Portrait}`}>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.Portrait}`}
checked={selectedOrientation === Orientation.Portrait}
value={Orientation.Portrait}
control={
<Radio
style={{ maxWidth: iconMaxWidth, maxHeight: iconMaxHeight }}
icon={
<FourPlayersSide
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<FourPlayersSide
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
/>
}
label=""
onChange={(e) => onChange(e.target.value as Orientation)}
/>
</>
);
<IconWrapper>
<FourPlayersSide className="w-full h-full" />
</IconWrapper>
</Label>
</LayoutsRadioGroup>
);
case 5:
return (
<>
<FormControlLabel
case 5:
return (
<LayoutsRadioGroup>
<Label htmlFor={`${numberOfPlayers}p-${Orientation.Landscape}`}>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.Landscape}`}
checked={selectedOrientation === Orientation.Landscape}
value={Orientation.Landscape}
control={
<Radio
style={{ maxWidth: iconMaxWidth, maxHeight: iconMaxHeight }}
icon={
<FivePlayers
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<FivePlayers
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
/>
}
label=""
onChange={(e) => onChange(e.target.value as Orientation)}
/>
{/* <FormControlLabel
value={GridTemplateAreas.FivePlayersSide}
control={
<Radio
icon={
<FivePlayersSide
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<FivePlayersSide
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
/>
}
label=""
/> */}
</>
);
<IconWrapper>
<FivePlayers className="w-full h-full" />
</IconWrapper>
</Label>
case 6:
return (
<>
<FormControlLabel
<Label htmlFor={`${numberOfPlayers}p-${Orientation.Portrait}`}>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.Portrait}`}
checked={selectedOrientation === Orientation.Portrait}
value={Orientation.Portrait}
onChange={(e) => onChange(e.target.value as Orientation)}
/>
<IconWrapper>
<FivePlayersSide className="w-full h-full" />
</IconWrapper>
</Label>
</LayoutsRadioGroup>
);
case 6:
return (
<LayoutsRadioGroup>
<Label htmlFor={`${numberOfPlayers}p-${Orientation.Landscape}`}>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.Landscape}`}
checked={selectedOrientation === Orientation.Landscape}
value={Orientation.Landscape}
control={
<Radio
style={{ maxWidth: iconMaxWidth, maxHeight: iconMaxHeight }}
icon={
<SixPlayers
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<SixPlayers
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
/>
}
label=""
onChange={(e) => onChange(e.target.value as Orientation)}
/>
{/* <FormControlLabel
value={GridTemplateAreas.SixPlayersSide}
control={
<Radio
icon={
<SixPlayersSide
height={iconHeight}
width={iconWidth}
fill={theme.palette.secondary.main}
/>
}
checkedIcon={
<SixPlayersSide
height={iconHeight}
width={iconWidth}
fill={theme.palette.primary.main}
/>
}
TouchRippleProps={{ style: { display: 'none' } }}
/>
}
label=""
/> */}
</>
);
<IconWrapper>
<SixPlayers className="w-full h-full" />
</IconWrapper>
</Label>
default:
return null;
}
};
<Label htmlFor={`${numberOfPlayers}p-${Orientation.Portrait}`}>
<Input
type="radio"
id={`${numberOfPlayers}p-${Orientation.Portrait}`}
checked={selectedOrientation === Orientation.Portrait}
value={Orientation.Portrait}
onChange={(e) => onChange(e.target.value as Orientation)}
/>
<IconWrapper>
<SixPlayersSide className="w-full h-full" />
</IconWrapper>
</Label>
</LayoutsRadioGroup>
);
return (
<LayoutWrapper>
<RadioGroup
row
onChange={(_e, value) => {
onChange(value as Orientation);
}}
value={selectedOrientation}
style={{ justifyContent: 'center' }}
>
{renderLayoutOptions()}
</RadioGroup>
</LayoutWrapper>
);
default:
return null;
}
};

View File

@@ -1,82 +1,52 @@
import { Button, FormControl, FormLabel, Switch } from '@mui/material';
import Slider from '@mui/material/Slider';
import { useEffect, useState } from 'react';
import { useEffect, useRef, useState } from 'react';
import { twc } from 'react-twc';
import { createInitialPlayers } from '../../../Data/getInitialPlayers';
import { theme } from '../../../Data/theme';
import { useAnalytics } from '../../../Hooks/useAnalytics';
import { useGlobalSettings } from '../../../Hooks/useGlobalSettings';
import { usePlayers } from '../../../Hooks/usePlayers';
import { Cog, Info } from '../../../Icons/generated';
import { Cog, Info, Trinket } from '../../../Icons/generated';
import {
GameFormat,
InitialGameSettings,
Orientation,
PreStartMode,
defaultInitialGameSettings,
} from '../../../Types/Settings';
import { InfoModal } from '../../Misc/InfoModal';
import { SettingsModal } from '../../Misc/SettingsModal';
import { SupportMe } from '../../Misc/SupportMe';
import { baseColors } from '../../../../tailwind.config';
import { InfoDialog } from '../../Dialogs/InfoDialog';
import { SettingsDialog } from '../../Dialogs/SettingsDialog';
import { ToggleButton } from '../../Misc/ToggleButton';
import { LayoutOptions } from './LayoutOptions';
const MainWrapper = twc.div`w-[100dvw] h-fit pb-14 overflow-hidden items-center flex flex-col`;
const commanderSettings: Pick<
InitialGameSettings,
'numberOfPlayers' | 'startingLifeTotal' | 'orientation'
> = {
numberOfPlayers: 4,
startingLifeTotal: 40,
orientation: Orientation.Landscape,
};
const StartButtonFooter = twc.div`w-full max-w-[548px] fixed bottom-4 z-1 items-center flex flex-col px-4`;
const standardSettings: Pick<
InitialGameSettings,
'numberOfPlayers' | 'startingLifeTotal' | 'orientation'
> = {
numberOfPlayers: 2,
startingLifeTotal: 20,
orientation: Orientation.Landscape,
};
const SliderWrapper = twc.div`mx-8`;
const MainWrapper = twc.div`h-fit w-full pb-24 overflow-hidden items-center flex flex-col min-[349px]:pb-10`;
const StartButtonFooter = twc.div`w-full max-w-[548px] fixed bottom-4 z-1 items-center flex flex-row flex-wrap px-4 z-10 gap-4`;
const SliderWrapper = twc.div`mx-8 relative`;
const ToggleButtonsWrapper = twc.div`flex flex-row justify-between items-center`;
const ToggleContainer = twc.div`flex flex-col items-center`;
export const LabelText = twc.div`text-md text-text-primary font-medium`;
const playerMarks = [
{
value: 1,
label: '1',
},
{
value: 2,
label: '2',
},
{
value: 3,
label: '3',
},
{
value: 4,
label: '4',
},
{
value: 5,
label: '5',
},
{
value: 6,
label: '6',
},
];
const healthMarks = [
{
value: 20,
label: '20',
},
{
value: 30,
label: '30',
},
{
value: 40,
label: '40',
},
{
value: 50,
label: '50',
},
{
value: 60,
label: '60',
},
];
let tracked = false;
const Start = () => {
const { setPlayers } = usePlayers();
@@ -89,27 +59,114 @@ const Start = () => {
setInitialGameSettings,
settings,
isPWA,
setRandomizingPlayer,
version,
setPlaying,
savedGame,
saveCurrentGame,
} = useGlobalSettings();
const [openInfoModal, setOpenInfoModal] = useState(false);
const [openSettingsModal, setOpenSettingsModal] = useState(false);
const infoDialogRef = useRef<HTMLDialogElement | null>(null);
const settingsDialogRef = useRef<HTMLDialogElement | null>(null);
const playersSliderRef = useRef<HTMLInputElement | null>(null);
const healthSliderRef = useRef<HTMLInputElement | null>(null);
const [playerOptions, setPlayerOptions] = useState<InitialGameSettings>(
initialGameSettings || {
numberOfPlayers: 4,
startingLifeTotal: 40,
useCommanderDamage: true,
orientation: Orientation.Portrait,
gameFormat: GameFormat.Commander,
}
initialGameSettings || defaultInitialGameSettings
);
const doStartGame = () => {
// Check for new version on mount
useEffect(() => {
if (!tracked) {
version.checkForNewVersion('start_menu');
tracked = true;
}
});
useEffect(() => {
if (!playersSliderRef.current) {
return;
}
let progress = 0;
switch (playerOptions?.numberOfPlayers) {
case 1:
progress = 0;
break;
case 2:
progress = 20;
break;
case 3:
progress = 40;
break;
case 4:
progress = 60;
break;
case 5:
progress = 80;
break;
case 6:
progress = 100;
break;
default:
break;
}
playersSliderRef.current.style.background = `linear-gradient(to right, ${baseColors.secondary.main} ${progress}%, ${baseColors.secondary.dark} ${progress}%)`;
}, [playerOptions?.numberOfPlayers]);
useEffect(() => {
if (!healthSliderRef.current) {
return;
}
let progress = 0;
switch (playerOptions?.startingLifeTotal) {
case 20:
progress = 0;
break;
case 30:
progress = 25;
break;
case 40:
progress = 50;
break;
case 50:
progress = 75;
break;
case 60:
progress = 100;
break;
default:
break;
}
healthSliderRef.current.style.background = `linear-gradient(to right, ${baseColors.secondary.main} ${progress}%, ${baseColors.secondary.dark} ${progress}%)`;
}, [playerOptions?.startingLifeTotal]);
useEffect(() => {
setInitialGameSettings(playerOptions);
}, [playerOptions, setInitialGameSettings]);
useEffect(() => {
setPlayerOptions({
...playerOptions,
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [playerOptions.numberOfPlayers]);
const doStartNewGame = () => {
if (!initialGameSettings) {
return;
}
analytics.trackEvent('game_started', { ...initialGameSettings });
analytics.trackEvent('game_started', {
...initialGameSettings,
...settings,
isPWA,
});
try {
if (settings.goFullscreenOnStart) {
@@ -125,186 +182,246 @@ const Start = () => {
setInitialGameSettings(initialGameSettings);
setPlayers(createInitialPlayers(initialGameSettings));
setRandomizingPlayer(settings.preStartMode === PreStartMode.RandomKing);
setShowPlay(true);
localStorage.setItem('playing', 'false');
localStorage.setItem('showPlay', 'true');
setPlaying(false);
tracked = false;
};
useEffect(() => {
setInitialGameSettings(playerOptions);
}, [playerOptions, setInitialGameSettings]);
const doResumeGame = () => {
if (!savedGame) {
return;
}
const valuetext = (value: number) => {
return `${value}`;
};
useEffect(() => {
setPlayerOptions({
...playerOptions,
analytics.trackEvent('game_resumed', {
...initialGameSettings,
...settings,
isPWA,
});
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [playerOptions.numberOfPlayers]);
try {
if (settings.goFullscreenOnStart) {
fullscreen.enableFullscreen();
}
} catch (error) {
console.error(error);
}
if (settings.keepAwake && !wakeLock.active) {
wakeLock.request();
}
setInitialGameSettings(savedGame.initialGameSettings);
setPlayers(savedGame.players);
saveCurrentGame(null);
setRandomizingPlayer(false);
setShowPlay(true);
setPlaying(true);
tracked = false;
};
const openInfo = () => {
if (infoDialogRef.current) {
infoDialogRef.current.showModal();
}
};
const openSettings = () => {
if (settingsDialogRef.current) {
settingsDialogRef.current.showModal();
version.checkForNewVersion('settings');
}
};
return (
<MainWrapper>
<Info
color={theme.palette.primary.light}
size="2rem"
style={{ position: 'absolute', top: '1rem', left: '1rem' }}
onClick={() => {
setOpenInfoModal(!openInfoModal);
}}
/>
<>
<InfoDialog dialogRef={infoDialogRef} />
{settings.showAnimations && (
<>
<div className="spotlight1" />
<div className="spotlight2" />
</>
)}
<InfoModal
closeModal={() => {
setOpenInfoModal(false);
}}
isOpen={openInfoModal}
/>
<SettingsDialog dialogRef={settingsDialogRef} />
<div className="flex justify-center items-center w-screen">
<MainWrapper>
<Info
className="size-8 absolute top-7 left-4 text-primary-main"
onClick={() => {
openInfo();
}}
/>
<a href="https://lifetrinket.com/">
<Trinket className="absolute w-12 h-12 top-4 right-4" />
</a>
<SettingsModal
closeModal={() => {
setOpenSettingsModal(false);
}}
isOpen={openSettingsModal}
/>
<h1 className="relative flex flex-col text-3xl font-bold mt-6 mb-6 text-text-primary justify-center items-center">
<div className="flex flex-row items-center">Life Trinket</div>
<div className="h-[1px] w-[120%] bg-common-white opacity-50" />
<div className="flex absolute text-xs font-medium -bottom-4">
v{version.installedVersion}
</div>
</h1>
<SupportMe />
<h1 className="text-3xl block font-bold mt-6 mb-5 text-text-primary">
Life Trinket
</h1>
<div className="overflow-hidden items-center flex flex-col max-w-[548px] w-full mb-8 px-4">
<FormControl focused={false} style={{ width: '100%' }}>
<FormLabel>Number of Players</FormLabel>
<SliderWrapper>
<Slider
title="Number of Players"
max={6}
min={1}
aria-label="Custom marks"
value={playerOptions?.numberOfPlayers ?? 4}
getAriaValueText={valuetext}
step={null}
marks={playerMarks}
onChange={(_e, value) => {
setPlayerOptions({
...playerOptions,
numberOfPlayers: value as number,
orientation: Orientation.Landscape,
});
}}
/>
</SliderWrapper>
<FormLabel className="mt-[0.7rem]">Starting Health</FormLabel>
<SliderWrapper>
<Slider
title="Starting Health"
max={60}
min={20}
aria-label="Custom marks"
value={playerOptions?.startingLifeTotal ?? 40}
getAriaValueText={valuetext}
step={10}
marks={healthMarks}
onChange={(_e, value) =>
setPlayerOptions({
...playerOptions,
startingLifeTotal: value as number,
orientation: Orientation.Landscape,
})
}
/>
</SliderWrapper>
<ToggleButtonsWrapper className="mt-4">
<ToggleContainer>
<FormLabel>Commander</FormLabel>
<Switch
checked={
playerOptions.useCommanderDamage ??
initialGameSettings?.useCommanderDamage ??
true
}
onChange={(_e, value) => {
if (value) {
<div className="overflow-hidden items-center flex flex-col max-w-[548px] w-full mb-8 px-4">
<div className="w-full">
<ToggleButtonsWrapper className="mt-4">
<ToggleButton
label="Commander"
checked={
playerOptions.useCommanderDamage ??
initialGameSettings?.useCommanderDamage ??
true
}
onChange={(e) => {
if (e.target.checked) {
setPlayerOptions({
...playerOptions,
useCommanderDamage: e.target.checked,
...commanderSettings,
});
return;
}
setPlayerOptions({
...playerOptions,
useCommanderDamage: value,
numberOfPlayers: 4,
startingLifeTotal: 40,
useCommanderDamage: e.target.checked,
...standardSettings,
});
}}
/>
<div className="flex flex-nowrap text-nowrap relative justify-center items-start">
<button
className="flex justify-center self-center items-center mt-1 mb-1 bg-primary-main px-3 py-2 rounded-md transition-colors duration-200 ease-in-out shadow-[1px_2px_4px_0px_rgba(0,0,0,0.3)] hover:bg-primary-dark"
onClick={openSettings}
>
<span className="text-sm flex flex-row items-center text-text-primary font-bold">
<Cog />
&nbsp;Game Settings
</span>
</button>
<div
data-not-latest-version={
!version.isLatest && !!version.remoteVersion
}
className="absolute flex justify-center text-text-primary text-xxs -bottom-5 bg-primary-dark px-2 rounded-md
opacity-0 transition-all duration-200 delay-500
data-[not-latest-version=true]:opacity-100
"
>
<div className="absolute bg-primary-dark rotate-45 size-2 -top-[2px] z-0" />
<span className="z-10">
v{version.remoteVersion} available!
</span>
</div>
</div>
</ToggleButtonsWrapper>
<LabelText className="mt-4">Number of Players</LabelText>
<SliderWrapper>
<input
ref={playersSliderRef}
className="accent-primary-main text-primary-dark w-full h-3 rounded-lg cursor-pointer"
title="Number of Players"
type="range"
max={6}
min={1}
value={playerOptions?.numberOfPlayers ?? 4}
onChange={(e) => {
setPlayerOptions({
...playerOptions,
numberOfPlayers: Number.parseInt(e.target.value),
orientation: Orientation.Landscape,
});
return;
}}
/>
<div className="flex w-full justify-between px-[6px] text-text-primary pointer-events-none">
<div>1</div>
<div>2</div>
<div>3</div>
<div>4</div>
<div>5</div>
<div>6</div>
</div>
</SliderWrapper>
<LabelText className="mt-4">Starting Health</LabelText>
<SliderWrapper>
<input
ref={healthSliderRef}
className="accent-primary-main text-primary-dark w-full h-3 rounded-lg cursor-pointer"
title="Starting Health"
type="range"
max={60}
min={20}
aria-label="Custom marks"
value={playerOptions?.startingLifeTotal ?? 40}
step={10}
onChange={(e) =>
setPlayerOptions({
...playerOptions,
startingLifeTotal: Number.parseInt(e.target.value),
orientation: Orientation.Landscape,
})
}
/>
<div className="flex w-full justify-between text-text-primary pointer-events-none">
<div>20</div>
<div>30</div>
<div>40</div>
<div>50</div>
<div>60</div>
</div>
</SliderWrapper>
<LabelText className="mt-4">Layout</LabelText>
<LayoutOptions
numberOfPlayers={playerOptions.numberOfPlayers}
selectedOrientation={playerOptions.orientation}
onChange={(orientation) => {
setPlayerOptions({
...playerOptions,
useCommanderDamage: value,
numberOfPlayers: 2,
startingLifeTotal: 20,
orientation: Orientation.Landscape,
orientation,
});
}}
/>
</ToggleContainer>
<Button
variant="contained"
style={{ height: '2rem' }}
onClick={() => {
setOpenSettingsModal(true);
}}
</div>
{!isPWA && (
<p className="text-center text-xs text-text-primary w-11/12 mt-4">
If you're on iOS, this page works better if you{' '}
<strong>hide the toolbar</strong> or{' '}
<strong>add the app to your home screen</strong>.
</p>
)}
</div>
<StartButtonFooter>
<button
className="flex flex-grow basis-0 justify-center self-center items-center bg-primary-main px-3 py-2 rounded-md text-text-primary min-w-[150px] duration-200 ease-in-out shadow-[1px_2px_4px_0px_rgba(0,0,0,0.3)] hover:bg-primary-dark font-bold"
onClick={doStartNewGame}
>
<Cog /> &nbsp; Other settings
</Button>
</ToggleButtonsWrapper>
NEW GAME
</button>
<FormLabel>Layout</FormLabel>
{/* <LayoutOptions
numberOfPlayers={playerOptions.numberOfPlayers}
gridAreas={playerOptions.gridAreas}
onChange={(gridAreas) =>
setPlayerOptions({
...playerOptions,
gridAreas,
//TODO fix the layout selection
orientation: Orientation.Portrait,
})
}
/> */}
<LayoutOptions
numberOfPlayers={playerOptions.numberOfPlayers}
selectedOrientation={playerOptions.orientation}
onChange={(orientation) => {
setPlayerOptions({
...playerOptions,
orientation,
});
}}
/>
</FormControl>
{!isPWA && (
<p className="text-center text-xs text-text-primary w-11/12 mt-4">
If you're on iOS, this page works better if you{' '}
<strong>hide the toolbar</strong> or{' '}
<strong>add the app to your home screen</strong>.
</p>
)}
{savedGame && (
<button
className="flex flex-grow basis-0 justify-center self-center items-center bg-secondary-main px-3 py-2 rounded-md text-text-primary min-w-[150px]
duration-200 ease-in-out shadow-[1px_2px_4px_0px_rgba(0,0,0,0.3)] hover:bg-secondary-dark font-bold"
onClick={doResumeGame}
>
RESUME&nbsp;
<span className="text-xs">
({savedGame.players.length}&nbsp;
{savedGame.players.length > 1 ? 'players' : 'player'})
</span>
</button>
)}
</StartButtonFooter>
</MainWrapper>
</div>
<StartButtonFooter>
<Button
size="large"
variant="contained"
onClick={doStartGame}
fullWidth
>
START GAME
</Button>
</StartButtonFooter>
</MainWrapper>
</>
);
};

View File

@@ -1,5 +1,18 @@
import { createContext } from 'react';
import { InitialGameSettings, Settings } from '../Types/Settings';
import { Player } from '../Types/Player';
type Version = {
installedVersion: string;
isLatest: boolean;
checkForNewVersion: (source: 'settings' | 'start_menu') => Promise<void>;
remoteVersion?: string;
};
export type SavedGame = {
initialGameSettings: InitialGameSettings;
players: Player[];
} | null;
export type GlobalSettingsContextType = {
fullscreen: {
@@ -18,11 +31,20 @@ export type GlobalSettingsContextType = {
goToStart: () => void;
showPlay: boolean;
setShowPlay: (showPlay: boolean) => void;
initialGameSettings: InitialGameSettings | null;
initialGameSettings: InitialGameSettings;
setInitialGameSettings: (initialGameSettings: InitialGameSettings) => void;
settings: Settings;
setSettings: (settings: Settings) => void;
playing: boolean;
setPlaying: (playing: boolean) => void;
randomizingPlayer: boolean;
setRandomizingPlayer: (stopRandom: boolean) => void;
isPWA: boolean;
preStartCompleted: boolean;
setPreStartCompleted: (completed: boolean) => void;
version: Version;
savedGame: SavedGame;
saveCurrentGame: (currentGame: SavedGame) => void;
};
export const GlobalSettingsContext =

View File

@@ -7,6 +7,8 @@ export type PlayersContextType = {
updatePlayer: (updatedPlayer: Player) => void;
updateLifeTotal: (player: Player, updatedLifeTotal: number) => number;
resetCurrentGame: () => void;
startingPlayerIndex: number;
setStartingPlayerIndex: (index: number) => void;
};
export const PlayersContext = createContext<PlayersContextType | null>(null);

View File

@@ -1,7 +1,7 @@
import { Player, Rotation } from '../Types/Player';
import { InitialGameSettings, Orientation } from '../Types/Settings';
const presetColors = [
export const presetColors = [
'#F06292', // Light Pink
'#4DB6AC', // Teal
'#FFA726', // Orange
@@ -127,15 +127,15 @@ const getOrientationRotations = (
case Orientation.Portrait:
switch (index) {
case 0:
return Rotation.Side;
return Rotation.Flipped;
case 1:
return Rotation.Side;
return Rotation.Flipped;
case 2:
return Rotation.SideFlipped;
return Rotation.Side;
case 3:
return Rotation.SideFlipped;
return Rotation.Normal;
case 4:
return Rotation.SideFlipped;
return Rotation.Normal;
default:
return Rotation.Normal;
}
@@ -163,17 +163,17 @@ const getOrientationRotations = (
case Orientation.Portrait:
switch (index) {
case 0:
return Rotation.Side;
return Rotation.SideFlipped;
case 1:
return Rotation.Side;
return Rotation.Flipped;
case 2:
return Rotation.Side;
return Rotation.Flipped;
case 3:
return Rotation.SideFlipped;
return Rotation.Side;
case 4:
return Rotation.SideFlipped;
return Rotation.Normal;
case 5:
return Rotation.SideFlipped;
return Rotation.Normal;
default:
return Rotation.Normal;
}
@@ -191,10 +191,8 @@ export const createInitialPlayers = ({
}: InitialGameSettings): Player[] => {
const players: Player[] = [];
const availableColors = [...presetColors]; // Create a copy of the colors array
const firstPlayerIndex = Math.floor(Math.random() * numberOfPlayers);
for (let i = 0; i <= numberOfPlayers - 1; i++) {
const isStartingPlayer = i === firstPlayerIndex;
const colorIndex = Math.floor(Math.random() * availableColors.length);
const color = availableColors[colorIndex];
@@ -224,11 +222,10 @@ export const createInitialPlayers = ({
usePoison: false,
rotation,
},
isStartingPlayer,
showStartingPlayer: isStartingPlayer,
extraCounters: [],
commanderDamage,
hasLost: false,
isStartingPlayer: false,
isSide: rotation === Rotation.Side || rotation === Rotation.SideFlipped,
};

View File

@@ -1,102 +0,0 @@
import { createTheme } from '@mui/material';
import resolveConfig from 'tailwindcss/resolveConfig';
import tailwindConfig from '../../tailwind.config';
//TODO Create provider for this
const fullConfig = resolveConfig(tailwindConfig);
const { primary, secondary, background, text, action, common } =
fullConfig.theme.colors;
export const theme = createTheme({
palette: {
primary,
secondary,
background,
text,
action,
common,
},
components: {
MuiFormLabel: {
styleOverrides: {
root: {
fontSize: '1rem',
color: text.primary,
},
},
},
MuiSlider: {
styleOverrides: {
markLabel: {
fontSize: '1rem',
color: text.primary,
},
valueLabel: {
display: 'none',
color: text.primary,
background: secondary.main,
},
track: {
height: '0.7rem',
},
rail: {
height: '0.7rem',
},
mark: {
width: '0.5rem',
height: '0.5rem',
borderRadius: '50%',
display: 'none',
},
thumb: {
width: '1.3rem',
height: '1.3rem',
},
},
},
MuiFormControlLabel: {
styleOverrides: {
root: {
margin: '0',
},
},
},
MuiFormGroup: {
styleOverrides: {
root: {},
},
},
MuiDrawer: {
styleOverrides: {
paper: {
top: '1rem',
background: background.default,
height: 'auto',
borderRadius: '8px',
},
},
},
MuiBackdrop: {
styleOverrides: {
root: {
backgroundColor: background.backdrop,
},
},
},
MuiButton: {
styleOverrides: {
root: {
textTransform: 'none',
},
},
},
MuiSwitch: {
styleOverrides: {
colorPrimary: {
color: action.disabled,
},
},
},
},
});

View File

@@ -18,7 +18,17 @@ export const useAnalytics = () => {
eventName: string,
eventParams?: { [key: string]: unknown }
) => {
logEvent(analytics, eventName, eventParams);
if (process.env.NODE_ENV === 'development') {
console.info('Event not tracked:', { eventName, eventParams });
return;
}
const paramsWithVersion = {
...eventParams,
app_version: import.meta.env.VITE_APP_VERSION,
};
logEvent(analytics, eventName, paramsWithVersion);
};
return { trackEvent };

View File

@@ -23,7 +23,6 @@ export default function useOrientation(
const onChange = () => {
if (mounted) {
const { orientation } = screen;
console.log(orientation);
if (orientation) {
const { angle, type } = orientation;

View File

@@ -0,0 +1,45 @@
import PropTypes from 'prop-types';
import { SVGProps } from 'react';
interface SVGRProps {
title?: string;
titleId?: string;
size?: string;
}
const Close = ({
title,
titleId,
...props
}: SVGProps<SVGSVGElement> & SVGRProps) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={props.size || 16}
height={props.size || 16}
fill="currentColor"
viewBox="0 0 52 52"
aria-labelledby={titleId}
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path
fillRule="evenodd"
d="M26 48c12.15 0 22-9.85 22-22S38.15 4 26 4 4 13.85 4 26s9.85 22 22 22m0 4c14.36 0 26-11.64 26-26S40.36 0 26 0 0 11.64 0 26s11.64 26 26 26"
clipRule="evenodd"
/>
<path
fillRule="evenodd"
d="M15.586 15.586a2 2 0 0 1 2.828 0l18 18a2 2 0 1 1-2.828 2.828l-18-18a2 2 0 0 1 0-2.828"
clipRule="evenodd"
/>
<path
fillRule="evenodd"
d="M36.414 15.586a2 2 0 0 1 0 2.828l-18 18a2 2 0 1 1-2.828-2.828l18-18a2 2 0 0 1 2.828 0"
clipRule="evenodd"
/>
</svg>
);
};
Close.propTypes = {
title: PropTypes.string,
};
export default Close;

View File

@@ -22,7 +22,7 @@ const Cog = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M80.7 1c-4.6 1.4-9.4 5.7-11.6 10.3-1.6 3.4-2.1 6.2-2.1 12.8v8.5l-5.7-5.4C48.2 15 38.1 15 26.3 27.1 14.9 38.9 15.2 49.2 27.4 61l5.7 5.5-10.1.6c-9 .5-10.4.8-14.2 3.5-2.3 1.6-5.2 4.9-6.6 7.4-2.1 4-2.3 5.5-2 14 .4 11.1 2.4 15.4 9 19.8 3.5 2.2 5.3 2.7 13.4 3l9.4.4-5.2 5.7c-11.6 12.7-11.8 22.4-.5 34 5.7 5.8 11.5 9 16.3 9.1 7 0 9.7-1.3 16.9-8.2l7.3-6.8.4 9.9c.3 8.6.7 10.3 3 13.8 1.5 2.2 4.4 5.1 6.5 6.4 3.4 2.1 5 2.4 14.3 2.4s10.9-.3 14.3-2.4c2.1-1.3 5-4.1 6.5-6.3 2.3-3.5 2.7-5.3 3-13.5l.4-9.5 4.2 4c7.3 6.9 11.1 9.2 16.4 9.9 7 .8 11.7-1.1 18.6-7.6 12.7-12.1 12.9-22.2.5-34.7l-6.1-6.2 9.9-.4c8.9-.3 10.2-.6 14.2-3.3 6.2-4.2 8.5-9.1 8.9-19.2.5-10.7-2.4-17.7-9-21.9-3.8-2.5-5.5-2.9-14.2-3.2l-9.8-.4 6.1-6.2c12.2-12.4 12.2-22.4 0-34.3-11.6-11.2-20.5-11.2-33.4.2l-6.3 5.5-.4-9.4c-.3-8.1-.8-9.9-3-13.4-4.4-6.6-8.7-8.6-19.3-8.9-4.9-.1-10.3.2-11.8.7zm24.4 59.9c5.9 3 12.1 9.2 15 14.9 2.1 4 2.4 6.1 2.4 14.7 0 8.5-.3 10.7-2.3 14.5-3.2 6.1-8.7 11.6-14.7 14.8-4.5 2.4-6.1 2.7-15 2.7s-10.5-.3-15-2.7c-6-3.2-11.5-8.7-14.7-14.8-3.1-6-3.7-18.6-1.3-25.9 2.7-8.3 12.1-17.4 20.6-20 6-1.8 19.9-.8 25 1.8z" />
<path d="M80.7 1c-4.6 1.4-9.4 5.7-11.6 10.3-1.6 3.4-2.1 6.2-2.1 12.8v8.5l-5.7-5.4C48.2 15 38.1 15 26.3 27.1 14.9 38.9 15.2 49.2 27.4 61l5.7 5.5-10.1.6c-9 .5-10.4.8-14.2 3.5-2.3 1.6-5.2 4.9-6.6 7.4-2.1 4-2.3 5.5-2 14 .4 11.1 2.4 15.4 9 19.8 3.5 2.2 5.3 2.7 13.4 3l9.4.4-5.2 5.7c-11.6 12.7-11.8 22.4-.5 34 5.7 5.8 11.5 9 16.3 9.1 7 0 9.7-1.3 16.9-8.2l7.3-6.8.4 9.9c.3 8.6.7 10.3 3 13.8 1.5 2.2 4.4 5.1 6.5 6.4 3.4 2.1 5 2.4 14.3 2.4s10.9-.3 14.3-2.4c2.1-1.3 5-4.1 6.5-6.3 2.3-3.5 2.7-5.3 3-13.5l.4-9.5 4.2 4c7.3 6.9 11.1 9.2 16.4 9.9 7 .8 11.7-1.1 18.6-7.6 12.7-12.1 12.9-22.2.5-34.7l-6.1-6.2 9.9-.4c8.9-.3 10.2-.6 14.2-3.3 6.2-4.2 8.5-9.1 8.9-19.2.5-10.7-2.4-17.7-9-21.9-3.8-2.5-5.5-2.9-14.2-3.2l-9.8-.4 6.1-6.2c12.2-12.4 12.2-22.4 0-34.3-11.6-11.2-20.5-11.2-33.4.2l-6.3 5.5-.4-9.4c-.3-8.1-.8-9.9-3-13.4-4.4-6.6-8.7-8.6-19.3-8.9-4.9-.1-10.3.2-11.8.7m24.4 59.9c5.9 3 12.1 9.2 15 14.9 2.1 4 2.4 6.1 2.4 14.7 0 8.5-.3 10.7-2.3 14.5-3.2 6.1-8.7 11.6-14.7 14.8-4.5 2.4-6.1 2.7-15 2.7s-10.5-.3-15-2.7c-6-3.2-11.5-8.7-14.7-14.8-3.1-6-3.7-18.6-1.3-25.9 2.7-8.3 12.1-17.4 20.6-20 6-1.8 19.9-.8 25 1.8" />
</svg>
);
};

View File

@@ -22,7 +22,7 @@ const CommanderTax = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M256 23.9c-1.9.4-5.5 1.8-7.9 3.2-5.1 2.8-130.3 133.3-135.8 141.5-5.4 8.1-7.5 14.7-8.1 25.5-.5 11.3.7 17.6 5.2 26.9 3.7 7.8 13.8 18.4 21.1 22.1 2.8 1.4 20.4 7.5 39.3 13.4 18.8 6 33.7 11.2 33 11.6-.7.3-24.2 9.3-52.3 19.9-32.8 12.4-52.9 20.5-56.3 22.7-6 4-12 10.7-15.6 17.4-1.5 2.7-9.7 31.1-20.6 71.5C41.3 461.3 39.9 467 40.3 473c.9 12.3 7.2 21.7 18.5 27.2l6.7 3.3H262c190.8 0 196.7-.1 202-1.9 7.5-2.6 15.9-11 18.8-18.9 4.1-10.8 3.9-11.8-15.3-81.5-9.6-35-18.7-66.6-20.2-70.1-3.4-8.3-13-18.6-21-22.8-3.2-1.7-27.9-11.5-55-21.9-27.1-10.4-48.9-19.2-48.5-19.5.4-.4 15.1-5.3 32.7-10.8 17.6-5.6 34.5-11.4 37.5-12.9 11.4-5.6 23-20.5 25.9-33.2 2.7-11.5.7-27.5-4.7-37.3-3.6-6.7-5.2-8.5-73.7-80.2-45.1-47.2-61.4-63.7-65.1-65.7-5.3-2.8-13.7-4.1-19.4-2.9zm32.5 97.6c9.3 1.8 31.6 8.3 32.9 9.5 1.6 1.5-12.1 43.6-18.3 56.5-6 12.3-16.1 27.7-22.6 34.7-7.3 7.7-16.8 10.3-26.6 7.5-7.3-2.2-11.4-5.8-19.6-17.4-16.1-22.8-22.4-36.2-29.9-64.3-2.4-9-4.1-16.7-3.6-17 2.3-2.1 30.7-9.3 44.7-11.4 6.3-.9 35.2.3 43 1.9zM325.1 225l62.1-31.1-.7 3.3c-1 4.7-2.1 6.4-5.8 9.1-1.7 1.3-28.8 16-60.1 32.7-51.8 27.7-57.1 30.2-59.6 29.3-5.3-2-114.5-60.6-116.9-62.7-2.5-2.2-5.1-7.4-5.1-10.1 0-1.1 18.7 7.8 62 29.5l61.9 31 62.2-31zm-194 131.4c1.1 3 .1 11.2-8.7 69.9-5.4 36.7-10.2 66.3-10.5 65.9-.4-.4-3-8-5.8-16.9l-5.1-16.2 11-57.8c6.1-31.8 11.4-58.5 11.6-59.3.5-1.4 4.6 6.4 7.5 14.4zm280.8 44.2 11.2 58.1-5.2 16.6c-2.9 9.2-5.6 16.4-6 15.9-.3-.4-5-30.4-10.4-66.7l-9.8-66 3.9-8.7c2.2-4.8 4.2-8.4 4.5-8 .4.4 5.7 26.8 11.8 58.8z" />
<path d="M256 23.9c-1.9.4-5.5 1.8-7.9 3.2-5.1 2.8-130.3 133.3-135.8 141.5-5.4 8.1-7.5 14.7-8.1 25.5-.5 11.3.7 17.6 5.2 26.9 3.7 7.8 13.8 18.4 21.1 22.1 2.8 1.4 20.4 7.5 39.3 13.4 18.8 6 33.7 11.2 33 11.6-.7.3-24.2 9.3-52.3 19.9-32.8 12.4-52.9 20.5-56.3 22.7-6 4-12 10.7-15.6 17.4-1.5 2.7-9.7 31.1-20.6 71.5C41.3 461.3 39.9 467 40.3 473c.9 12.3 7.2 21.7 18.5 27.2l6.7 3.3H262c190.8 0 196.7-.1 202-1.9 7.5-2.6 15.9-11 18.8-18.9 4.1-10.8 3.9-11.8-15.3-81.5-9.6-35-18.7-66.6-20.2-70.1-3.4-8.3-13-18.6-21-22.8-3.2-1.7-27.9-11.5-55-21.9s-48.9-19.2-48.5-19.5c.4-.4 15.1-5.3 32.7-10.8 17.6-5.6 34.5-11.4 37.5-12.9 11.4-5.6 23-20.5 25.9-33.2 2.7-11.5.7-27.5-4.7-37.3-3.6-6.7-5.2-8.5-73.7-80.2-45.1-47.2-61.4-63.7-65.1-65.7-5.3-2.8-13.7-4.1-19.4-2.9m32.5 97.6c9.3 1.8 31.6 8.3 32.9 9.5 1.6 1.5-12.1 43.6-18.3 56.5-6 12.3-16.1 27.7-22.6 34.7-7.3 7.7-16.8 10.3-26.6 7.5-7.3-2.2-11.4-5.8-19.6-17.4-16.1-22.8-22.4-36.2-29.9-64.3-2.4-9-4.1-16.7-3.6-17 2.3-2.1 30.7-9.3 44.7-11.4 6.3-.9 35.2.3 43 1.9M325.1 225l62.1-31.1-.7 3.3c-1 4.7-2.1 6.4-5.8 9.1-1.7 1.3-28.8 16-60.1 32.7-51.8 27.7-57.1 30.2-59.6 29.3-5.3-2-114.5-60.6-116.9-62.7-2.5-2.2-5.1-7.4-5.1-10.1 0-1.1 18.7 7.8 62 29.5l61.9 31zm-194 131.4c1.1 3 .1 11.2-8.7 69.9-5.4 36.7-10.2 66.3-10.5 65.9-.4-.4-3-8-5.8-16.9l-5.1-16.2 11-57.8c6.1-31.8 11.4-58.5 11.6-59.3.5-1.4 4.6 6.4 7.5 14.4m280.8 44.2 11.2 58.1-5.2 16.6c-2.9 9.2-5.6 16.4-6 15.9-.3-.4-5-30.4-10.4-66.7l-9.8-66 3.9-8.7c2.2-4.8 4.2-8.4 4.5-8 .4.4 5.7 26.8 11.8 58.8" />
</svg>
);
};

View File

@@ -22,7 +22,7 @@ const Cross = ({
{title ? <title id={titleId}>{title}</title> : null}
<path
fill="currentColor"
d="M85.8 34.4c-5.3 1.9-9.2 5.3-30 26.3C35.9 80.8 33 84.8 33 93c0 2.5.9 6.4 1.9 8.6 1.2 2.7 27.7 32.1 74.5 82.7 39.9 43.3 72.6 79.1 72.6 79.7 0 .6-32.3 35.2-71.7 77-48.5 51.3-72.7 77.7-74.6 81.1-3.4 6.4-3.5 11.7-.3 18.4 3.3 6.8 42 45.5 48.6 48.4 6.4 2.9 12.7 2.7 18.8-.7 3.3-1.7 31.6-27.6 81.3-74.5 42-39.4 76.7-71.6 77.1-71.5.4.2 35.5 32.5 77.9 71.8 42.4 39.3 79.2 72.7 81.8 74.2 3.2 1.9 6 2.8 9.1 2.8 10.1 0 10.9-.6 34.9-24.3 14.2-14.1 23-23.7 24.2-26.2 2.4-5.1 2.4-12.8 0-18.1-1.2-2.6-27.1-30.8-74.5-81.2-40-42.5-72.6-77.6-72.4-78.1.2-.4 32.5-34.7 71.8-76.1 39.3-41.4 72.5-76.7 73.8-78.4 4.5-6.3 4.4-17.9-.1-24.2-5.1-7.2-43.3-46.7-46.9-48.5-2.1-1.1-5.8-2.2-8.2-2.5-9.6-1.4-5.3-5.2-158.3 138.2L262.2 183l-78.4-73.1c-49.6-46.5-79.8-73.9-82.3-75-4.7-2.2-10.5-2.3-15.7-.5z"
d="M85.8 34.4c-5.3 1.9-9.2 5.3-30 26.3C35.9 80.8 33 84.8 33 93c0 2.5.9 6.4 1.9 8.6 1.2 2.7 27.7 32.1 74.5 82.7 39.9 43.3 72.6 79.1 72.6 79.7s-32.3 35.2-71.7 77c-48.5 51.3-72.7 77.7-74.6 81.1-3.4 6.4-3.5 11.7-.3 18.4 3.3 6.8 42 45.5 48.6 48.4 6.4 2.9 12.7 2.7 18.8-.7 3.3-1.7 31.6-27.6 81.3-74.5 42-39.4 76.7-71.6 77.1-71.5.4.2 35.5 32.5 77.9 71.8s79.2 72.7 81.8 74.2c3.2 1.9 6 2.8 9.1 2.8 10.1 0 10.9-.6 34.9-24.3 14.2-14.1 23-23.7 24.2-26.2 2.4-5.1 2.4-12.8 0-18.1-1.2-2.6-27.1-30.8-74.5-81.2-40-42.5-72.6-77.6-72.4-78.1.2-.4 32.5-34.7 71.8-76.1s72.5-76.7 73.8-78.4c4.5-6.3 4.4-17.9-.1-24.2-5.1-7.2-43.3-46.7-46.9-48.5-2.1-1.1-5.8-2.2-8.2-2.5-9.6-1.4-5.3-5.2-158.3 138.2L262.2 183l-78.4-73.1c-49.6-46.5-79.8-73.9-82.3-75-4.7-2.2-10.5-2.3-15.7-.5"
/>
</svg>
);

View File

@@ -22,7 +22,7 @@ const Energy = ({
{title ? <title id={titleId}>{title}</title> : null}
<path
fill="currentColor"
d="M115 56.7c0 43.4-3.9 70.1-15.2 105.3-13.2 41.2-31 72.7-64.7 114.9-9.4 11.8-16.8 21.8-16.4 22.1.5.4 15.9 7.1 34.3 15 45.7 19.5 62.7 28.1 85.5 43.3 20.7 13.8 37.9 28 56 46.2 25.5 25.5 37.6 41.5 64.9 86.1l2.8 4.7 4.2-6.7c23.6-38.7 58.8-78.7 94.3-107.4 36.6-29.6 69.6-48.8 120.8-70.6 12.7-5.4 23.4-10.2 23.8-10.6.5-.4-6.1-9.5-14.6-20.1-18.3-23.1-25-32.4-34.6-48.3-22.9-38.1-38.1-82-44.6-128.6-1.1-7.4-1.8-22.4-2.2-41.8l-.6-30.3-2.6.5c-1.4.3-24.6 4.1-51.6 8.5-92 15-94.4 15-199.8-2.5-21.3-3.5-39-6.4-39.2-6.4-.3 0-.5 12-.5 26.7zm129 28.7c14.8 6.1 22.9 7.8 39.5 8.3 13.2.4 16.9.2 30.8-2.2 8.7-1.5 16-2.6 16.2-2.4.2.2-4 4-9.2 8.4-19.6 16.6-37.7 36.8-50.7 56.6-9.5 14.7-24.6 45.4-24.6 50.2 0 1 3.2 1.8 12.3 3 42.6 5.8 64 5.9 108 .6 9.3-1.1 17-1.9 17.2-1.7.2.2-7.6 9.3-17.2 20.3-28.6 32.6-40.9 48.8-55.3 72.5-10.5 17.4-14.4 26.9-26.6 64-6.3 19.5-13.9 42.7-16.8 51.5l-5.3 16-.9-28c-1.2-36.9-1-59 .5-70 2.3-17.3 7.5-35.6 15.1-53.8 4.5-10.5 3.9-11.7-6.9-14.6-22.9-6.2-71.6-4.5-114.5 3.9-8.3 1.6-15.1 2.8-15.3 2.6-.2-.1 3-4.1 7-8.7 31.2-35.8 55.4-78.7 69.6-123.3 2.1-6.6 6.4-22.4 9.6-34.9 4.8-18.9 6.1-22.8 7.4-22.3.9.2 5.4 2 10.1 4z"
d="M115 56.7c0 43.4-3.9 70.1-15.2 105.3-13.2 41.2-31 72.7-64.7 114.9-9.4 11.8-16.8 21.8-16.4 22.1.5.4 15.9 7.1 34.3 15 45.7 19.5 62.7 28.1 85.5 43.3 20.7 13.8 37.9 28 56 46.2 25.5 25.5 37.6 41.5 64.9 86.1l2.8 4.7 4.2-6.7c23.6-38.7 58.8-78.7 94.3-107.4 36.6-29.6 69.6-48.8 120.8-70.6 12.7-5.4 23.4-10.2 23.8-10.6.5-.4-6.1-9.5-14.6-20.1-18.3-23.1-25-32.4-34.6-48.3-22.9-38.1-38.1-82-44.6-128.6-1.1-7.4-1.8-22.4-2.2-41.8l-.6-30.3-2.6.5c-1.4.3-24.6 4.1-51.6 8.5-92 15-94.4 15-199.8-2.5-21.3-3.5-39-6.4-39.2-6.4-.3 0-.5 12-.5 26.7m129 28.7c14.8 6.1 22.9 7.8 39.5 8.3 13.2.4 16.9.2 30.8-2.2 8.7-1.5 16-2.6 16.2-2.4s-4 4-9.2 8.4c-19.6 16.6-37.7 36.8-50.7 56.6-9.5 14.7-24.6 45.4-24.6 50.2 0 1 3.2 1.8 12.3 3 42.6 5.8 64 5.9 108 .6 9.3-1.1 17-1.9 17.2-1.7s-7.6 9.3-17.2 20.3c-28.6 32.6-40.9 48.8-55.3 72.5-10.5 17.4-14.4 26.9-26.6 64-6.3 19.5-13.9 42.7-16.8 51.5l-5.3 16-.9-28c-1.2-36.9-1-59 .5-70 2.3-17.3 7.5-35.6 15.1-53.8 4.5-10.5 3.9-11.7-6.9-14.6-22.9-6.2-71.6-4.5-114.5 3.9-8.3 1.6-15.1 2.8-15.3 2.6-.2-.1 3-4.1 7-8.7 31.2-35.8 55.4-78.7 69.6-123.3 2.1-6.6 6.4-22.4 9.6-34.9 4.8-18.9 6.1-22.8 7.4-22.3.9.2 5.4 2 10.1 4"
/>
</svg>
);

View File

@@ -21,8 +21,8 @@ const Exit = ({
>
{title ? <title id={titleId}>{title}</title> : null}
<g fill="currentColor">
<path d="M149.3 6.5c-20.9 4.6-40.3 24.4-44.8 46-2.2 10.6-2.2 408.5 0 419 2.4 11.3 7.7 20.9 16.4 29.6 9 9 16.2 13.2 26.7 15.9 7.5 1.9 11.2 2 113.3 2 87.8 0 106.7-.3 112.4-1.5 20-4.2 38.2-21.9 44.4-43.1 1.5-5.2 1.7-12.9 2.1-68.7l.3-62.7h-30l-.3 60.7c-.3 59.8-.3 60.9-2.5 65.5-2.6 5.7-9.4 12.4-15.3 15.2-4.5 2.1-4.9 2.1-110.5 2.1h-106l-5.7-2.8c-3.2-1.6-7.5-4.8-9.7-7.3-7.7-8.8-7.1 9.5-6.9-215.9.3-199 .3-202.1 2.3-206 2.7-5.5 9.7-12.2 15.3-14.8l4.7-2.2h211l5.6 2.6c6.8 3.2 12.4 8.7 15.3 14.8 2 4.5 2.1 6.1 2.4 54.3l.3 49.8h30l-.3-51.8c-.4-45.1-.7-52.5-2.1-57.6-6.1-20.9-22.8-37.4-43.2-42.6-7.6-1.9-11-2-113.4-1.9-84.8 0-106.8.3-111.8 1.4z" />
<path d="M426 188.7c-.8.3-2.5 1.5-3.7 2.6-2.2 1.9-2.3 2.8-2.3 16.8 0 8.1-.3 15.4-.6 16.3-.6 1.4-9.5 1.6-91.3 1.6-56.9 0-91.9.4-94.2 1-1.9.6-4.6 2.2-6 3.6-2.3 2.5-2.4 3.2-2.7 19.1-.4 18 .2 21 4.7 24 2.4 1.7 8 1.8 95.6 2.1 72.2.2 93.1.5 93.7 1.5.4.6.8 7.8.8 15.9 0 8 .3 15.4.6 16.3 1.6 4.1 11.6 6.1 17 3.2 5.2-2.7 67.2-56.1 68.4-58.9.7-1.5 1-3.8.6-5.2-.7-2.9-65-57.5-69.9-59.3-3.4-1.2-8.2-1.5-10.7-.6z" />
<path d="M149.3 6.5c-20.9 4.6-40.3 24.4-44.8 46-2.2 10.6-2.2 408.5 0 419 2.4 11.3 7.7 20.9 16.4 29.6 9 9 16.2 13.2 26.7 15.9 7.5 1.9 11.2 2 113.3 2 87.8 0 106.7-.3 112.4-1.5 20-4.2 38.2-21.9 44.4-43.1 1.5-5.2 1.7-12.9 2.1-68.7l.3-62.7h-30l-.3 60.7c-.3 59.8-.3 60.9-2.5 65.5-2.6 5.7-9.4 12.4-15.3 15.2-4.5 2.1-4.9 2.1-110.5 2.1h-106l-5.7-2.8c-3.2-1.6-7.5-4.8-9.7-7.3-7.7-8.8-7.1 9.5-6.9-215.9.3-199 .3-202.1 2.3-206 2.7-5.5 9.7-12.2 15.3-14.8l4.7-2.2h211l5.6 2.6c6.8 3.2 12.4 8.7 15.3 14.8 2 4.5 2.1 6.1 2.4 54.3l.3 49.8h30l-.3-51.8c-.4-45.1-.7-52.5-2.1-57.6-6.1-20.9-22.8-37.4-43.2-42.6-7.6-1.9-11-2-113.4-1.9-84.8 0-106.8.3-111.8 1.4" />
<path d="M426 188.7c-.8.3-2.5 1.5-3.7 2.6-2.2 1.9-2.3 2.8-2.3 16.8 0 8.1-.3 15.4-.6 16.3-.6 1.4-9.5 1.6-91.3 1.6-56.9 0-91.9.4-94.2 1-1.9.6-4.6 2.2-6 3.6-2.3 2.5-2.4 3.2-2.7 19.1-.4 18 .2 21 4.7 24 2.4 1.7 8 1.8 95.6 2.1 72.2.2 93.1.5 93.7 1.5.4.6.8 7.8.8 15.9 0 8 .3 15.4.6 16.3 1.6 4.1 11.6 6.1 17 3.2 5.2-2.7 67.2-56.1 68.4-58.9.7-1.5 1-3.8.6-5.2-.7-2.9-65-57.5-69.9-59.3-3.4-1.2-8.2-1.5-10.7-.6" />
</g>
</svg>
);

View File

@@ -21,7 +21,7 @@ const Experience = ({
>
{title ? <title id={titleId}>{title}</title> : null}
<g fill="currentColor">
<path d="M24.2 73.7c14 18.5 27.2 42.3 30.4 55.3 2.8 11.1 1.5 23.8-6.1 58.5-15 69-16.8 93.2-7.9 111.3 8.7 17.8 45 48.1 121.5 101.4 23.5 16.4 84.8 56.8 86.2 56.8.4 0 .6-64.2.5-142.6l-.3-142.6-7-2.2c-25.3-8-38.8-24.2-41.1-49-.8-8.6 1.4-20.7 5.2-29.4 1.3-3 2.1-5.9 1.7-6.3-.5-.4-9-4.6-19-9.3L170.1 67h-151l5.1 6.7zM334.3 76c-10.1 4.9-18.3 9.1-18.3 9.3 0 .3 1.1 2.9 2.4 5.8 3.7 8.5 5.1 15.7 5 25.9-.1 16.1-4.7 27.6-15 37.7-6.9 6.8-18.7 13.3-28.1 15.4l-5.3 1.2v142.9c0 78.5.3 142.8.8 142.8.4 0 11.8-7.3 25.4-16.3C409.9 369.3 469 323.6 482.5 300.6c9.9-16.9 8.4-41.8-6.6-111.1-8.5-39-9.6-50.6-5.9-62.6 4.3-14.5 13.5-31.3 27-49.5 3.9-5.2 7-9.6 7-9.9 0-.3-34.1-.5-75.7-.4l-75.8.1-18.2 8.8z" />
<path d="M24.2 73.7c14 18.5 27.2 42.3 30.4 55.3 2.8 11.1 1.5 23.8-6.1 58.5-15 69-16.8 93.2-7.9 111.3 8.7 17.8 45 48.1 121.5 101.4 23.5 16.4 84.8 56.8 86.2 56.8.4 0 .6-64.2.5-142.6l-.3-142.6-7-2.2c-25.3-8-38.8-24.2-41.1-49-.8-8.6 1.4-20.7 5.2-29.4 1.3-3 2.1-5.9 1.7-6.3-.5-.4-9-4.6-19-9.3L170.1 67h-151zM334.3 76c-10.1 4.9-18.3 9.1-18.3 9.3 0 .3 1.1 2.9 2.4 5.8 3.7 8.5 5.1 15.7 5 25.9-.1 16.1-4.7 27.6-15 37.7-6.9 6.8-18.7 13.3-28.1 15.4l-5.3 1.2v142.9c0 78.5.3 142.8.8 142.8.4 0 11.8-7.3 25.4-16.3C409.9 369.3 469 323.6 482.5 300.6c9.9-16.9 8.4-41.8-6.6-111.1-8.5-39-9.6-50.6-5.9-62.6 4.3-14.5 13.5-31.3 27-49.5 3.9-5.2 7-9.6 7-9.9s-34.1-.5-75.7-.4l-75.8.1z" />
</g>
</svg>
);

View File

@@ -21,7 +21,7 @@ const FullscreenOff = ({
>
{title ? <title id={titleId}>{title}</title> : null}
<g fill="currentColor">
<path d="M29.3 20c-1.3.5-3.2 2.4-4.3 4.2-2 3.2-2 5-2 85.6V192l3.4 3.7c3.2 3.5 3.6 3.7 10 3.7 6.2 0 6.9-.3 9.9-3.2l3.2-3.2.2-69.8c.2-52.4.6-70.3 1.5-72 2.8-5.3 1.4-5.2 75.9-5.2h69.1l3.4-3.4c3.2-3.2 3.4-3.8 3.4-10.4 0-6.8-.1-7.1-3.5-10.1l-3.6-3.1-82.2.1c-46.4 0-83.2.4-84.4.9zM323.7 22.1c-5.5 4.2-5.8 16-.6 21.1l2.7 2.8h67.9c43.4 0 69.1.4 71.5 1 2 .6 4.6 2.2 5.8 3.7 2 2.5 2 3.6 2 71.5 0 75.9-.2 73.1 6.2 76.4 4.9 2.5 14.1 1.5 17.6-1.9l2.7-2.7.3-83.5.2-83.4-3.1-3.5-3.1-3.6H410c-82.9 0-83.8 0-86.3 2.1zM26.5 320.9c-1.1.5-2.9 1.9-4 3.1-2 2.2-2 3.8-2.3 85.6l-.2 83.3 3.1 3.5 3.1 3.6H110c82.9 0 83.8 0 86.3-2.1 5.5-4.2 5.8-16 .6-21.1l-2.7-2.8h-67.9c-43.4 0-69.1-.4-71.5-1-2-.6-4.6-2.2-5.8-3.7-2-2.5-2-3.6-2-71.5 0-75.6.2-73.1-6-76.3-3.1-1.6-11.2-1.9-14.5-.6zM477.2 323.4l-3.7 3.4-.5 71.1c-.6 79.2 0 73.4-7.6 75.1-2.1.5-34.3 1-71.5 1h-67.7l-3.1 3.5c-2.7 3.1-3.1 4.3-3.1 9.5s.4 6.4 3.1 9.5l3.1 3.5h168l2.9-2.9 2.9-2.9V326.8l-3.4-3.4c-3.1-3.1-3.9-3.4-9.5-3.4s-6.5.3-9.9 3.4z" />
<path d="M29.3 20c-1.3.5-3.2 2.4-4.3 4.2-2 3.2-2 5-2 85.6V192l3.4 3.7c3.2 3.5 3.6 3.7 10 3.7 6.2 0 6.9-.3 9.9-3.2l3.2-3.2.2-69.8c.2-52.4.6-70.3 1.5-72 2.8-5.3 1.4-5.2 75.9-5.2h69.1l3.4-3.4c3.2-3.2 3.4-3.8 3.4-10.4 0-6.8-.1-7.1-3.5-10.1l-3.6-3.1-82.2.1c-46.4 0-83.2.4-84.4.9M323.7 22.1c-5.5 4.2-5.8 16-.6 21.1l2.7 2.8h67.9c43.4 0 69.1.4 71.5 1 2 .6 4.6 2.2 5.8 3.7 2 2.5 2 3.6 2 71.5 0 75.9-.2 73.1 6.2 76.4 4.9 2.5 14.1 1.5 17.6-1.9l2.7-2.7.3-83.5.2-83.4-3.1-3.5-3.1-3.6H410c-82.9 0-83.8 0-86.3 2.1M26.5 320.9c-1.1.5-2.9 1.9-4 3.1-2 2.2-2 3.8-2.3 85.6l-.2 83.3 3.1 3.5 3.1 3.6H110c82.9 0 83.8 0 86.3-2.1 5.5-4.2 5.8-16 .6-21.1l-2.7-2.8h-67.9c-43.4 0-69.1-.4-71.5-1-2-.6-4.6-2.2-5.8-3.7-2-2.5-2-3.6-2-71.5 0-75.6.2-73.1-6-76.3-3.1-1.6-11.2-1.9-14.5-.6M477.2 323.4l-3.7 3.4-.5 71.1c-.6 79.2 0 73.4-7.6 75.1-2.1.5-34.3 1-71.5 1h-67.7l-3.1 3.5c-2.7 3.1-3.1 4.3-3.1 9.5s.4 6.4 3.1 9.5l3.1 3.5h168l2.9-2.9 2.9-2.9V326.8l-3.4-3.4c-3.1-3.1-3.9-3.4-9.5-3.4s-6.5.3-9.9 3.4" />
</g>
</svg>
);

View File

@@ -21,7 +21,7 @@ const FullscreenOn = ({
>
{title ? <title id={titleId}>{title}</title> : null}
<g fill="currentColor">
<path d="M185.3 20c-1.8.4-4 1.4-4.9 2.1-4.3 3.6-4.4 4.5-4.4 76.3v68.5l-2.4 2.8-2.4 2.8-71.2.5-71.2.5-2.9 3.3c-2.6 2.9-2.9 4-2.9 9.7 0 5.7.3 6.8 2.9 9.7l2.9 3.3h168.4l2.9-3.3 2.9-3.2v-83.3c0-89.3.2-86-4.8-88.6-2.7-1.4-9.4-2-12.9-1.1zM328 20c-1.9.5-4.5 2-5.7 3.5l-2.3 2.6v167.1l3.4 3.4 3.4 3.4 83.7-.2 83.7-.3 3-3.4c2.8-3.2 3-3.7 2.6-10.2-.3-5.9-.8-7.3-3.1-9.7l-2.7-2.7-70.9-.5-70.9-.5-2.6-2.4-2.5-2.4-.3-70.1c-.3-64.9-.4-70.4-2-72.9-1-1.4-2.6-3-3.5-3.5-2.9-1.5-9.5-2.1-13.3-1.2zM26.4 321c-1.2.4-3.1 2.1-4.4 3.7-1.9 2.4-2.1 3.7-1.8 9.6.3 5.7.8 7.1 3.1 9.5l2.7 2.7 70.9.5 70.9.5 2.6 2.4 2.6 2.4v67.6c0 37.2.5 69.4 1 71.5.5 2.1 1.7 4.8 2.8 5.8 4.6 4.7 16.7 4.2 21-.7l2.2-2.6V326.8l-3.4-3.4-3.4-3.4-82.3.1c-45.3 0-83.4.4-84.5.9zM326.3 321c-1.3.5-3.2 2.4-4.3 4.2-2 3.2-2 5-2 85.6V493l3.4 3.7c3.2 3.5 3.6 3.7 10 3.7 6.2 0 6.9-.3 9.9-3.2l3.2-3.2.2-69.8c.2-52.4.6-70.3 1.5-72 2.8-5.3 1.4-5.2 75.9-5.2h69.1l3.4-3.4c3.2-3.2 3.4-3.8 3.4-10.4 0-6.8-.1-7.1-3.5-10.1l-3.6-3.1-82.2.1c-46.4 0-83.2.4-84.4.9z" />
<path d="M185.3 20c-1.8.4-4 1.4-4.9 2.1-4.3 3.6-4.4 4.5-4.4 76.3v68.5l-2.4 2.8-2.4 2.8-71.2.5-71.2.5-2.9 3.3c-2.6 2.9-2.9 4-2.9 9.7s.3 6.8 2.9 9.7l2.9 3.3h168.4l2.9-3.3 2.9-3.2v-83.3c0-89.3.2-86-4.8-88.6-2.7-1.4-9.4-2-12.9-1.1M328 20c-1.9.5-4.5 2-5.7 3.5l-2.3 2.6v167.1l3.4 3.4 3.4 3.4 83.7-.2 83.7-.3 3-3.4c2.8-3.2 3-3.7 2.6-10.2-.3-5.9-.8-7.3-3.1-9.7l-2.7-2.7-70.9-.5-70.9-.5-2.6-2.4-2.5-2.4-.3-70.1c-.3-64.9-.4-70.4-2-72.9-1-1.4-2.6-3-3.5-3.5-2.9-1.5-9.5-2.1-13.3-1.2M26.4 321c-1.2.4-3.1 2.1-4.4 3.7-1.9 2.4-2.1 3.7-1.8 9.6.3 5.7.8 7.1 3.1 9.5l2.7 2.7 70.9.5 70.9.5 2.6 2.4 2.6 2.4v67.6c0 37.2.5 69.4 1 71.5s1.7 4.8 2.8 5.8c4.6 4.7 16.7 4.2 21-.7l2.2-2.6V326.8l-3.4-3.4-3.4-3.4-82.3.1c-45.3 0-83.4.4-84.5.9M326.3 321c-1.3.5-3.2 2.4-4.3 4.2-2 3.2-2 5-2 85.6V493l3.4 3.7c3.2 3.5 3.6 3.7 10 3.7 6.2 0 6.9-.3 9.9-3.2l3.2-3.2.2-69.8c.2-52.4.6-70.3 1.5-72 2.8-5.3 1.4-5.2 75.9-5.2h69.1l3.4-3.4c3.2-3.2 3.4-3.8 3.4-10.4 0-6.8-.1-7.1-3.5-10.1l-3.6-3.1-82.2.1c-46.4 0-83.2.4-84.4.9" />
</g>
</svg>
);

View File

@@ -15,15 +15,17 @@ const Info = ({
xmlns="http://www.w3.org/2000/svg"
width={props.size || 16}
height={props.size || 16}
viewBox="0 0 524 524"
fill="currentColor"
viewBox="0 0 52 52"
aria-labelledby={titleId}
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<g fill="currentColor">
<path d="M236.7 33.5c-28.8 3.6-51.4 10.2-75.4 22C92.7 89.2 46.2 152.7 34.4 229c-2.5 16-2.5 50 0 66C46 370 91.6 433.3 158.5 467.2c32.9 16.7 65.2 24.3 103.5 24.3 22.1 0 34.2-1.4 54.5-6.2 31.1-7.3 65.4-24.3 90.8-45.2 9.1-7.4 27-25.5 34.3-34.6 25-31.3 41.8-70.1 48-111 2.5-16.4 2.5-48.3 0-65-11.4-76.2-58.6-140.8-126.9-174-23.2-11.2-42.1-17.1-67.7-21-14.5-2.2-44.7-2.8-58.3-1zM294 78.9c74.6 13.2 133.6 70.2 149.6 144.4 8.6 40.3 3.5 82-14.6 119.3C390.5 422 302.6 463 216.5 441.9c-88.7-21.8-148.8-107.6-139.4-199 7.3-71.5 56.7-133.8 124.4-156.8 12.2-4.1 27.1-7.4 40.5-9.1 11.8-1.4 38.8-.4 52 1.9z" />
<path d="M246.5 112c-20.8 2-36.2 8.6-48.5 21.1-11.5 11.6-19.3 26.4-27.5 52-3.4 10.6-3.6 11.9-2.4 14.4 2 4.1 5.8 6.5 11.4 7.1 7.4.9 9.2-1 17.8-19 14.9-30.8 25.7-41.9 46-47.3 8.4-2.3 29.8-2.2 38.6.1 21.2 5.5 34.6 19.5 35.9 37.6.8 11.1-2.3 16.4-20.5 35.2-26 26.8-38 45.6-44.2 69.2-3 11.3-4.6 31.6-3.6 46 .7 11.3.9 12.1 3.5 14.8 2.6 2.5 3.5 2.8 9.5 2.8 5.7 0 6.9-.3 9-2.5 1.4-1.3 2.5-3.2 2.6-4.2.1-1 .2-9.9.3-19.8.2-20.3 1.6-28.1 7.1-40.2 7.6-16.6 23.7-36 42.5-51.3 22.4-18.2 28.1-27.9 28-47.8-.1-19.8-6.1-35.4-17.9-46.5-8.6-8.1-14.8-11.8-26.6-15.7-16.5-5.4-41.3-7.8-61-6zM252.4 372.9c-4.2 1.8-5.4 5-5.4 13.9 0 4.6.5 9.2 1 10.3 1.8 3.3 6.4 4.9 14 4.9 12.6 0 15.5-3.3 14.9-16.9-.6-11.3-1.9-12.5-13.7-12.8-4.8-.2-9.7.1-10.8.6z" />
</g>
<path
fillRule="evenodd"
d="M26 48c12.15 0 22-9.85 22-22S38.15 4 26 4 4 13.85 4 26s9.85 22 22 22m0 4c14.36 0 26-11.64 26-26S40.36 0 26 0 0 11.64 0 26s11.64 26 26 26m-4.191-36.87-.264.172c-2.513 1.644-2.671 5.27-.31 7.125a2 2 0 1 1-2.47 3.146c-4.514-3.547-4.213-10.477.591-13.619l.264-.172a11.66 11.66 0 0 1 12.76 0l.77.503c4.556 2.98 4.841 9.551.561 12.914-.422.332-.877.62-1.357.86l-.54.27A6.9 6.9 0 0 0 28 32.5a2 2 0 1 1-4 0 10.9 10.9 0 0 1 6.025-9.748l.54-.27q.36-.18.675-.428c2.128-1.672 1.986-4.94-.28-6.421l-.769-.503a7.66 7.66 0 0 0-8.382 0M26 42a3 3 0 1 0 0-6 3 3 0 0 0 0 6"
clipRule="evenodd"
/>
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const FivePlayers = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zM396 269v221H57V409.3l11.3-.6c18.4-1 32.5-6 42.3-15C125.7 380 138.1 334 138.1 292c0-23.9-3.5-47.1-10.7-71-9.5-31.4-25.9-44.2-58.8-45.7l-11.9-.6.6-11.6c1.1-18.8 4.8-33.4 12.7-49.2C83.9 86 109.2 64.3 139.7 54c17.7-5.9 15.3-5.8 141.1-5.9L396 48v221zM651.5 50.9c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.2 6.9 1.5 19.8 1.5 68.3v59.7l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6v353.4l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6v59.7c0 65.6-.2 69-6.1 86.4-13.7 41-49.7 71.9-92.9 79.7-6.1 1.1-29.8 1.4-123.5 1.4h-116l-.3-638.8-.2-638.8 118.7.4 118.8.3 9 2.3zM396 692v192H57V805.3l11.3-.6c18.4-1 32.5-6 42.3-15C125.7 776 138.1 730 138.1 688c0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.6-45.7l-11.8-.6V500h339v192zm0 417.5V1326H285.3c-63.3 0-115-.5-120.7-1-32.5-3.2-63-20.2-83-46.5-15-19.7-24.6-47.5-24.6-71.6v-6.6l11.3-.6c18.4-1 32.5-6 42.3-15 15.1-13.7 27.5-59.7 27.5-101.7 0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.6-45.7l-11.8-.6V893h339v216.5z" />
<path d="M195 236.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM574.1 340.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2zM574.1 928.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2zM195 632.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM195 1027.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 4-19-1.3-36.4-15.6-50.7-11.5-11.6-24.1-16.8-40.2-16.6-4 0-9.7.7-12.7 1.5z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7M396 269v221H57v-80.7l11.3-.6q27.6-1.5 42.3-15C125.7 380 138.1 334 138.1 292c0-23.9-3.5-47.1-10.7-71-9.5-31.4-25.9-44.2-58.8-45.7l-11.9-.6.6-11.6c1.1-18.8 4.8-33.4 12.7-49.2C83.9 86 109.2 64.3 139.7 54c17.7-5.9 15.3-5.8 141.1-5.9L396 48zM651.5 50.9c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.2 6.9 1.5 19.8 1.5 68.3v59.7l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6v353.4l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6v59.7c0 65.6-.2 69-6.1 86.4-13.7 41-49.7 71.9-92.9 79.7-6.1 1.1-29.8 1.4-123.5 1.4h-116l-.3-638.8-.2-638.8 118.7.4 118.8.3zM396 692v192H57v-78.7l11.3-.6q27.6-1.5 42.3-15C125.7 776 138.1 730 138.1 688c0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.6-45.7l-11.8-.6V500h339zm0 417.5V1326H285.3c-63.3 0-115-.5-120.7-1-32.5-3.2-63-20.2-83-46.5-15-19.7-24.6-47.5-24.6-71.6v-6.6l11.3-.6q27.6-1.5 42.3-15c15.1-13.7 27.5-59.7 27.5-101.7 0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.6-45.7l-11.8-.6V893h339z" />
<path d="M195 236.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M574.1 340.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2M574.1 928.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2M195 632.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M195 1027.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 4-19-1.3-36.4-15.6-50.7-11.5-11.6-24.1-16.8-40.2-16.6-4 0-9.7.7-12.7 1.5" />
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const FivePlayersSide = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zM396 285.5V523H57V418.3l9.8-.6c17.2-1.2 31.4-6.3 40.8-15 8.8-8 16-24.7 21.9-51.2 7.6-33.9 7.6-68.2-.1-102-5.7-25.6-11.3-39-19.9-48.3-9.3-10.1-23.7-15.9-42.5-17.1l-9.5-.6.1-15c.1-21.7 3.3-36.1 12.1-54 14.1-28.4 39.2-50.1 70-60.5 17.7-5.9 15.3-5.8 141.1-5.9L396 48v237.5zM651.5 50.9c36 9.4 63.5 30.9 79.4 62 9.1 17.9 13.1 35 13.1 56.6v13.2l-9.4.7c-18 1.2-33.9 7.2-42.3 15.9-5.5 5.6-10.5 15-14.7 27.7-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.1 10.1 22.9 15.1 41.4 16.1l10.2.6V523H405V47.9l118.8.4 118.7.3 9 2.3zM395.8 767.2l.2 234.8H57V872.3l11.8-.6c18.9-1 32.8-5.9 42.8-15C126.7 843 139.1 797 139.1 755c0-23.9-3.5-47.1-10.7-71-9.5-31.5-25.9-44.2-59.1-45.7l-12.3-.6V532l169.3.2 169.2.3.3 234.7zM744 584.4v52.3l-9.4.7c-18 1.2-33.9 7.2-42.3 15.9-5.5 5.6-10.5 15-14.7 27.7-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.1 10.1 22.9 15.1 41.4 16.1l10.2.6V1002H405V532h339v52.4zm0 530c0 113.4.1 111.6-6.1 130-13.4 40-47.4 70-89.9 79.2-6.3 1.4-17 1.7-68.6 2.1l-61.1.4-.6-10.3c-.7-11.8-4-24.6-8.3-32.3-8.3-14.9-24-23.3-57.9-30.9-23.8-5.4-54.3-7.2-76-4.6-21.2 2.5-48 9.3-60.9 15.5-19.1 9-28.7 25.4-30.4 52l-.7 10-53 .3c-57.6.3-70.7-.4-85.4-4.3-24.3-6.6-47.8-22.5-63.5-43-7.7-10.1-16.6-27.7-19.6-38.6-4.9-18.3-5-19.6-5-127.7V1011h687v103.4z" />
<path d="M192 245.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM578.1 247.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2zM196 699.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM578.1 701.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2zM388.3 1121.5c-10.8 2.3-19 7-27.6 15.6-11.4 11.4-16.7 23.9-16.7 39.7 0 23.6 15.9 45.3 39 53.3 9.2 3.1 23.7 3.2 33.7.1 12.7-3.9 24.1-12.9 31.6-24.9 7.9-12.6 10-31 5.2-46.1-8.6-27.2-37.2-43.8-65.2-37.7z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7M396 285.5V523H57V418.3l9.8-.6c17.2-1.2 31.4-6.3 40.8-15 8.8-8 16-24.7 21.9-51.2 7.6-33.9 7.6-68.2-.1-102-5.7-25.6-11.3-39-19.9-48.3-9.3-10.1-23.7-15.9-42.5-17.1l-9.5-.6.1-15c.1-21.7 3.3-36.1 12.1-54 14.1-28.4 39.2-50.1 70-60.5 17.7-5.9 15.3-5.8 141.1-5.9L396 48zM651.5 50.9c36 9.4 63.5 30.9 79.4 62 9.1 17.9 13.1 35 13.1 56.6v13.2l-9.4.7c-18 1.2-33.9 7.2-42.3 15.9-5.5 5.6-10.5 15-14.7 27.7-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.1 10.1 22.9 15.1 41.4 16.1l10.2.6V523H405V47.9l118.8.4 118.7.3zM395.8 767.2l.2 234.8H57V872.3l11.8-.6c18.9-1 32.8-5.9 42.8-15C126.7 843 139.1 797 139.1 755c0-23.9-3.5-47.1-10.7-71-9.5-31.5-25.9-44.2-59.1-45.7l-12.3-.6V532l169.3.2 169.2.3zM744 584.4v52.3l-9.4.7c-18 1.2-33.9 7.2-42.3 15.9-5.5 5.6-10.5 15-14.7 27.7-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.1 10.1 22.9 15.1 41.4 16.1l10.2.6V1002H405V532h339zm0 530c0 113.4.1 111.6-6.1 130-13.4 40-47.4 70-89.9 79.2-6.3 1.4-17 1.7-68.6 2.1l-61.1.4-.6-10.3c-.7-11.8-4-24.6-8.3-32.3-8.3-14.9-24-23.3-57.9-30.9-23.8-5.4-54.3-7.2-76-4.6-21.2 2.5-48 9.3-60.9 15.5-19.1 9-28.7 25.4-30.4 52l-.7 10-53 .3c-57.6.3-70.7-.4-85.4-4.3-24.3-6.6-47.8-22.5-63.5-43-7.7-10.1-16.6-27.7-19.6-38.6-4.9-18.3-5-19.6-5-127.7V1011h687z" />
<path d="M192 245.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M578.1 247.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2M196 699.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M578.1 701.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2M388.3 1121.5c-10.8 2.3-19 7-27.6 15.6-11.4 11.4-16.7 23.9-16.7 39.7 0 23.6 15.9 45.3 39 53.3 9.2 3.1 23.7 3.2 33.7.1 12.7-3.9 24.1-12.9 31.6-24.9 7.9-12.6 10-31 5.2-46.1-8.6-27.2-37.2-43.8-65.2-37.7" />
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const FourPlayers = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zM396 365v317H57V511.3l11.3-.6c18.4-1 32.5-6 42.3-15C125.7 482 138.1 436 138.1 394c0-23.9-3.5-47.1-10.7-71-9.4-31.4-25.9-44.2-58.7-45.7l-11.8-.6.4-62.6c.3-59.6.4-63 2.5-71.6 2.8-11.9 5.1-18.4 10.2-28.6C83.9 86 109.2 64.3 139.7 54c17.7-5.9 15.3-5.8 141.1-5.9L396 48v317zM651.5 50.9c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.2 6.9 1.5 19.8 1.5 68.3v59.7l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6V682H405V47.9l118.8.4 118.7.3 9 2.3zM396 1009v317H285.3c-63.3 0-115-.5-120.7-1-32.5-3.2-63-20.2-83-46.5-7.7-10.1-16.6-27.7-19.6-38.6-4.6-17.2-5-22.8-5-83.5v-57.1l11.3-.6c18.4-1 32.5-6 42.3-15 15.1-13.7 27.5-59.7 27.5-101.7 0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.6-45.7l-11.8-.6V692h339v317zm348-231.2v85.9l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6v59.7c0 65.6-.2 69-6.1 86.4-13.7 41-49.7 71.9-92.9 79.7-6.1 1.1-29.8 1.4-123.5 1.4h-116l-.3-316.8L405 692h339v85.8z" />
<path d="M195 338.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM574.1 340.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2zM195 926.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM574.1 928.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7M396 365v317H57V511.3l11.3-.6q27.6-1.5 42.3-15C125.7 482 138.1 436 138.1 394c0-23.9-3.5-47.1-10.7-71-9.4-31.4-25.9-44.2-58.7-45.7l-11.8-.6.4-62.6c.3-59.6.4-63 2.5-71.6 2.8-11.9 5.1-18.4 10.2-28.6C83.9 86 109.2 64.3 139.7 54c17.7-5.9 15.3-5.8 141.1-5.9L396 48zM651.5 50.9c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.2 6.9 1.5 19.8 1.5 68.3v59.7l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6V682H405V47.9l118.8.4 118.7.3zM396 1009v317H285.3c-63.3 0-115-.5-120.7-1-32.5-3.2-63-20.2-83-46.5-7.7-10.1-16.6-27.7-19.6-38.6-4.6-17.2-5-22.8-5-83.5v-57.1l11.3-.6q27.6-1.5 42.3-15c15.1-13.7 27.5-59.7 27.5-101.7 0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.6-45.7l-11.8-.6V692h339zm348-231.2v85.9l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6v59.7c0 65.6-.2 69-6.1 86.4-13.7 41-49.7 71.9-92.9 79.7-6.1 1.1-29.8 1.4-123.5 1.4h-116l-.3-316.8L405 692h339z" />
<path d="M195 338.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M574.1 340.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2M195 926.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M574.1 928.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2" />
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const FourPlayersSide = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zm124 41.2c.1 21 5.7 36.8 16.7 47.4 14.3 13.6 60.7 25.4 100.3 25.4 23.7 0 42.4-2.7 66.7-9.7 23.4-6.7 35.7-15 42.3-28.8 5-10.6 6.6-17.6 7.2-32.9l.6-13.8 62.1.3c61.6.3 62.2.3 71.6 2.7 48.7 12.2 83.1 48.6 91.5 96.8 1.3 7.3 1.5 26.3 1.5 124.9V389l-343.2-.2-343.3-.3V271c0-109.1.1-118.1 1.8-126 9.2-43.6 38.7-77 80.4-91 16.6-5.5 20.3-5.8 84.8-5.9l59-.1v12.3zM396 687v289H57V805.3l12.8-.6c19.8-.9 33.6-5.6 43.8-15C128.7 776 141.1 730 141.1 688c0-23.9-3.5-47.1-10.7-71-9.6-31.9-26-44.4-60.1-45.7l-13.3-.6V398h339v289zm348-202.8v86.3h-12.3c-14.9.1-24.8 2.2-35.5 7.5-13.1 6.6-19.9 15.8-26.6 36-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 11.1 11 23.1 15.3 45.4 16.1l14.2.6V976H405V398h339v86.2zm0 617.2c0 127.7.1 124.4-6.1 143-13.4 40-47.4 70-89.9 79.2-6.3 1.4-17 1.7-68.6 2.1l-61.1.4-.7-8.6c-.8-10.3-4.3-23-8.2-30-8.3-14.9-24-23.3-57.9-30.9-23.8-5.4-54.3-7.2-76-4.6-21.2 2.5-48 9.3-60.9 15.5-18.5 8.7-28.1 24.5-30.3 49.6l-.8 8.4-53 .3c-57.6.3-70.7-.4-85.4-4.3-24.3-6.6-47.8-22.5-63.5-43-7.7-10.1-16.6-27.7-19.6-38.6-5-18.4-5-18.6-5-140.7V985h687v116.4z" />
<path d="M391.8 148c-16.5 3-30 12.2-39.1 26.7-7.9 12.6-10 31-5.2 46.1 4.5 14.4 15.5 26.9 29.1 33.4 22.1 10.4 46.1 6.2 63.5-11.1 11.5-11.5 16.9-24.2 16.9-39.9 0-23.4-16.1-45.5-38.6-53.1-7.1-2.3-19.8-3.4-26.6-2.1zM198 632.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM570.1 634.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2zM388.3 1125.5c-10.8 2.3-19 7-27.6 15.6-11.4 11.4-16.7 23.9-16.7 39.7 0 23.6 15.9 45.3 39 53.3 9.2 3.1 23.7 3.2 33.7.1 12.7-3.9 24.1-12.9 31.6-24.9 7.9-12.6 10-31 5.2-46.1-8.6-27.2-37.2-43.8-65.2-37.7z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7m124 41.2c.1 21 5.7 36.8 16.7 47.4 14.3 13.6 60.7 25.4 100.3 25.4 23.7 0 42.4-2.7 66.7-9.7 23.4-6.7 35.7-15 42.3-28.8 5-10.6 6.6-17.6 7.2-32.9l.6-13.8 62.1.3c61.6.3 62.2.3 71.6 2.7 48.7 12.2 83.1 48.6 91.5 96.8 1.3 7.3 1.5 26.3 1.5 124.9V389l-343.2-.2-343.3-.3V271c0-109.1.1-118.1 1.8-126 9.2-43.6 38.7-77 80.4-91 16.6-5.5 20.3-5.8 84.8-5.9l59-.1zM396 687v289H57V805.3l12.8-.6c19.8-.9 33.6-5.6 43.8-15C128.7 776 141.1 730 141.1 688c0-23.9-3.5-47.1-10.7-71-9.6-31.9-26-44.4-60.1-45.7l-13.3-.6V398h339zm348-202.8v86.3h-12.3c-14.9.1-24.8 2.2-35.5 7.5-13.1 6.6-19.9 15.8-26.6 36-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 11.1 11 23.1 15.3 45.4 16.1l14.2.6V976H405V398h339zm0 617.2c0 127.7.1 124.4-6.1 143-13.4 40-47.4 70-89.9 79.2-6.3 1.4-17 1.7-68.6 2.1l-61.1.4-.7-8.6c-.8-10.3-4.3-23-8.2-30-8.3-14.9-24-23.3-57.9-30.9-23.8-5.4-54.3-7.2-76-4.6-21.2 2.5-48 9.3-60.9 15.5-18.5 8.7-28.1 24.5-30.3 49.6l-.8 8.4-53 .3c-57.6.3-70.7-.4-85.4-4.3-24.3-6.6-47.8-22.5-63.5-43-7.7-10.1-16.6-27.7-19.6-38.6-5-18.4-5-18.6-5-140.7V985h687z" />
<path d="M391.8 148c-16.5 3-30 12.2-39.1 26.7-7.9 12.6-10 31-5.2 46.1 4.5 14.4 15.5 26.9 29.1 33.4 22.1 10.4 46.1 6.2 63.5-11.1 11.5-11.5 16.9-24.2 16.9-39.9 0-23.4-16.1-45.5-38.6-53.1-7.1-2.3-19.8-3.4-26.6-2.1M198 632.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M570.1 634.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2M388.3 1125.5c-10.8 2.3-19 7-27.6 15.6-11.4 11.4-16.7 23.9-16.7 39.7 0 23.6 15.9 45.3 39 53.3 9.2 3.1 23.7 3.2 33.7.1 12.7-3.9 24.1-12.9 31.6-24.9 7.9-12.6 10-31 5.2-46.1-8.6-27.2-37.2-43.8-65.2-37.7" />
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const OnePlayerLandscape = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zm492 31.8c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.3 7.5 1.5 73.4 1.5 539.3 0 474.6-.2 531.7-1.5 539.6-8.5 48.4-45 85.9-94.5 97.1-6.9 1.6-26.1 1.7-239 2-154.7.3-235.3 0-243-.7-20.8-1.8-38.3-8-55.8-19.7-28.1-18.7-46.6-48.2-51.8-82.8-1.1-7.4-1.4-45.9-1.4-213.6V804.3l9.8-.6c17.2-1.2 31.4-6.3 40.8-15 8.8-8 16-24.7 21.9-51.2 7.6-33.9 7.6-68.2-.1-102-5.7-25.6-11.3-39-19.9-48.3-9.3-10.1-23.7-15.9-42.5-17.1l-9.5-.6v-208c0-196.2.1-208.5 1.8-216.5 9.2-43.6 38.7-77 80.4-91 18.5-6.2 3.5-5.8 264.3-5.6l238.5.1 9 2.4z" />
<path d="M192 631.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7m492 31.8c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.3 7.5 1.5 73.4 1.5 539.3 0 474.6-.2 531.7-1.5 539.6-8.5 48.4-45 85.9-94.5 97.1-6.9 1.6-26.1 1.7-239 2-154.7.3-235.3 0-243-.7-20.8-1.8-38.3-8-55.8-19.7-28.1-18.7-46.6-48.2-51.8-82.8-1.1-7.4-1.4-45.9-1.4-213.6V804.3l9.8-.6c17.2-1.2 31.4-6.3 40.8-15 8.8-8 16-24.7 21.9-51.2 7.6-33.9 7.6-68.2-.1-102-5.7-25.6-11.3-39-19.9-48.3-9.3-10.1-23.7-15.9-42.5-17.1l-9.5-.6v-208c0-196.2.1-208.5 1.8-216.5 9.2-43.6 38.7-77 80.4-91 18.5-6.2 3.5-5.8 264.3-5.6l238.5.1z" />
<path d="M192 631.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5" />
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const OnePlayerPortrait = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zm492 31.8c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.3 7.5 1.5 73.4 1.5 539.3 0 474.6-.2 531.7-1.5 539.6-8.5 48.4-45.4 86.3-94.5 97-6.3 1.4-17 1.7-68.6 2.1l-61.1.4-.7-9c-.8-10.6-4.3-23.4-8.2-30.6-8.3-14.9-24-23.3-57.9-30.9-23.8-5.4-54.3-7.2-76-4.6-21.2 2.5-48 9.3-60.9 15.5-18.6 8.8-28.2 24.8-30.4 50.2l-.7 8.8-53 .3c-30.9.2-57.8-.2-64.5-.8-56.5-5-101.1-48.5-108-105.2-.8-6.8-1-151.9-.8-538.8l.3-529.5 2.2-9c2.9-12 5.2-18.5 10.3-28.6C83.9 86 109.2 64.3 139.7 54c18.5-6.2 3.5-5.8 264.3-5.6l238.5.1 9 2.4z" />
<path d="M388.3 1124.5c-10.8 2.3-19 7-27.6 15.6-11.4 11.4-16.7 23.9-16.7 39.7 0 23.6 15.9 45.3 39 53.3 9.2 3.1 23.7 3.2 33.7.1 12.7-3.9 24.1-12.9 31.6-24.9 7.9-12.6 10-31 5.2-46.1-8.6-27.2-37.2-43.8-65.2-37.7z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7m492 31.8c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.3 7.5 1.5 73.4 1.5 539.3 0 474.6-.2 531.7-1.5 539.6-8.5 48.4-45.4 86.3-94.5 97-6.3 1.4-17 1.7-68.6 2.1l-61.1.4-.7-9c-.8-10.6-4.3-23.4-8.2-30.6-8.3-14.9-24-23.3-57.9-30.9-23.8-5.4-54.3-7.2-76-4.6-21.2 2.5-48 9.3-60.9 15.5-18.6 8.8-28.2 24.8-30.4 50.2l-.7 8.8-53 .3c-30.9.2-57.8-.2-64.5-.8-56.5-5-101.1-48.5-108-105.2-.8-6.8-1-151.9-.8-538.8l.3-529.5 2.2-9c2.9-12 5.2-18.5 10.3-28.6C83.9 86 109.2 64.3 139.7 54c18.5-6.2 3.5-5.8 264.3-5.6l238.5.1z" />
<path d="M388.3 1124.5c-10.8 2.3-19 7-27.6 15.6-11.4 11.4-16.7 23.9-16.7 39.7 0 23.6 15.9 45.3 39 53.3 9.2 3.1 23.7 3.2 33.7.1 12.7-3.9 24.1-12.9 31.6-24.9 7.9-12.6 10-31 5.2-46.1-8.6-27.2-37.2-43.8-65.2-37.7" />
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const SixPlayers = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zM396 266.5V485l-169.2-.2-169.3-.3-.3-37.6-.2-37.6 11.2-.6c18.5-1 32.6-6 42.4-15C125.7 380 138.1 334 138.1 292c0-23.9-3.5-47.1-10.7-71-9.5-31.4-25.9-44.2-58.8-45.7l-11.9-.6.6-11.6c1.1-18.8 4.8-33.4 12.7-49.2C83.9 86 109.2 64.3 139.7 54c17.7-5.9 15.3-5.8 141.1-5.9L396 48v218.5zM651.5 50.9c36 9.4 63.5 30.9 79.4 62C739.3 129.4 744 148 744 165v8.7l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6V485l-169.2-.2-169.3-.3-.3-218.3-.2-218.3 118.7.4 118.8.3 9 2.3zM396 687v193H57V805.3l11.3-.6c18.4-1 32.5-6 42.3-15C125.7 776 138.1 730 138.1 688c0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.6-45.7l-11.8-.6V494h339v193zm348-155.2v37.9l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6V880H405V494h339v37.8zm-348 575.7V1326H285.3c-63.3 0-115-.5-120.7-1-32.5-3.2-63-20.2-83-46.5-15-19.7-24.6-47.5-24.6-71.6v-6.6l11.3-.6c18.4-1 32.5-6 42.3-15 15.1-13.7 27.5-59.7 27.5-101.7 0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.6-45.7l-11.8-.6V889h339v218.5zm348-180.7v37.9l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6v9.2c0 55.8-42.5 105.3-99 115.6-6.1 1.1-29.8 1.4-123.5 1.4h-116l-.3-217c-.1-119.4 0-217.6.3-218.3.3-.9 35.2-1.2 169.5-1.2h169v37.8z" />
<path d="M195 236.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM574.1 238.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2zM195 632.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM574.1 634.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2zM195 1027.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 4-19-1.3-36.4-15.6-50.7-11.5-11.6-24.1-16.8-40.2-16.6-4 0-9.7.7-12.7 1.5zM574.1 1029.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7M396 266.5V485l-169.2-.2-169.3-.3-.3-37.6-.2-37.6 11.2-.6c18.5-1 32.6-6 42.4-15C125.7 380 138.1 334 138.1 292c0-23.9-3.5-47.1-10.7-71-9.5-31.4-25.9-44.2-58.8-45.7l-11.9-.6.6-11.6c1.1-18.8 4.8-33.4 12.7-49.2C83.9 86 109.2 64.3 139.7 54c17.7-5.9 15.3-5.8 141.1-5.9L396 48zM651.5 50.9c36 9.4 63.5 30.9 79.4 62C739.3 129.4 744 148 744 165v8.7l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6V485l-169.2-.2-169.3-.3-.3-218.3-.2-218.3 118.7.4 118.8.3zM396 687v193H57v-74.7l11.3-.6q27.6-1.5 42.3-15C125.7 776 138.1 730 138.1 688c0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.6-45.7l-11.8-.6V494h339zm348-155.2v37.9l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6V880H405V494h339zm-348 575.7V1326H285.3c-63.3 0-115-.5-120.7-1-32.5-3.2-63-20.2-83-46.5-15-19.7-24.6-47.5-24.6-71.6v-6.6l11.3-.6q27.6-1.5 42.3-15c15.1-13.7 27.5-59.7 27.5-101.7 0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.6-45.7l-11.8-.6V889h339zm348-180.7v37.9l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6v9.2c0 55.8-42.5 105.3-99 115.6-6.1 1.1-29.8 1.4-123.5 1.4h-116l-.3-217c-.1-119.4 0-217.6.3-218.3.3-.9 35.2-1.2 169.5-1.2h169z" />
<path d="M195 236.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M574.1 238.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2M195 632.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M574.1 634.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2M195 1027.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 4-19-1.3-36.4-15.6-50.7-11.5-11.6-24.1-16.8-40.2-16.6-4 0-9.7.7-12.7 1.5M574.1 1029.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2" />
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const SixPlayersSide = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zm124 42.1c0 22 5.5 37.7 16.7 48.5 14.3 13.6 60.7 25.4 100.3 25.4 23.7 0 42.4-2.7 66.7-9.7 23.4-6.7 35.7-15 42.3-28.8 5.2-10.9 6.6-17.5 7.2-33.9l.6-14.8 62.1.3c61.6.3 62.2.3 71.6 2.7 48.7 12.2 83.1 48.6 91.5 96.8 1.2 7 1.5 20.5 1.5 73.9V287H56.9l.4-67.8c.3-64.8.4-68.1 2.5-76.7 2.8-11.9 5.1-18.4 10.2-28.6C83.9 86 109.2 64.3 139.7 54c16.6-5.5 20.3-5.8 84.8-5.9l59-.1v13.2zM396 489v193H57v-42.7l9.8-.6c17.2-1.2 31.4-6.3 40.8-15 8.8-8 16-24.7 21.9-51.2 7.6-33.9 7.6-68.2-.1-102-5.7-25.6-11.3-39-19.9-48.3-9.3-10.1-23.7-15.9-42.5-17.1l-9.5-.6-.3-54.3L57 296h339v193zm348-139.1v53.8l-9.4.7c-18 1.2-33.9 7.2-42.3 15.9-5.5 5.6-10.5 15-14.7 27.7-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.1 10.1 22.9 15.1 41.4 16.1l10.2.6V682H405V296h339v53.9zM395.8 880.2l-.3 188.3-169.2.3-169.3.2V985.3l11.8-.6c18.9-1 32.8-5.9 42.8-15C126.7 956 139.1 910 139.1 868c0-23.9-3.5-47.1-10.7-71-9.5-31.5-25.9-44.2-59.1-45.7l-12.3-.6V692h339l-.2 188.2zM744 720.9v28.8l-9.4.7c-18 1.2-33.9 7.2-42.3 15.9-5.5 5.6-10.5 15-14.7 27.7-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.1 10.1 22.9 15.1 41.4 16.1l10.2.6V1069H405V692h339v28.9zm0 427c0 76.6-.1 78.7-6.1 96.5-13.4 40-47.4 70-89.9 79.2-6.3 1.4-17 1.7-68.6 2.1l-61.1.4-.6-10.3c-.7-11.8-4-24.6-8.3-32.3-8.3-14.9-24-23.3-57.9-30.9-23.8-5.4-54.3-7.2-76-4.6-21.2 2.5-48 9.3-60.9 15.5-19.1 9-28.7 25.4-30.4 52l-.7 10-53 .3c-57.6.3-70.7-.4-85.4-4.3-24.3-6.6-47.8-22.5-63.5-43-7.7-10.1-16.6-27.7-19.6-38.6-4.7-17.6-5-22.1-5-94.2V1078h687v69.9z" />
<path d="M391.8 150c-16.5 3-30 12.2-39.1 26.7-7.9 12.6-10 31-5.2 46.1 4.5 14.4 15.5 26.9 29.1 33.4 22.1 10.4 46.1 6.2 63.5-11.1 11.5-11.5 16.9-24.2 16.9-39.9 0-23.4-16.1-45.5-38.6-53.1-7.1-2.3-19.8-3.4-26.6-2.1zM192 466.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM578.1 468.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2zM196 812.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM578.1 814.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2zM388.3 1121.5c-10.8 2.3-19 7-27.6 15.6-11.4 11.4-16.7 23.9-16.7 39.7 0 23.6 15.9 45.3 39 53.3 9.2 3.1 23.7 3.2 33.7.1 12.7-3.9 24.1-12.9 31.6-24.9 7.9-12.6 10-31 5.2-46.1-8.6-27.2-37.2-43.8-65.2-37.7z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7m124 42.1c0 22 5.5 37.7 16.7 48.5 14.3 13.6 60.7 25.4 100.3 25.4 23.7 0 42.4-2.7 66.7-9.7 23.4-6.7 35.7-15 42.3-28.8 5.2-10.9 6.6-17.5 7.2-33.9l.6-14.8 62.1.3c61.6.3 62.2.3 71.6 2.7 48.7 12.2 83.1 48.6 91.5 96.8 1.2 7 1.5 20.5 1.5 73.9V287H56.9l.4-67.8c.3-64.8.4-68.1 2.5-76.7 2.8-11.9 5.1-18.4 10.2-28.6C83.9 86 109.2 64.3 139.7 54c16.6-5.5 20.3-5.8 84.8-5.9l59-.1zM396 489v193H57v-42.7l9.8-.6c17.2-1.2 31.4-6.3 40.8-15 8.8-8 16-24.7 21.9-51.2 7.6-33.9 7.6-68.2-.1-102-5.7-25.6-11.3-39-19.9-48.3-9.3-10.1-23.7-15.9-42.5-17.1l-9.5-.6-.3-54.3L57 296h339zm348-139.1v53.8l-9.4.7c-18 1.2-33.9 7.2-42.3 15.9-5.5 5.6-10.5 15-14.7 27.7-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.1 10.1 22.9 15.1 41.4 16.1l10.2.6V682H405V296h339zM395.8 880.2l-.3 188.3-169.2.3-169.3.2v-83.7l11.8-.6c18.9-1 32.8-5.9 42.8-15C126.7 956 139.1 910 139.1 868c0-23.9-3.5-47.1-10.7-71-9.5-31.5-25.9-44.2-59.1-45.7l-12.3-.6V692h339zM744 720.9v28.8l-9.4.7c-18 1.2-33.9 7.2-42.3 15.9-5.5 5.6-10.5 15-14.7 27.7-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.1 10.1 22.9 15.1 41.4 16.1l10.2.6v84.7H405V692h339zm0 427c0 76.6-.1 78.7-6.1 96.5-13.4 40-47.4 70-89.9 79.2-6.3 1.4-17 1.7-68.6 2.1l-61.1.4-.6-10.3c-.7-11.8-4-24.6-8.3-32.3-8.3-14.9-24-23.3-57.9-30.9-23.8-5.4-54.3-7.2-76-4.6-21.2 2.5-48 9.3-60.9 15.5-19.1 9-28.7 25.4-30.4 52l-.7 10-53 .3c-57.6.3-70.7-.4-85.4-4.3-24.3-6.6-47.8-22.5-63.5-43-7.7-10.1-16.6-27.7-19.6-38.6-4.7-17.6-5-22.1-5-94.2V1078h687z" />
<path d="M391.8 150c-16.5 3-30 12.2-39.1 26.7-7.9 12.6-10 31-5.2 46.1 4.5 14.4 15.5 26.9 29.1 33.4 22.1 10.4 46.1 6.2 63.5-11.1 11.5-11.5 16.9-24.2 16.9-39.9 0-23.4-16.1-45.5-38.6-53.1-7.1-2.3-19.8-3.4-26.6-2.1M192 466.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M578.1 468.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2M196 812.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M578.1 814.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2M388.3 1121.5c-10.8 2.3-19 7-27.6 15.6-11.4 11.4-16.7 23.9-16.7 39.7 0 23.6 15.9 45.3 39 53.3 9.2 3.1 23.7 3.2 33.7.1 12.7-3.9 24.1-12.9 31.6-24.9 7.9-12.6 10-31 5.2-46.1-8.6-27.2-37.2-43.8-65.2-37.7" />
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const ThreePlayers = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zM396 365v317H57V511.3l11.3-.6c18.4-1 32.5-6 42.3-15C125.7 482 138.1 436 138.1 394c0-23.9-3.5-47.1-10.7-71-9.4-31.4-25.9-44.2-58.7-45.7l-11.8-.6.4-62.6c.3-59.6.4-63 2.5-71.6 2.8-11.9 5.1-18.4 10.2-28.6C83.9 86 109.2 64.3 139.7 54c17.7-5.9 15.3-5.8 141.1-5.9L396 48v317zM651.5 50.9c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.3 7.4 1.5 36.6 1.5 215.3v206.7l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6V1011c0 227.3.3 214.2-6.1 233.4-13.4 40-47 69.6-89.9 79.3-6.9 1.6-26.1 1.7-239 2-154.7.3-235.3 0-243-.7-20.8-1.8-38.3-8-55.8-19.7-28.1-18.7-46.6-48.2-51.8-82.8-1.1-6.8-1.4-23-1.4-66.1v-57.1l11.3-.6c18.4-1 32.5-6 42.3-15 15.1-13.7 27.5-59.7 27.5-101.7 0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.6-45.7l-11.8-.6V691h339v634h9V47.9l118.8.4 118.7.3 9 2.3z" />
<path d="M195 338.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM574.1 634.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2zM195 926.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7M396 365v317H57V511.3l11.3-.6q27.6-1.5 42.3-15C125.7 482 138.1 436 138.1 394c0-23.9-3.5-47.1-10.7-71-9.4-31.4-25.9-44.2-58.7-45.7l-11.8-.6.4-62.6c.3-59.6.4-63 2.5-71.6 2.8-11.9 5.1-18.4 10.2-28.6C83.9 86 109.2 64.3 139.7 54c17.7-5.9 15.3-5.8 141.1-5.9L396 48zM651.5 50.9c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.3 7.4 1.5 36.6 1.5 215.3v206.7l-11.2.6c-13.6.8-24.6 3.4-33.7 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.6 10.6 23 15.2 43.4 16.1l12.2.6V1011c0 227.3.3 214.2-6.1 233.4-13.4 40-47 69.6-89.9 79.3-6.9 1.6-26.1 1.7-239 2-154.7.3-235.3 0-243-.7-20.8-1.8-38.3-8-55.8-19.7-28.1-18.7-46.6-48.2-51.8-82.8-1.1-6.8-1.4-23-1.4-66.1v-57.1l11.3-.6q27.6-1.5 42.3-15c15.1-13.7 27.5-59.7 27.5-101.7 0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.6-45.7l-11.8-.6V691h339v634h9V47.9l118.8.4 118.7.3z" />
<path d="M195 338.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M574.1 634.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2M195 926.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5" />
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const ThreePlayersSide = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zM397 471.5V895H57V592.3l9.8-.6c17.2-1.2 31.4-6.3 40.8-15 8.8-8 16-24.7 21.9-51.2 7.6-33.9 7.6-68.2-.1-102-5.7-25.6-11.3-39-19.9-48.3-9.3-10.1-23.7-15.9-42.5-17.1l-9.5-.6v-102c0-94.2.1-102.6 1.8-110.5 9.2-43.6 38.7-77 80.4-91 17.7-5.9 15.2-5.8 141.6-5.9L397 48v423.5zM651.5 50.9c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.3 7.2 1.5 24.4 1.5 108.8v100.2l-8.2.8c-17.1 1.4-32.5 7.5-40.5 15.8-5.5 5.6-10.5 15-14.7 27.7-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 9.7 9.7 22.6 14.9 39.9 16.1l8.7.6V895H407V47.9l117.8.4 117.7.3 9 2.3zm92.5 1010c0 172.4.3 164.6-6.1 183.5-13.4 40-47.4 70-89.9 79.2-6.3 1.4-17 1.7-68.6 2.1l-61.1.4-.7-8.6c-.8-10.3-4.3-23-8.2-30-8.3-14.9-24-23.3-57.9-30.9-23.8-5.4-54.3-7.2-76-4.6-21.2 2.5-48 9.3-60.9 15.5-18.5 8.7-28.1 24.5-30.3 49.6l-.8 8.4-53 .3c-57.6.3-70.7-.4-85.4-4.3-24.3-6.6-47.8-22.5-63.5-43-7.7-10.1-16.6-27.7-19.6-38.6-5.1-18.8-5-15.5-5-181.2V904h687v156.9z" />
<path d="M192 419.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM581.1 421.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2zM388.3 1125.5c-10.8 2.3-19 7-27.6 15.6-11.4 11.4-16.7 23.9-16.7 39.7 0 23.6 15.9 45.3 39 53.3 9.2 3.1 23.7 3.2 33.7.1 12.7-3.9 24.1-12.9 31.6-24.9 7.9-12.6 10-31 5.2-46.1-8.6-27.2-37.2-43.8-65.2-37.7z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7M397 471.5V895H57V592.3l9.8-.6c17.2-1.2 31.4-6.3 40.8-15 8.8-8 16-24.7 21.9-51.2 7.6-33.9 7.6-68.2-.1-102-5.7-25.6-11.3-39-19.9-48.3-9.3-10.1-23.7-15.9-42.5-17.1l-9.5-.6v-102c0-94.2.1-102.6 1.8-110.5 9.2-43.6 38.7-77 80.4-91 17.7-5.9 15.2-5.8 141.6-5.9L397 48zM651.5 50.9c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.3 7.2 1.5 24.4 1.5 108.8v100.2l-8.2.8c-17.1 1.4-32.5 7.5-40.5 15.8-5.5 5.6-10.5 15-14.7 27.7-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 9.7 9.7 22.6 14.9 39.9 16.1l8.7.6V895H407V47.9l117.8.4 117.7.3zm92.5 1010c0 172.4.3 164.6-6.1 183.5-13.4 40-47.4 70-89.9 79.2-6.3 1.4-17 1.7-68.6 2.1l-61.1.4-.7-8.6c-.8-10.3-4.3-23-8.2-30-8.3-14.9-24-23.3-57.9-30.9-23.8-5.4-54.3-7.2-76-4.6-21.2 2.5-48 9.3-60.9 15.5-18.5 8.7-28.1 24.5-30.3 49.6l-.8 8.4-53 .3c-57.6.3-70.7-.4-85.4-4.3-24.3-6.6-47.8-22.5-63.5-43-7.7-10.1-16.6-27.7-19.6-38.6-5.1-18.8-5-15.5-5-181.2V904h687z" />
<path d="M192 419.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M581.1 421.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2M388.3 1125.5c-10.8 2.3-19 7-27.6 15.6-11.4 11.4-16.7 23.9-16.7 39.7 0 23.6 15.9 45.3 39 53.3 9.2 3.1 23.7 3.2 33.7.1 12.7-3.9 24.1-12.9 31.6-24.9 7.9-12.6 10-31 5.2-46.1-8.6-27.2-37.2-43.8-65.2-37.7" />
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const TwoPlayersOppositeLandscape = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zM396 687v639H285.3c-63.3 0-115-.5-120.7-1-32.5-3.2-63-20.2-83-46.5-7.7-10.1-16.6-27.7-19.6-38.6-5.1-19-5-11.7-5-230.5V805.3l11.3-.6c18.4-1 32.5-6 42.3-15C125.7 776 138.1 730 138.1 688c0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.7-45.7l-11.7-.6.3-209.6.3-209.6 2.1-9c2.9-11.9 5.2-18.4 10.3-28.6C83.9 86 109.2 64.3 139.7 54c17.7-5.9 15.3-5.8 141.1-5.9L396 48v639zM651.5 50.9c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.3 7.4 1.5 36.5 1.5 214.8v206.2l-11.7.6c-14 .7-24.9 3.3-34.2 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.7 10.7 23.1 15.2 43.9 16.1l12.7.6v207.2c0 227.9.3 214.7-6.1 233.9-13.7 41-49.7 71.9-92.9 79.7-6.1 1.1-29.8 1.4-123.5 1.4h-116l-.3-638.8-.2-638.8 118.7.4 118.8.3 9 2.3z" />
<path d="M195 632.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM573.1 633.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7M396 687v639H285.3c-63.3 0-115-.5-120.7-1-32.5-3.2-63-20.2-83-46.5-7.7-10.1-16.6-27.7-19.6-38.6-5.1-19-5-11.7-5-230.5V805.3l11.3-.6q27.6-1.5 42.3-15C125.7 776 138.1 730 138.1 688c0-23.9-3.5-47.1-10.7-71-9.4-31.3-25.9-44.2-58.7-45.7l-11.7-.6.3-209.6.3-209.6 2.1-9c2.9-11.9 5.2-18.4 10.3-28.6C83.9 86 109.2 64.3 139.7 54c17.7-5.9 15.3-5.8 141.1-5.9L396 48zM651.5 50.9c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.3 7.4 1.5 36.5 1.5 214.8v206.2l-11.7.6c-14 .7-24.9 3.3-34.2 8.2-12.2 6.4-19 15.9-25.5 35.5-13.2 40-15.3 83.2-6 124.8 5.8 25.6 11.8 39.8 20.8 48.8 10.7 10.7 23.1 15.2 43.9 16.1l12.7.6v207.2c0 227.9.3 214.7-6.1 233.9-13.7 41-49.7 71.9-92.9 79.7-6.1 1.1-29.8 1.4-123.5 1.4h-116l-.3-638.8-.2-638.8 118.7.4 118.8.3z" />
<path d="M195 632.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M573.1 633.5c-14.3 4.6-27 15.7-33.3 29.1-10.4 22.2-6.2 46.1 11.1 63.5 11.5 11.5 24.2 16.9 39.9 16.9 23.6 0 45.3-15.9 53.3-39 3.1-9.2 3.2-23.7.1-33.7-3.9-12.7-12.9-24.1-24.9-31.6-12.5-7.9-31.4-10-46.2-5.2" />
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const TwoPlayersOppositePortrait = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zm123.9 39.6c1.2 20.3 6.6 34.2 16.8 44 10.3 9.8 39.8 19.5 72.3 23.8 13.9 1.8 40.1 2.1 53 .5 21.2-2.5 48-9.3 60.9-15.5 19.3-9.2 28.8-25.6 30.3-52.3l.6-11.3 62.1.3c61.6.3 62.2.3 71.6 2.7 48.7 12.2 83.1 48.6 91.5 96.8 1.3 7.4 1.5 43.1 1.5 272.9V685H57l.3-266.8.3-266.7 2.1-9c2.9-12 5.2-18.4 10.3-28.6C83.9 86 109.2 64.3 139.7 54c16.6-5.5 20.4-5.8 84.4-5.9l58.6-.1.7 10.7zM744 955.9c0 288.1.4 269.2-6.1 288.5-13.4 40-47.4 70-89.9 79.2-6.3 1.4-17 1.7-68.6 2.1l-61.1.4-.6-11.3c-1.5-27-10.8-43.5-29.8-52.6-13.9-6.7-36.6-12.7-59.4-15.7-13.9-1.8-40-2.1-53-.5-21.2 2.5-48 9.3-60.9 15.5-19.4 9.2-28.8 25.7-30.5 53l-.6 11-53 .3c-57.6.3-70.7-.4-85.4-4.3-24.3-6.6-47.8-22.5-63.5-43-7.7-10.1-16.6-27.7-19.6-38.6-5.2-19.2-5-7.3-5-286.2V694h687v261.9z" />
<path d="M391.8 143c-16.5 3-30 12.2-39.1 26.7-7.9 12.6-10 31-5.2 46.1 4.5 14.4 15.5 26.9 29.1 33.4 22.1 10.4 46.1 6.2 63.5-11.1 11.5-11.5 16.9-24.2 16.9-39.9 0-23.4-16.1-45.5-38.6-53.1-7.1-2.3-19.8-3.4-26.6-2.1zM388.3 1119.5c-10.8 2.3-19 7-27.6 15.6-11.4 11.4-16.7 23.9-16.7 39.7 0 23.6 15.9 45.3 39 53.3 9.2 3.1 23.7 3.2 33.7.1 12.7-3.9 24.1-12.9 31.6-24.9 7.9-12.6 10-31 5.2-46.1-8.6-27.2-37.2-43.8-65.2-37.7z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7m123.9 39.6c1.2 20.3 6.6 34.2 16.8 44 10.3 9.8 39.8 19.5 72.3 23.8 13.9 1.8 40.1 2.1 53 .5 21.2-2.5 48-9.3 60.9-15.5 19.3-9.2 28.8-25.6 30.3-52.3l.6-11.3 62.1.3c61.6.3 62.2.3 71.6 2.7 48.7 12.2 83.1 48.6 91.5 96.8 1.3 7.4 1.5 43.1 1.5 272.9V685H57l.3-266.8.3-266.7 2.1-9c2.9-12 5.2-18.4 10.3-28.6C83.9 86 109.2 64.3 139.7 54c16.6-5.5 20.4-5.8 84.4-5.9l58.6-.1zM744 955.9c0 288.1.4 269.2-6.1 288.5-13.4 40-47.4 70-89.9 79.2-6.3 1.4-17 1.7-68.6 2.1l-61.1.4-.6-11.3c-1.5-27-10.8-43.5-29.8-52.6-13.9-6.7-36.6-12.7-59.4-15.7-13.9-1.8-40-2.1-53-.5-21.2 2.5-48 9.3-60.9 15.5-19.4 9.2-28.8 25.7-30.5 53l-.6 11-53 .3c-57.6.3-70.7-.4-85.4-4.3-24.3-6.6-47.8-22.5-63.5-43-7.7-10.1-16.6-27.7-19.6-38.6-5.2-19.2-5-7.3-5-286.2V694h687z" />
<path d="M391.8 143c-16.5 3-30 12.2-39.1 26.7-7.9 12.6-10 31-5.2 46.1 4.5 14.4 15.5 26.9 29.1 33.4 22.1 10.4 46.1 6.2 63.5-11.1 11.5-11.5 16.9-24.2 16.9-39.9 0-23.4-16.1-45.5-38.6-53.1-7.1-2.3-19.8-3.4-26.6-2.1M388.3 1119.5c-10.8 2.3-19 7-27.6 15.6-11.4 11.4-16.7 23.9-16.7 39.7 0 23.6 15.9 45.3 39 53.3 9.2 3.1 23.7 3.2 33.7.1 12.7-3.9 24.1-12.9 31.6-24.9 7.9-12.6 10-31 5.2-46.1-8.6-27.2-37.2-43.8-65.2-37.7" />
</svg>
);
};

View File

@@ -20,8 +20,8 @@ const TwoPlayersSameSide = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7zm492 31.8c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.3 7.4 1.5 42.9 1.5 271.4V682H57V511.3l11.8-.6c18.9-1 32.8-5.9 42.8-15C126.7 482 139.1 436 139.1 394c0-23.9-3.5-47.1-10.7-71-9.5-31.5-25.9-44.2-59.2-45.7l-12.3-.6.4-62.6c.3-59.6.4-63 2.5-71.6 2.8-11.9 5.1-18.4 10.2-28.6C83.9 86 109.2 64.3 139.7 54c18.5-6.2 3.5-5.8 264.3-5.6l238.5.1 9 2.4zm92.5 904c0 289.2.4 270.2-6.1 289.5-13.4 40-47 69.6-89.9 79.3-6.9 1.6-26.1 1.7-239 2-154.7.3-235.3 0-243-.7-20.8-1.8-38.3-8-55.8-19.7-28.1-18.7-46.6-48.2-51.8-82.8-1.1-6.8-1.4-23.1-1.4-67.1v-58.1l11.8-.6c18.9-1 32.8-5.9 42.8-15 15.1-13.7 27.5-59.7 27.5-101.7 0-23.9-3.5-47.1-10.7-71-9.5-31.5-25.9-44.2-59.1-45.7l-12.3-.6V692h687v262.9z" />
<path d="M196 338.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5zM196 924.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5z" />
<path d="M159.5 19.1c-17.6 1.8-34.7 7.2-52.2 16.4-14.4 7.5-25 15.3-36.8 27-20.3 20.4-33.6 45.2-40.7 76l-2.3 10-.3 531.5c-.2 382 0 534.3.8 541.5 2.2 20.1 7.2 36.4 16.5 54.3 7.3 14 15.2 24.6 26.7 36.1 20.1 20.1 41 31.8 70.8 39.8l10.5 2.8h497l11.7-3.2c27-7.4 47-18.5 66.9-37.1 21.5-20.2 37-48.2 43.6-79.2 1.7-8.1 1.8-30.9 1.8-548 0-518.6-.1-539.8-1.8-548-12-55.7-49.8-97.4-103.5-114.4-20.5-6.4-.6-6-262.7-6.2-130.9-.1-241.6.2-246 .7m492 31.8c5 1.3 13.2 4.1 18.4 6.2 38.5 15.7 65.4 49.3 72.6 90.6 1.3 7.4 1.5 42.9 1.5 271.4V682H57V511.3l11.8-.6c18.9-1 32.8-5.9 42.8-15C126.7 482 139.1 436 139.1 394c0-23.9-3.5-47.1-10.7-71-9.5-31.5-25.9-44.2-59.2-45.7l-12.3-.6.4-62.6c.3-59.6.4-63 2.5-71.6 2.8-11.9 5.1-18.4 10.2-28.6C83.9 86 109.2 64.3 139.7 54c18.5-6.2 3.5-5.8 264.3-5.6l238.5.1zm92.5 904c0 289.2.4 270.2-6.1 289.5-13.4 40-47 69.6-89.9 79.3-6.9 1.6-26.1 1.7-239 2-154.7.3-235.3 0-243-.7-20.8-1.8-38.3-8-55.8-19.7-28.1-18.7-46.6-48.2-51.8-82.8-1.1-6.8-1.4-23.1-1.4-67.1v-58.1l11.8-.6c18.9-1 32.8-5.9 42.8-15 15.1-13.7 27.5-59.7 27.5-101.7 0-23.9-3.5-47.1-10.7-71-9.5-31.5-25.9-44.2-59.1-45.7l-12.3-.6V692h687z" />
<path d="M196 338.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5M196 924.6c-18.6 4.9-33.7 19-40.1 37.4-1.7 5-2.2 8.9-2.3 16.5-.1 12.8 2.5 21.5 9.4 31.8 10.7 16 27 24.7 46.4 24.7 27.2 0 49.5-18 55.1-44.6 1.8-8.7 1.8-14.1 0-22.6-4.4-21.2-22.5-39.4-43.3-43.7-7.2-1.5-18.5-1.3-25.2.5" />
</svg>
);
};

View File

@@ -21,8 +21,8 @@ const LittleGuy = ({
>
{title ? <title id={titleId}>{title}</title> : null}
<g fill="currentColor">
<path d="M233.8 9.7c-18.1 17.5-25.6 32.5-25.8 51.5 0 5.9.7 7.8 3.1 7.8 2.8 0 3.6-2.6 4.1-13.2.4-8.9.7-10.2 4.7-18.3 3.6-7.4 6.2-10.7 15.7-20.5C241.9 10.6 247 4.6 247 3.7c0-1.2-1.9-2.7-3.6-2.7-.3 0-4.6 3.9-9.6 8.7zM36.5 54.7c-8.4.6-31.6 4.3-33.6 5.4-2.3 1.2-2.5 4.5-.3 5.3.9.3 1.9.4 2.3.2.3-.2 7.2-1.4 15.1-2.6 12.9-2 17.1-2.2 37.5-1.6 24.9.6 31.9 1.5 52.6 6.9 16.2 4.3 29 8.8 42.3 15.1 8.7 4 10.2 4.5 11.4 3.2 2.3-2.3.8-4.3-5.5-7.4C141.9 70.9 111 61 90.5 57.5c-7.8-1.4-41.4-3.7-47-3.3-1.1.1-4.2.3-7 .5zM205.8 87.6c-16.9 3-35.3 12.3-44.8 22.7-4.5 4.8-9.9 16.6-11.6 25.4-2.6 12.8-.2 40.8 4.7 56.2 8.1 25.4 34.3 55.1 55.6 63.1 12.4 4.6 17.3 5.5 31.3 5.4 7.9 0 14.6-.5 16.3-1.2 2.5-1.1 2.7-1.5 2.7-7.6v-6.5l-4.2 1.6c-6.1 2.3-24.2 2.2-32.7-.1-13.5-3.7-26.2-12.2-36.9-24.5-16.9-19.7-22.9-34.2-25.1-60.6-1.4-17.8 0-27.4 5.6-37.6 3.6-6.8 9.5-11.8 19.5-16.7 21.8-10.7 42.8-11.5 66.3-2.3l7.5 2.9V94.2l-8-2.7c-16.2-5.4-31.1-6.7-46.2-3.9z" />
<path d="M222.5 132.5c-4.8 4.7-1.9 11.5 4.9 11.5 6.4 0 9-7.9 4-11.9-3.5-2.7-5.9-2.6-8.9.4zM184.5 152.5c-3 3-3.1 5.4-.4 8.9 4 5 11.9 2.4 11.9-4 0-6.8-6.8-9.7-11.5-4.9zM255.8 171.8c-4.7 9.7-13.3 20.3-19.5 23.8-5.9 3.3-7.3 5-7.3 8.6 0 3.6 3.2 6.8 6.8 6.8 4.1 0 12-5.1 18.5-11.8l5.7-6.1v-14.5c0-8-.1-14.6-.2-14.5-.2 0-2 3.5-4 7.7z" />
<path d="M233.8 9.7c-18.1 17.5-25.6 32.5-25.8 51.5 0 5.9.7 7.8 3.1 7.8 2.8 0 3.6-2.6 4.1-13.2.4-8.9.7-10.2 4.7-18.3 3.6-7.4 6.2-10.7 15.7-20.5C241.9 10.6 247 4.6 247 3.7c0-1.2-1.9-2.7-3.6-2.7-.3 0-4.6 3.9-9.6 8.7M36.5 54.7c-8.4.6-31.6 4.3-33.6 5.4-2.3 1.2-2.5 4.5-.3 5.3.9.3 1.9.4 2.3.2.3-.2 7.2-1.4 15.1-2.6 12.9-2 17.1-2.2 37.5-1.6 24.9.6 31.9 1.5 52.6 6.9 16.2 4.3 29 8.8 42.3 15.1 8.7 4 10.2 4.5 11.4 3.2 2.3-2.3.8-4.3-5.5-7.4C141.9 70.9 111 61 90.5 57.5c-7.8-1.4-41.4-3.7-47-3.3-1.1.1-4.2.3-7 .5M205.8 87.6c-16.9 3-35.3 12.3-44.8 22.7-4.5 4.8-9.9 16.6-11.6 25.4-2.6 12.8-.2 40.8 4.7 56.2 8.1 25.4 34.3 55.1 55.6 63.1 12.4 4.6 17.3 5.5 31.3 5.4 7.9 0 14.6-.5 16.3-1.2 2.5-1.1 2.7-1.5 2.7-7.6v-6.5l-4.2 1.6c-6.1 2.3-24.2 2.2-32.7-.1-13.5-3.7-26.2-12.2-36.9-24.5-16.9-19.7-22.9-34.2-25.1-60.6-1.4-17.8 0-27.4 5.6-37.6 3.6-6.8 9.5-11.8 19.5-16.7 21.8-10.7 42.8-11.5 66.3-2.3l7.5 2.9V94.2l-8-2.7c-16.2-5.4-31.1-6.7-46.2-3.9" />
<path d="M222.5 132.5c-4.8 4.7-1.9 11.5 4.9 11.5 6.4 0 9-7.9 4-11.9-3.5-2.7-5.9-2.6-8.9.4M184.5 152.5c-3 3-3.1 5.4-.4 8.9 4 5 11.9 2.4 11.9-4 0-6.8-6.8-9.7-11.5-4.9M255.8 171.8c-4.7 9.7-13.3 20.3-19.5 23.8-5.9 3.3-7.3 5-7.3 8.6s3.2 6.8 6.8 6.8c4.1 0 12-5.1 18.5-11.8l5.7-6.1v-14.5c0-8-.1-14.6-.2-14.5-.2 0-2 3.5-4 7.7" />
</g>
</svg>
);

View File

@@ -22,7 +22,7 @@ const Logo = ({
>
{title ? <title id={titleId}>{title}</title> : null}
<path
d="M0-196.791c108.629 0 196.791 88.162 196.791 196.791 0 108.629-88.162 196.791-196.791 196.791-108.629 0-196.791-88.162-196.791-196.791 0-108.629 88.162-196.791 196.791-196.791z"
d="M0-196.791c108.629 0 196.791 88.162 196.791 196.791S108.63 196.791 0 196.791-196.791 108.63-196.791 0-108.63-196.791 0-196.791z"
style={{
stroke: '#590713',
strokeWidth: 0,
@@ -39,7 +39,7 @@ const Logo = ({
/>
<path
strokeLinecap="round"
d="M-17.706-50.704s-4.378 12.973.446 25.583c2.124 5.55 12.255 17.109 17.107 36.364 4.852 19.255 19.679 39.46 19.679 39.46"
d="M-17.706-50.704s-4.378 12.973.446 25.583c2.124 5.55 12.255 17.109 17.107 36.364s19.679 39.46 19.679 39.46"
style={{
stroke: '#000',
strokeWidth: 4,
@@ -52,12 +52,12 @@ const Logo = ({
fillRule: 'nonzero',
opacity: 1,
}}
transform="rotate(1 -17129.538 10072.475) scale(2.11279)"
transform="rotate(1 -17129.538 10072.475)scale(2.11279)"
/>
<path
fill="none"
strokeLinecap="round"
d="M50.163 56.172S31.68 34 24.46 3.6C17.239-26.8 13.467-35.306 2.42-47.373c-11.046-12.066-26.224-12.189-25.26 2.534.966 14.722 12.84 12.598 14.365 1.93 1.526-10.667-21.8-10.696-32.304 1.854C-53.573-25.77-49.57-2.79-49.57-2.79"
d="M50.163 56.172S31.68 34 24.46 3.6 13.467-35.306 2.42-47.373c-11.046-12.066-26.224-12.189-25.26 2.534.966 14.722 12.84 12.598 14.365 1.93 1.526-10.667-21.8-10.696-32.304 1.854C-53.573-25.77-49.57-2.79-49.57-2.79"
style={{
stroke: '#000',
strokeWidth: 6,
@@ -76,7 +76,7 @@ const Logo = ({
<path
fill="none"
strokeLinecap="round"
d="M-61.541-71.832s39.965 62.644 41.684 89.093c1.718 26.45 7.326 33.328 17.516 44.667 10.19 11.339 36.055 16.684 32.478-4.845-3.578-21.53-29.514-8.071-16.735 4.07 12.779 12.143 30.514 9.462 39.88-2.368 6.188-7.814 9.732-26.682 7.67-41.524-1.059-7.627-14.72-28.434-14.72-28.434"
d="M-61.541-71.832s39.965 62.644 41.684 89.093 7.326 33.328 17.516 44.667 36.055 16.684 32.478-4.845c-3.578-21.53-29.514-8.071-16.735 4.07 12.779 12.143 30.514 9.462 39.88-2.368 6.188-7.814 9.732-26.682 7.67-41.524-1.059-7.627-14.72-28.434-14.72-28.434"
style={{
stroke: '#000',
strokeWidth: 6,
@@ -95,7 +95,7 @@ const Logo = ({
<path
fill="none"
strokeLinecap="round"
d="M-26.889-69.574S-9.544-51.826-3.454-23.78c6.09 28.046 24.518 40.828 27.8 61.071 3.284 20.244 3.494 23.63 0 32.283"
d="M-26.889-69.574S-9.544-51.826-3.454-23.78s24.518 40.828 27.8 61.071c3.284 20.244 3.494 23.63 0 32.283"
style={{
stroke: '#000',
strokeWidth: 6,
@@ -114,7 +114,7 @@ const Logo = ({
<path
fill="none"
strokeLinecap="round"
d="M30.481-85.77S31.897-63.74-.082-1.032C-32.06 61.673-30.478 85.769-30.478 85.769"
d="M30.481-85.77S31.897-63.74-.082-1.032s-30.396 86.802-30.396 86.802"
style={{
stroke: '#000',
strokeWidth: 6,
@@ -133,7 +133,7 @@ const Logo = ({
<path
fill="none"
strokeLinecap="round"
d="M-30.017 97.228S-.607 52.493 6.833 6.645c7.44-45.849 23.184-103.873 23.184-103.873"
d="M-30.017 97.228S-.607 52.493 6.833 6.645 30.016-97.228 30.016-97.228"
style={{
stroke: '#000',
strokeWidth: 6,
@@ -152,7 +152,7 @@ const Logo = ({
<path
fill="none"
strokeLinecap="round"
d="M-24.23-79.242s-7.454 19.782-.69 39.5c2.979 8.68 17.988 27.06 24.437 57.033 6.45 29.973 28.24 61.951 28.24 61.951"
d="M-24.23-79.242s-7.454 19.782-.69 39.5c2.979 8.68 17.988 27.06 24.437 57.033s28.24 61.951 28.24 61.951"
style={{
stroke: '#000',
strokeWidth: 1,
@@ -166,11 +166,11 @@ const Logo = ({
fillRule: 'nonzero',
opacity: 1,
}}
transform="rotate(-1.005 17359.092 -9769.972) scale(1.36839)"
transform="rotate(-1.005 17359.092 -9769.972)scale(1.36839)"
/>
<path
strokeLinecap="round"
d="M-45.63-48.464C-71.24-37.592-84.397-27.166-91.043-20.02c-4.07 4.376-3.966 4.338-5.24 6.898a4.617 4.617 0 0 0 .396 4.766c.894 1.234.96 1.326 2.899 3.595C-83.146 6.756-56.46 32.52-4.814 47.45c44.828 12.96 74.528 12.437 89.557 10.58 2.68-.332 2.726-.3 4.041-.593a10.178 10.178 0 0 0 7.957-9.425c.047-.93.022-1.057-.024-2.821-.34-12.824-3.372-35.645-18.26-58.984-22.56-35.37-46.732-40.492-46.732-40.492S.657-68.114-45.63-48.464z"
d="M-45.63-48.464C-71.24-37.592-84.397-27.166-91.043-20.02c-4.07 4.376-3.966 4.338-5.24 6.898a4.62 4.62 0 0 0 .396 4.766c.894 1.234.96 1.326 2.899 3.595C-83.146 6.756-56.46 32.52-4.814 47.45c44.828 12.96 74.528 12.437 89.557 10.58 2.68-.332 2.726-.3 4.041-.593a10.18 10.18 0 0 0 7.957-9.425c.047-.93.022-1.057-.024-2.821-.34-12.824-3.372-35.645-18.26-58.984-22.56-35.37-46.732-40.492-46.732-40.492S.657-68.114-45.63-48.464z"
style={{
stroke: '#000',
strokeWidth: 6,
@@ -225,7 +225,7 @@ const Logo = ({
/>
<path
strokeLinecap="round"
d="M-90.654-77.091S-74.41-28.509-9.055-2.309C56.299 23.89 100.897 9.078 100.897 9.078S61.451 101.65-37.09 70.793C-135.63 39.936-90.654-77.09-90.654-77.09z"
d="M-90.654-77.091S-74.41-28.509-9.055-2.309C56.299 23.89 100.897 9.078 100.897 9.078S61.451 101.65-37.09 70.793-90.654-77.09-90.654-77.09z"
style={{
stroke: '#000',
strokeWidth: 6,

View File

@@ -22,7 +22,7 @@ const PartnerTax = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M196.7 79.1c-2.1.5-5 1.5-6.5 2.3-3.3 1.8-17.6 16.3-59.3 60.1-60 63.1-60.2 63.3-62.2 78.5-1.7 13.3 1.4 24.2 10 34.7 6.5 7.9 10.6 9.9 40.8 19.8 29.9 9.8 33 11 30.5 11.9-.8.3-8 3.1-16 6.1-8 3.1-19.7 7.5-26 9.9-20.7 7.9-40.3 15.7-45 18.1-2.6 1.3-7.2 5.1-10.2 8.4-6.6 7.1-7.2 8.7-17.9 47.6-19.1 69.1-21.3 78.3-20.3 84.8 1.6 9.6 7.1 16.9 16.3 21.7l4 2 233.6-.2 233.7-.3 3.3-3.7c5.2-5.6 5.3-7.6 1.6-22.3-5.9-23.2-13.2-47.9-15.3-51.3-3.3-5.3-7.3-7.5-30-16.3-12-4.6-21.8-8.6-21.8-8.9 0-.3 6.6-2.7 14.8-5.4 16.2-5.3 19.9-7.5 23.8-14.3 3.4-5.6 3.7-13.7.8-20-1.9-4.2-32.4-37.2-52.7-57.1-9-8.8-9.6-9.2-13.8-9.2-2.4.1-5.4.6-6.5 1.3-1.8 1-17.1 16.5-46 46.6l-7.2 7.5-3.3-3.5c-7.4-7.7-11.5-9.6-79.6-35.9-9-3.5-16.3-6.7-16.3-7.1 0-.4 12.5-4.8 27.8-9.8 16.3-5.3 29.6-10.2 32.2-11.9 6-3.8 13.3-11.8 16.3-17.8 7-13.9 5.4-33.5-3.8-45.3-7.2-9.1-103-109.8-110.2-115.7-5.8-4.8-13.2-6.7-19.6-5.3zm34.8 84.4c5.5 1.4 12.2 3.3 14.9 4.2l4.8 1.5-.6 4.6c-1 7.4-11.3 36.9-16.3 46.8-2.5 5.1-7.6 13.4-11.3 18.5-5.4 7.6-7.7 9.9-12 12.1-6.8 3.6-12.8 3.7-19.7.3-5.8-2.9-9.3-6.8-18.2-20.5-8.2-12.5-13.2-23.1-17.5-37.1-5.1-17-6.4-23.8-4.6-24.9.8-.5 7.9-2.5 15.9-4.4 8.1-1.9 15.5-3.8 16.6-4 1.1-.3 10.1-.3 20-.1 15.1.4 19.6.8 28 3zm-76.1 88.4 46.9 23.5 51.8-25.9c28.5-14.3 52.1-25.7 52.4-25.3.8.8-1.8 7-3.6 8.4-3.9 3.1-93.1 50.5-98.6 52.5-3.1 1-4.2.6-19-7.1-23.6-12.4-66.7-35.6-75.5-40.7-7.6-4.4-11.8-8.5-11.8-11.6 0-2.4 4.5-.3 57.4 26.2zM418.5 318c12 1.2 19.5 3.5 19.5 5.9 0 3.7-7.2 22.7-11 29.2-5.4 9.1-9.9 12.9-15.2 12.9-3.7 0-4.7-.6-8.7-4.8-5.3-5.5-12-17.7-15-27.6-3.2-10.5-3.1-11.3 3.2-13.1 12.1-3.5 15-3.8 27.2-2.5zM88.6 354.5c1.4 3.2 2.4 7.5 2.4 10.1 0 6-14 102.3-15.7 107.8-.5 1.8-.6 1.8-1.5.1-1.4-2.4-7.8-23.3-7.8-25.4-.1-3.8 18.5-98.1 19.2-98.1.5 0 2 2.5 3.4 5.5zm239.8 43.3c5.3 26.8 9.6 49.4 9.6 50.1 0 2.1-9.2 28.1-9.9 28.1-.4 0-1.9-7.8-3.4-17.3-1.4-9.4-5.4-34.7-8.7-56l-6-38.8 3.4-7.4c1.9-4.1 3.9-7.5 4.4-7.5.5 0 5.3 21.9 10.6 48.8zm136.5-43.3c-3 2.9-50.1 27.5-52.5 27.5-1.1 0-8.6-3.6-16.9-8.1-8.2-4.4-18.9-10.1-23.7-12.6-8-4.2-10.8-6.7-9.3-8.2.3-.3 11.7 5 25.3 11.8l24.7 12.3 27-13.5c25.2-12.6 31.2-14.8 25.4-9.2zm-86.6 25.1c4.3 1.4 7.7 2.8 7.5 3-.2.2-3.4 1.5-7.1 2.9l-6.6 2.5-1.6-5.2c-.8-2.8-1.5-5.3-1.5-5.5 0-.6 1.7-.2 9.3 2.3zm100.1 62.8 4.5 23.4-2.3 6.9c-2.9 8.4-2.5 9.8-7.6-24.5-3.7-25.3-3.8-26.5-2.2-29.8 1.5-3.2 1.7-3.3 2.4-1.5.4 1.1 2.7 12.6 5.2 25.5z" />
<path d="M196.7 79.1c-2.1.5-5 1.5-6.5 2.3-3.3 1.8-17.6 16.3-59.3 60.1-60 63.1-60.2 63.3-62.2 78.5-1.7 13.3 1.4 24.2 10 34.7 6.5 7.9 10.6 9.9 40.8 19.8 29.9 9.8 33 11 30.5 11.9-.8.3-8 3.1-16 6.1-8 3.1-19.7 7.5-26 9.9-20.7 7.9-40.3 15.7-45 18.1-2.6 1.3-7.2 5.1-10.2 8.4-6.6 7.1-7.2 8.7-17.9 47.6-19.1 69.1-21.3 78.3-20.3 84.8 1.6 9.6 7.1 16.9 16.3 21.7l4 2 233.6-.2 233.7-.3 3.3-3.7c5.2-5.6 5.3-7.6 1.6-22.3-5.9-23.2-13.2-47.9-15.3-51.3-3.3-5.3-7.3-7.5-30-16.3-12-4.6-21.8-8.6-21.8-8.9s6.6-2.7 14.8-5.4c16.2-5.3 19.9-7.5 23.8-14.3 3.4-5.6 3.7-13.7.8-20-1.9-4.2-32.4-37.2-52.7-57.1-9-8.8-9.6-9.2-13.8-9.2-2.4.1-5.4.6-6.5 1.3-1.8 1-17.1 16.5-46 46.6l-7.2 7.5-3.3-3.5c-7.4-7.7-11.5-9.6-79.6-35.9-9-3.5-16.3-6.7-16.3-7.1s12.5-4.8 27.8-9.8c16.3-5.3 29.6-10.2 32.2-11.9 6-3.8 13.3-11.8 16.3-17.8 7-13.9 5.4-33.5-3.8-45.3-7.2-9.1-103-109.8-110.2-115.7-5.8-4.8-13.2-6.7-19.6-5.3m34.8 84.4c5.5 1.4 12.2 3.3 14.9 4.2l4.8 1.5-.6 4.6c-1 7.4-11.3 36.9-16.3 46.8-2.5 5.1-7.6 13.4-11.3 18.5-5.4 7.6-7.7 9.9-12 12.1-6.8 3.6-12.8 3.7-19.7.3-5.8-2.9-9.3-6.8-18.2-20.5-8.2-12.5-13.2-23.1-17.5-37.1-5.1-17-6.4-23.8-4.6-24.9.8-.5 7.9-2.5 15.9-4.4 8.1-1.9 15.5-3.8 16.6-4 1.1-.3 10.1-.3 20-.1 15.1.4 19.6.8 28 3m-76.1 88.4 46.9 23.5 51.8-25.9c28.5-14.3 52.1-25.7 52.4-25.3.8.8-1.8 7-3.6 8.4-3.9 3.1-93.1 50.5-98.6 52.5-3.1 1-4.2.6-19-7.1-23.6-12.4-66.7-35.6-75.5-40.7-7.6-4.4-11.8-8.5-11.8-11.6 0-2.4 4.5-.3 57.4 26.2M418.5 318c12 1.2 19.5 3.5 19.5 5.9 0 3.7-7.2 22.7-11 29.2-5.4 9.1-9.9 12.9-15.2 12.9-3.7 0-4.7-.6-8.7-4.8-5.3-5.5-12-17.7-15-27.6-3.2-10.5-3.1-11.3 3.2-13.1 12.1-3.5 15-3.8 27.2-2.5M88.6 354.5c1.4 3.2 2.4 7.5 2.4 10.1 0 6-14 102.3-15.7 107.8-.5 1.8-.6 1.8-1.5.1-1.4-2.4-7.8-23.3-7.8-25.4-.1-3.8 18.5-98.1 19.2-98.1.5 0 2 2.5 3.4 5.5m239.8 43.3c5.3 26.8 9.6 49.4 9.6 50.1 0 2.1-9.2 28.1-9.9 28.1-.4 0-1.9-7.8-3.4-17.3-1.4-9.4-5.4-34.7-8.7-56l-6-38.8 3.4-7.4c1.9-4.1 3.9-7.5 4.4-7.5s5.3 21.9 10.6 48.8m136.5-43.3c-3 2.9-50.1 27.5-52.5 27.5-1.1 0-8.6-3.6-16.9-8.1-8.2-4.4-18.9-10.1-23.7-12.6-8-4.2-10.8-6.7-9.3-8.2.3-.3 11.7 5 25.3 11.8l24.7 12.3 27-13.5c25.2-12.6 31.2-14.8 25.4-9.2m-86.6 25.1c4.3 1.4 7.7 2.8 7.5 3s-3.4 1.5-7.1 2.9l-6.6 2.5-1.6-5.2c-.8-2.8-1.5-5.3-1.5-5.5 0-.6 1.7-.2 9.3 2.3m100.1 62.8 4.5 23.4-2.3 6.9c-2.9 8.4-2.5 9.8-7.6-24.5-3.7-25.3-3.8-26.5-2.2-29.8 1.5-3.2 1.7-3.3 2.4-1.5.4 1.1 2.7 12.6 5.2 25.5" />
</svg>
);
};

View File

@@ -23,7 +23,7 @@ const Poison = ({
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path d="M261.6 32.1 228 57.2v60.5l-6.7 1.2c-16.1 2.9-39.8 10.8-54.6 18.2-9.7 4.9-27.4 17-36.5 24.9-24.3 21.3-40.6 49-46.3 79-1.6 8.3-1.6 33.5 0 42 4.3 22.8 16.3 46.9 32.3 64.6 26 28.9 60 47.5 104 56.9l7.8 1.6.2 55.8.3 55.7 34-25.2 34-25.2.5-30.8.5-30.8 10.5-2.2c27-5.6 54.2-17.8 75.5-33.8 77.9-58.4 77.4-158.4-1.2-216.5-22.5-16.7-46.6-27.2-77-33.7l-8.3-1.7V62.3c0-30.8-.4-55.3-.9-55.3s-16 11.3-34.5 25.1zM228 262v89l-2.7-.6c-5.3-1.3-14.8-5.1-23.8-9.7-31-15.5-50.5-41.7-53.4-71.4-2.5-25.1 6.9-48.5 27-67.8 9.4-9 15.7-13.4 27.6-19.4 7.8-3.9 21.4-9 24.1-9.1.9 0 1.2 18.5 1.2 89zm76.1-86.9c33.2 10.8 58.9 34.5 68.6 63.4 2.5 7.4 2.7 9.2 2.7 23.5 0 14.2-.3 16.2-2.8 23.5-6.7 19.6-18.7 35-37.3 47.8-7.1 4.9-25.9 14-33 16l-5.3 1.5v-88.9c0-48.9.2-88.9.3-88.9.2 0 3.3.9 6.8 2.1z" />
<path d="M261.6 32.1 228 57.2v60.5l-6.7 1.2c-16.1 2.9-39.8 10.8-54.6 18.2-9.7 4.9-27.4 17-36.5 24.9-24.3 21.3-40.6 49-46.3 79-1.6 8.3-1.6 33.5 0 42 4.3 22.8 16.3 46.9 32.3 64.6 26 28.9 60 47.5 104 56.9l7.8 1.6.2 55.8.3 55.7 34-25.2 34-25.2.5-30.8.5-30.8 10.5-2.2c27-5.6 54.2-17.8 75.5-33.8 77.9-58.4 77.4-158.4-1.2-216.5-22.5-16.7-46.6-27.2-77-33.7l-8.3-1.7V62.3c0-30.8-.4-55.3-.9-55.3s-16 11.3-34.5 25.1M228 262v89l-2.7-.6c-5.3-1.3-14.8-5.1-23.8-9.7-31-15.5-50.5-41.7-53.4-71.4-2.5-25.1 6.9-48.5 27-67.8 9.4-9 15.7-13.4 27.6-19.4 7.8-3.9 21.4-9 24.1-9.1.9 0 1.2 18.5 1.2 89m76.1-86.9c33.2 10.8 58.9 34.5 68.6 63.4 2.5 7.4 2.7 9.2 2.7 23.5 0 14.2-.3 16.2-2.8 23.5-6.7 19.6-18.7 35-37.3 47.8-7.1 4.9-25.9 14-33 16l-5.3 1.5v-88.9c0-48.9.2-88.9.3-88.9.2 0 3.3.9 6.8 2.1" />
</svg>
);
};

View File

@@ -22,7 +22,7 @@ const ResetGame = ({
{title ? <title id={titleId}>{title}</title> : null}
<path
fill="currentColor"
d="M129.3 50.7C105.7 81.6 95 95.8 82.6 113c-14.3 19.7-16.7 25.2-14.6 33.2 2.5 9.4 9 14.2 21.3 15.8 8.2 1.1 116.4 3.7 117.2 2.8.3-.3-3.3-8.8-8-18.8s-8.8-19.3-9.1-20.5c-.5-2.1-.1-2.3 8.3-3.4 4.9-.6 20.3-1.6 34.2-2.2 65.4-2.7 102.7 6.4 133.2 32.4 31.4 26.8 48.8 75.9 44.9 126.8-6.7 87.6-61.2 133.4-155.3 130.6-45.4-1.3-78.1-13.8-103.7-39.6-23.5-23.8-39-60.5-41.9-99.4-.9-12-2-15.4-6.7-20-5.2-5.2-7.9-5.7-29.3-5.6-24 .1-27.9 1.2-32.1 9.5-1.6 3-2 5.9-2 13.9 0 35.9 12.4 76.8 32.8 108 34.1 52.5 88.1 87.3 152.2 98.2 16.3 2.8 57.2 2.5 73.5-.5 46.1-8.4 84.5-28.3 116.4-60.3 42.5-42.7 65-104 60.3-164.1-4.2-52.8-25-98.7-61.2-134.8-38.8-38.8-87.2-59.7-145-62.6-24.6-1.2-73.1 2.8-99.1 8.2-2.5.5-2.9-.2-10.9-17.1-4.6-9.6-8.7-17.5-9.1-17.5-.3 0-9.1 11.1-19.6 24.7z"
d="M129.3 50.7C105.7 81.6 95 95.8 82.6 113c-14.3 19.7-16.7 25.2-14.6 33.2 2.5 9.4 9 14.2 21.3 15.8 8.2 1.1 116.4 3.7 117.2 2.8.3-.3-3.3-8.8-8-18.8s-8.8-19.3-9.1-20.5c-.5-2.1-.1-2.3 8.3-3.4 4.9-.6 20.3-1.6 34.2-2.2 65.4-2.7 102.7 6.4 133.2 32.4 31.4 26.8 48.8 75.9 44.9 126.8-6.7 87.6-61.2 133.4-155.3 130.6-45.4-1.3-78.1-13.8-103.7-39.6-23.5-23.8-39-60.5-41.9-99.4-.9-12-2-15.4-6.7-20-5.2-5.2-7.9-5.7-29.3-5.6-24 .1-27.9 1.2-32.1 9.5-1.6 3-2 5.9-2 13.9 0 35.9 12.4 76.8 32.8 108 34.1 52.5 88.1 87.3 152.2 98.2 16.3 2.8 57.2 2.5 73.5-.5 46.1-8.4 84.5-28.3 116.4-60.3 42.5-42.7 65-104 60.3-164.1-4.2-52.8-25-98.7-61.2-134.8-38.8-38.8-87.2-59.7-145-62.6-24.6-1.2-73.1 2.8-99.1 8.2-2.5.5-2.9-.2-10.9-17.1-4.6-9.6-8.7-17.5-9.1-17.5-.3 0-9.1 11.1-19.6 24.7"
/>
</svg>
);

View File

@@ -21,8 +21,8 @@ const Skull = ({
>
{title ? <title id={titleId}>{title}</title> : null}
<g fill="currentColor">
<path d="M237.2 37.1c-30.6 2.9-64.8 15-89.4 31.6-12.2 8.2-31.7 23.4-38.3 30-15.2 14.9-24.6 33.8-27.5 55.1-4.5 32.9 10.8 64.5 38.7 79.8 16.3 8.9 22.3 12.7 28.1 18 15 13.5 23.5 31.4 24.9 52.3.8 11.5 3.2 17.9 8.9 23.1 8.6 7.9 4.4 7.5 73.4 7.5 60.6 0 61.6 0 66-2.1 10-4.8 14.7-12.3 16-25.7 1.3-12.5 1.8-15.2 4.2-22.7 3.9-12.1 11.9-24.4 21.2-32.7 5.5-4.9 8.1-6.5 25.3-16 16.4-9.1 26.1-19.1 33.9-34.8 5.6-11.4 7.4-18.5 8.1-30.8 1.5-26.6-9.6-54.2-29.4-72.7-8.8-8.3-27.3-22.7-38.3-29.8-35.8-23.3-82.1-34.3-125.8-30.1zm-46 72c15 3.2 26.2 13.8 28.7 27.3 1.7 9.2-2.6 18.2-14 29.7-14.1 14.1-28.2 21.9-40.9 22.6-6.6.4-7.9.2-11-1.9-7.5-5-10.9-17.2-11-39 0-14.7 1.9-20.6 8.9-27.6 10.1-10 24.7-14.2 39.3-11.1zm145 0c11.6 2.5 22.7 10.8 26.9 20.2 2.2 4.8 2.4 6.4 2.3 20.7-.1 22.2-3.1 32.2-11 37.1-2.9 1.8-4.6 2.1-10.8 1.7-6.2-.3-8.6-1-15.9-4.6-15.2-7.5-30.9-21.8-36.5-33.2-11.3-23.1 15.6-48.1 45-41.9zm-73.5 102.8c4.7 3.4 11.8 13.7 13.3 19.3 2 7.3-2 13.6-11.5 17.9-12.1 5.6-29.5-2.7-29.5-14.1 0-6.8 7.2-19 13.9-23.6 4.8-3.2 8.9-3.1 13.8.5z" />
<path d="M56.8 304.7c-1.4 1-3.6 3.1-4.9 4.6-5.1 6.6-8.2 25.8-4.7 29.3 2.9 2.9 19.8 7.1 67.8 16.9 36.1 7.4 79 17.5 79 18.7 0 .4-.6.8-1.4.8-2.3 0-73.5 23.6-95.6 31.7-20.8 7.6-40.7 16.4-44.8 19.9-1.6 1.3-2.7 4.1-3.8 9.4-2.9 14.3.2 20.8 12.5 25.5 6.3 2.4 7.3 2.5 11.7 1.4 6.2-1.6 18.9-6.3 48.4-18.2 56.7-22.9 114.7-42.6 140.7-47.7l5.8-1.2 24.5 8.5c13.5 4.7 45.2 16 70.5 25.2 78.6 28.6 95.9 34 101.1 31.6 3.2-1.4 5.4-6.7 5.4-12.8 0-9.6-3.3-16.3-10.8-22-4.8-3.6-8.7-4.9-27.7-8.8-7.1-1.5-15.9-3.8-19.5-5.2-3.6-1.3-17.1-6.5-30-11.5-12.9-4.9-30.4-11.4-38.8-14.4-8.4-2.9-15.8-5.7-16.4-6-.6-.4 4.2-2.2 10.8-4.1 11.6-3.3 27-7.7 58.3-16.9 17.6-5.2 48.9-16.6 54.1-19.6 8.8-5.2 14.8-13.3 17.4-23.3 1.3-5.3 1.4-6.2.1-8.2-2-3-5.3-3.7-13.4-2.9-19.7 1.8-89.3 19.4-175.4 44l-29.8 8.6-18.2-5.1c-20.2-5.6-63.5-18.8-91.2-27.9-18.1-5.9-52.3-16.5-62.5-19.4-9.6-2.7-16.1-3-19.2-.9z" />
<path d="M237.2 37.1c-30.6 2.9-64.8 15-89.4 31.6-12.2 8.2-31.7 23.4-38.3 30-15.2 14.9-24.6 33.8-27.5 55.1-4.5 32.9 10.8 64.5 38.7 79.8 16.3 8.9 22.3 12.7 28.1 18 15 13.5 23.5 31.4 24.9 52.3.8 11.5 3.2 17.9 8.9 23.1 8.6 7.9 4.4 7.5 73.4 7.5 60.6 0 61.6 0 66-2.1 10-4.8 14.7-12.3 16-25.7 1.3-12.5 1.8-15.2 4.2-22.7 3.9-12.1 11.9-24.4 21.2-32.7 5.5-4.9 8.1-6.5 25.3-16 16.4-9.1 26.1-19.1 33.9-34.8 5.6-11.4 7.4-18.5 8.1-30.8 1.5-26.6-9.6-54.2-29.4-72.7-8.8-8.3-27.3-22.7-38.3-29.8-35.8-23.3-82.1-34.3-125.8-30.1m-46 72c15 3.2 26.2 13.8 28.7 27.3 1.7 9.2-2.6 18.2-14 29.7-14.1 14.1-28.2 21.9-40.9 22.6-6.6.4-7.9.2-11-1.9-7.5-5-10.9-17.2-11-39 0-14.7 1.9-20.6 8.9-27.6 10.1-10 24.7-14.2 39.3-11.1m145 0c11.6 2.5 22.7 10.8 26.9 20.2 2.2 4.8 2.4 6.4 2.3 20.7-.1 22.2-3.1 32.2-11 37.1-2.9 1.8-4.6 2.1-10.8 1.7-6.2-.3-8.6-1-15.9-4.6-15.2-7.5-30.9-21.8-36.5-33.2-11.3-23.1 15.6-48.1 45-41.9m-73.5 102.8c4.7 3.4 11.8 13.7 13.3 19.3 2 7.3-2 13.6-11.5 17.9-12.1 5.6-29.5-2.7-29.5-14.1 0-6.8 7.2-19 13.9-23.6 4.8-3.2 8.9-3.1 13.8.5" />
<path d="M56.8 304.7c-1.4 1-3.6 3.1-4.9 4.6-5.1 6.6-8.2 25.8-4.7 29.3 2.9 2.9 19.8 7.1 67.8 16.9 36.1 7.4 79 17.5 79 18.7 0 .4-.6.8-1.4.8-2.3 0-73.5 23.6-95.6 31.7-20.8 7.6-40.7 16.4-44.8 19.9-1.6 1.3-2.7 4.1-3.8 9.4-2.9 14.3.2 20.8 12.5 25.5 6.3 2.4 7.3 2.5 11.7 1.4 6.2-1.6 18.9-6.3 48.4-18.2 56.7-22.9 114.7-42.6 140.7-47.7l5.8-1.2 24.5 8.5c13.5 4.7 45.2 16 70.5 25.2 78.6 28.6 95.9 34 101.1 31.6 3.2-1.4 5.4-6.7 5.4-12.8 0-9.6-3.3-16.3-10.8-22-4.8-3.6-8.7-4.9-27.7-8.8-7.1-1.5-15.9-3.8-19.5-5.2-3.6-1.3-17.1-6.5-30-11.5-12.9-4.9-30.4-11.4-38.8-14.4-8.4-2.9-15.8-5.7-16.4-6-.6-.4 4.2-2.2 10.8-4.1 11.6-3.3 27-7.7 58.3-16.9 17.6-5.2 48.9-16.6 54.1-19.6 8.8-5.2 14.8-13.3 17.4-23.3 1.3-5.3 1.4-6.2.1-8.2-2-3-5.3-3.7-13.4-2.9-19.7 1.8-89.3 19.4-175.4 44l-29.8 8.6-18.2-5.1c-20.2-5.6-63.5-18.8-91.2-27.9-18.1-5.9-52.3-16.5-62.5-19.4-9.6-2.7-16.1-3-19.2-.9" />
</g>
</svg>
);

View File

@@ -23,23 +23,23 @@ const BuyMeCoffee = ({
{title ? <title id={titleId}>{title}</title> : null}
<path
fill="#0D0C22"
d="m791.109 297.518-.878-.516-2.03-.619a4.833 4.833 0 0 0 2.908 1.135ZM803.896 388.891l-.98.275.98-.275ZM791.484 297.377a1.773 1.773 0 0 1-.366-.087 1.42 1.42 0 0 0 0 .244.738.738 0 0 0 .366-.157Z"
d="m791.109 297.518-.878-.516-2.03-.619a4.83 4.83 0 0 0 2.908 1.135M803.896 388.891l-.98.275zM791.484 297.377a1.8 1.8 0 0 1-.366-.087 1.4 1.4 0 0 0 0 .244.74.74 0 0 0 .366-.157"
/>
<path
fill="#0D0C22"
d="M791.113 297.529h.131v-.082l-.131.082ZM803.111 388.726l1.48-.843.551-.31.499-.533a8.447 8.447 0 0 0-2.53 1.686ZM793.669 299.515l-1.446-1.377-.98-.533a4.077 4.077 0 0 0 2.426 1.91ZM430.019 1186.18a7.55 7.55 0 0 0-2.943 2.27l.912-.58c.62-.57 1.497-1.24 2.031-1.69ZM641.187 1144.63c0-1.3-.636-1.06-.482 3.58 0-.37.155-.75.224-1.11.086-.83.155-1.64.258-2.47ZM619.284 1186.18a7.546 7.546 0 0 0-2.942 2.27l.912-.58c.619-.57 1.497-1.24 2.03-1.69ZM281.304 1196.06a6.299 6.299 0 0 0-3.097-1.45c.929.45 1.858.9 2.477 1.24l.62.21ZM247.841 1164.01a9.895 9.895 0 0 0-1.222-3.85c.474 1.23.87 2.5 1.187 3.78l.035.07Z"
d="M791.113 297.529h.131v-.082zM803.111 388.726l1.48-.843.551-.31.499-.533a8.5 8.5 0 0 0-2.53 1.686M793.669 299.515l-1.446-1.377-.98-.533a4.08 4.08 0 0 0 2.426 1.91M430.019 1186.18a7.55 7.55 0 0 0-2.943 2.27l.912-.58c.62-.57 1.497-1.24 2.031-1.69M641.187 1144.63c0-1.3-.636-1.06-.482 3.58 0-.37.155-.75.224-1.11.086-.83.155-1.64.258-2.47M619.284 1186.18a7.55 7.55 0 0 0-2.942 2.27l.912-.58c.619-.57 1.497-1.24 2.03-1.69M281.304 1196.06a6.3 6.3 0 0 0-3.097-1.45c.929.45 1.858.9 2.477 1.24zM247.841 1164.01a9.9 9.9 0 0 0-1.222-3.85c.474 1.23.87 2.5 1.187 3.78z"
/>
<path
fill="#FD0"
d="M472.623 590.836c-45.941 19.667-98.077 41.966-165.647 41.966a313.577 313.577 0 0 1-83.623-11.528l46.733 479.806a80.166 80.166 0 0 0 25.593 52.38 80.18 80.18 0 0 0 54.313 21.19s66.262 3.44 88.373 3.44c23.796 0 95.151-3.44 95.151-3.44 20.12 0 39.503-7.57 54.303-21.2a80.149 80.149 0 0 0 25.587-52.37l50.053-530.204c-22.368-7.639-44.943-12.715-70.391-12.715-44.014-.017-79.477 15.142-120.445 32.675Z"
d="M472.623 590.836c-45.941 19.667-98.077 41.966-165.647 41.966a313.6 313.6 0 0 1-83.623-11.528l46.733 479.806a80.17 80.17 0 0 0 25.593 52.38 80.18 80.18 0 0 0 54.313 21.19s66.262 3.44 88.373 3.44c23.796 0 95.151-3.44 95.151-3.44 20.12 0 39.503-7.57 54.303-21.2a80.15 80.15 0 0 0 25.587-52.37l50.053-530.204c-22.368-7.639-44.943-12.715-70.391-12.715-44.014-.017-79.477 15.142-120.445 32.675"
/>
<path
fill="#0D0C22"
d="m78.689 386.132.79.74.517.31a7.95 7.95 0 0 0-1.307-1.05Z"
d="m78.689 386.132.79.74.517.31a8 8 0 0 0-1.307-1.05"
/>
<path
fill="#0D0C22"
d="m879.567 341.849-7.037-35.497c-6.315-31.849-20.648-61.943-53.34-73.454-10.479-3.683-22.369-5.265-30.404-12.888-8.035-7.622-10.41-19.46-12.268-30.438-3.442-20.149-6.676-40.315-10.204-60.429-3.045-17.293-5.454-36.719-13.386-52.583-10.324-21.302-31.746-33.76-53.048-42.001a305.493 305.493 0 0 0-33.363-10.324C613.297 10.195 557.342 5.033 502.591 2.09a1376.266 1376.266 0 0 0-197.169 3.27c-48.797 4.439-100.193 9.807-146.564 26.687-16.948 6.177-34.413 13.593-47.3 26.687-15.813 16.088-20.975 40.969-9.43 61.031 8.208 14.247 22.111 24.313 36.857 30.972a298.948 298.948 0 0 0 59.844 19.478c57.297 12.664 116.642 17.636 175.178 19.753a1333.99 1333.99 0 0 0 194.433-6.35 1106.995 1106.995 0 0 0 47.817-6.314c18.738-2.874 30.765-27.376 25.242-44.445-6.608-20.406-24.365-28.321-44.444-25.241-2.96.464-5.902.894-8.862 1.324l-2.133.31c-6.803.861-13.605 1.663-20.407 2.409a1083.055 1083.055 0 0 1-42.259 3.717c-31.626 2.202-63.337 3.217-95.031 3.269-31.144 0-62.305-.878-93.38-2.925a1187.382 1187.382 0 0 1-42.431-3.545 1019.94 1019.94 0 0 1-19.219-2.168l-6.092-.774-1.324-.189-6.315-.912c-12.905-1.945-25.81-4.181-38.577-6.883a5.8 5.8 0 0 1 0-11.322h.241c11.064-2.357 22.213-4.37 33.397-6.125 3.729-.585 7.468-1.159 11.219-1.72h.103c7.003-.465 14.041-1.722 21.009-2.547A1336.183 1336.183 0 0 1 469.538 73.1c29.577.86 59.138 2.599 88.578 5.593a979.44 979.44 0 0 1 18.927 2.116c2.409.293 4.835.636 7.262.93l4.886.705a678.058 678.058 0 0 1 42.517 7.725c20.889 4.543 47.714 6.022 57.005 28.907 2.96 7.261 4.302 15.331 5.936 22.953l2.082 9.722c.055.174.095.353.121.533 4.921 22.942 9.848 45.884 14.78 68.826a12.608 12.608 0 0 1-2.006 9.871 12.612 12.612 0 0 1-8.593 5.254h-.138l-3.011.413-2.976.395c-9.43 1.228-18.87 2.375-28.322 3.442a1829.308 1829.308 0 0 1-55.938 5.506 1957.204 1957.204 0 0 1-111.55 6.074c-18.984.504-37.963.74-56.936.705a1975.736 1975.736 0 0 1-225.989-13.146c-8.122-.963-16.243-1.996-24.365-3.045 6.298.809-4.577-.62-6.779-.929a1447.245 1447.245 0 0 1-15.486-2.254c-17.327-2.599-34.55-5.799-51.843-8.604-20.906-3.441-40.9-1.72-59.81 8.604a86.994 86.994 0 0 0-36.012 37.338c-8.156 16.862-10.582 35.221-14.23 53.34C4 342.193-1.678 361.688.473 380.288 5.1 420.431 33.165 453.054 73.53 460.35c37.975 6.882 76.156 12.457 114.44 17.206a2114.804 2114.804 0 0 0 489.988 2.822 25.814 25.814 0 0 1 21.003 7.339 25.806 25.806 0 0 1 7.491 20.948l-3.82 37.132-23.091 225.077a178840.62 178840.62 0 0 1-31.126 302.866c-2.203 21.84-2.512 44.36-6.659 65.94-6.539 33.93-29.509 54.77-63.027 62.39a439.172 439.172 0 0 1-93.569 10.94c-34.912.19-69.806-1.36-104.718-1.17-37.27.21-82.918-3.23-111.687-30.97-25.277-24.36-28.77-62.51-32.211-95.5-4.588-43.67-9.136-87.331-13.645-130.989l-25.293-242.766-16.363-157.077c-.276-2.598-.551-5.162-.809-7.778-1.962-18.737-15.228-37.079-36.134-36.133-17.894.791-38.232 16.002-36.133 36.133l12.13 116.454 25.087 240.89a378681.11 378681.11 0 0 1 21.388 205.306c1.377 13.11 2.667 26.26 4.112 39.37 7.864 71.65 62.58 110.26 130.339 121.13 39.575 6.37 80.113 7.68 120.273 8.33 51.482.83 103.48 2.81 154.118-6.52 75.038-13.77 131.337-63.87 139.372-141.59 2.295-22.44 4.589-44.88 6.883-67.33 7.628-74.241 15.245-148.487 22.85-222.739l24.881-242.61 11.408-111.188a25.812 25.812 0 0 1 20.785-22.696c21.456-4.181 41.967-11.322 57.229-27.651 24.295-25.998 29.13-59.895 20.544-94.067ZM72.43 365.835c.327-.155-.275 2.649-.533 3.957-.052-1.979.051-3.734.533-3.957Zm2.082 16.105c.172-.121.688.568 1.222 1.394-.809-.758-1.325-1.325-1.24-1.394h.018Zm2.048 2.701c.74 1.256 1.135 2.048 0 0Zm4.112 3.338h.103c0 .121.19.241.258.362a2.666 2.666 0 0 0-.378-.362h.017Zm720.124-4.99c-7.708 7.33-19.323 10.737-30.8 12.441-128.704 19.099-259.283 28.769-389.399 24.502-93.121-3.183-185.261-13.525-277.453-26.55-9.034-1.273-18.824-2.925-25.036-9.584-11.7-12.561-5.953-37.854-2.908-53.03 2.788-13.903 8.122-32.434 24.657-34.413 25.81-3.028 55.783 7.863 81.318 11.735a1539.798 1539.798 0 0 0 92.57 11.27c132.18 12.045 266.58 10.169 398.175-7.45a1661.346 1661.346 0 0 0 71.699-11.236c21.216-3.803 44.737-10.943 57.556 11.029 8.792 14.97 9.962 34.998 8.603 51.912a28.942 28.942 0 0 1-8.999 19.374h.017Z"
d="m879.567 341.849-7.037-35.497c-6.315-31.849-20.648-61.943-53.34-73.454-10.479-3.683-22.369-5.265-30.404-12.888-8.035-7.622-10.41-19.46-12.268-30.438-3.442-20.149-6.676-40.315-10.204-60.429-3.045-17.293-5.454-36.719-13.386-52.583-10.324-21.302-31.746-33.76-53.048-42.001a306 306 0 0 0-33.363-10.324C613.297 10.195 557.342 5.033 502.591 2.09a1376 1376 0 0 0-197.169 3.27c-48.797 4.439-100.193 9.807-146.564 26.687-16.948 6.177-34.413 13.593-47.3 26.687-15.813 16.088-20.975 40.969-9.43 61.031 8.208 14.247 22.111 24.313 36.857 30.972a299 299 0 0 0 59.844 19.478c57.297 12.664 116.642 17.636 175.178 19.753a1334 1334 0 0 0 194.433-6.35 1107 1107 0 0 0 47.817-6.314c18.738-2.874 30.765-27.376 25.242-44.445-6.608-20.406-24.365-28.321-44.444-25.241-2.96.464-5.902.894-8.862 1.324l-2.133.31q-10.204 1.29-20.407 2.409a1083 1083 0 0 1-42.259 3.717c-31.626 2.202-63.337 3.217-95.031 3.269-31.144 0-62.305-.878-93.38-2.925a1187 1187 0 0 1-42.431-3.545 1020 1020 0 0 1-19.219-2.168l-6.092-.774-1.324-.189-6.315-.912c-12.905-1.945-25.81-4.181-38.577-6.883a5.8 5.8 0 0 1 0-11.322h.241c11.064-2.357 22.213-4.37 33.397-6.125q5.593-.878 11.219-1.72h.103c7.003-.465 14.041-1.722 21.009-2.547A1336 1336 0 0 1 469.538 73.1c29.577.86 59.138 2.599 88.578 5.593a979 979 0 0 1 18.927 2.116c2.409.293 4.835.636 7.262.93l4.886.705a678 678 0 0 1 42.517 7.725c20.889 4.543 47.714 6.022 57.005 28.907 2.96 7.261 4.302 15.331 5.936 22.953l2.082 9.722q.082.262.121.533 7.382 34.413 14.78 68.826a12.6 12.6 0 0 1-2.006 9.871 12.61 12.61 0 0 1-8.593 5.254h-.138l-3.011.413-2.976.395q-14.144 1.842-28.322 3.442a1829 1829 0 0 1-55.938 5.506 1957 1957 0 0 1-111.55 6.074q-28.476.757-56.936.705a1976 1976 0 0 1-225.989-13.146c-8.122-.963-16.243-1.996-24.365-3.045 6.298.809-4.577-.62-6.779-.929a1447 1447 0 0 1-15.486-2.254c-17.327-2.599-34.55-5.799-51.843-8.604-20.906-3.441-40.9-1.72-59.81 8.604a87 87 0 0 0-36.012 37.338c-8.156 16.862-10.582 35.221-14.23 53.34C4 342.193-1.678 361.688.473 380.288 5.1 420.431 33.165 453.054 73.53 460.35c37.975 6.882 76.156 12.457 114.44 17.206a2114.8 2114.8 0 0 0 489.988 2.822 25.81 25.81 0 0 1 21.003 7.339 25.8 25.8 0 0 1 7.491 20.948l-3.82 37.132-23.091 225.077a178841 178841 0 0 1-31.126 302.866c-2.203 21.84-2.512 44.36-6.659 65.94-6.539 33.93-29.509 54.77-63.027 62.39a439 439 0 0 1-93.569 10.94c-34.912.19-69.806-1.36-104.718-1.17-37.27.21-82.918-3.23-111.687-30.97-25.277-24.36-28.77-62.51-32.211-95.5q-6.882-65.504-13.645-130.989l-25.293-242.766-16.363-157.077c-.276-2.598-.551-5.162-.809-7.778-1.962-18.737-15.228-37.079-36.134-36.133-17.894.791-38.232 16.002-36.133 36.133l12.13 116.454 25.087 240.89a378681 378681 0 0 1 21.388 205.306c1.377 13.11 2.667 26.26 4.112 39.37 7.864 71.65 62.58 110.26 130.339 121.13 39.575 6.37 80.113 7.68 120.273 8.33 51.482.83 103.48 2.81 154.118-6.52 75.038-13.77 131.337-63.87 139.372-141.59 2.295-22.44 4.589-44.88 6.883-67.33q11.442-111.361 22.85-222.739l24.881-242.61 11.408-111.188a25.812 25.812 0 0 1 20.785-22.696c21.456-4.181 41.967-11.322 57.229-27.651 24.295-25.998 29.13-59.895 20.544-94.067M72.43 365.835c.327-.155-.275 2.649-.533 3.957-.052-1.979.051-3.734.533-3.957m2.082 16.105c.172-.121.688.568 1.222 1.394-.809-.758-1.325-1.325-1.24-1.394zm2.048 2.701c.74 1.256 1.135 2.048 0 0m4.112 3.338h.103c0 .121.19.241.258.362a2.7 2.7 0 0 0-.378-.362zm720.124-4.99c-7.708 7.33-19.323 10.737-30.8 12.441-128.704 19.099-259.283 28.769-389.399 24.502-93.121-3.183-185.261-13.525-277.453-26.55-9.034-1.273-18.824-2.925-25.036-9.584-11.7-12.561-5.953-37.854-2.908-53.03 2.788-13.903 8.122-32.434 24.657-34.413 25.81-3.028 55.783 7.863 81.318 11.735a1540 1540 0 0 0 92.57 11.27c132.18 12.045 266.58 10.169 398.175-7.45a1661 1661 0 0 0 71.699-11.236c21.216-3.803 44.737-10.943 57.556 11.029 8.792 14.97 9.962 34.998 8.603 51.912a28.94 28.94 0 0 1-8.999 19.374z"
/>
</svg>
);

View File

@@ -31,14 +31,14 @@ const KoFi = ({
<use x={97} y={83} href="#a" />
<path
fillRule="evenodd"
d="m521.5 52.4 410 .2 12.5 2.1c56.6 9.6 99.9 28 143.5 61.2 11.7 8.9 33.5 30.2 42.5 41.6 31 39.2 50.6 86.9 59.2 143.8 3 19.5 3.2 65 .5 83.2-7.3 48.4-24.3 89.7-52.3 127.3-10.5 13.9-35.9 39.8-49.4 50.2-52.3 40.3-116.3 63.2-188.8 67.6-10.4.6-11.3.8-11.6 2.8-.3 1.1-1.1 7.5-2 14.1-7.1 54-32.5 98.7-70.7 124.1-16.3 10.9-38.6 20.3-58.8 25-9.9 2.3-102.7 3.2-354.1 3.6-230.9.3-217.6.6-239.5-4.9-41.1-10.2-73.8-34.9-91.3-69-10.6-20.6-14.9-39-16.2-68.3-1.8-38.7-3.2-261.9-2.7-402 .5-138.6.6-141.7 2.6-149.2 7.2-27.3 27.3-47.5 52.6-52.8 2.2-.4 188.5-.7 414-.6zm-4.6 57.6H117.3l-2 2.2c-4.9 5.4-4.7-1.7-5.1 148.8-.4 142.7 1.1 364 2.8 395.5.7 13.5 1.4 18.8 3.5 26 8.7 29.8 29 48 63.2 56.7l8.8 2.3 216-.3c118.8-.2 243.9-.7 278-1.1l62-.8 8.5-2.8c40.5-13.2 64.2-41.6 73.5-87.9 2.5-12.7 4.5-32.6 4.5-45.1 0-13.1 5-22.4 15.1-28l5.4-3 28-.6c16.4-.4 33-1.4 40-2.3 64.9-8.9 116.3-33.4 156-74.7 32.8-34.1 52.5-77.3 57.6-126.8 1.5-14.3.6-46.8-1.6-61.1-8.5-55.1-29.1-98-62.6-130.6-11.8-11.4-17.7-16-33.9-26.7-33.1-21.6-66.1-33.5-106-38.2-10.8-1.3-67.3-1.5-412.1-1.5z"
d="m521.5 52.4 410 .2 12.5 2.1c56.6 9.6 99.9 28 143.5 61.2 11.7 8.9 33.5 30.2 42.5 41.6 31 39.2 50.6 86.9 59.2 143.8 3 19.5 3.2 65 .5 83.2-7.3 48.4-24.3 89.7-52.3 127.3-10.5 13.9-35.9 39.8-49.4 50.2-52.3 40.3-116.3 63.2-188.8 67.6-10.4.6-11.3.8-11.6 2.8-.3 1.1-1.1 7.5-2 14.1-7.1 54-32.5 98.7-70.7 124.1-16.3 10.9-38.6 20.3-58.8 25-9.9 2.3-102.7 3.2-354.1 3.6-230.9.3-217.6.6-239.5-4.9-41.1-10.2-73.8-34.9-91.3-69-10.6-20.6-14.9-39-16.2-68.3-1.8-38.7-3.2-261.9-2.7-402 .5-138.6.6-141.7 2.6-149.2 7.2-27.3 27.3-47.5 52.6-52.8 2.2-.4 188.5-.7 414-.6m-4.6 57.6H117.3l-2 2.2c-4.9 5.4-4.7-1.7-5.1 148.8-.4 142.7 1.1 364 2.8 395.5.7 13.5 1.4 18.8 3.5 26 8.7 29.8 29 48 63.2 56.7l8.8 2.3 216-.3c118.8-.2 243.9-.7 278-1.1l62-.8 8.5-2.8c40.5-13.2 64.2-41.6 73.5-87.9 2.5-12.7 4.5-32.6 4.5-45.1 0-13.1 5-22.4 15.1-28l5.4-3 28-.6c16.4-.4 33-1.4 40-2.3 64.9-8.9 116.3-33.4 156-74.7 32.8-34.1 52.5-77.3 57.6-126.8 1.5-14.3.6-46.8-1.6-61.1-8.5-55.1-29.1-98-62.6-130.6-11.8-11.4-17.7-16-33.9-26.7-33.1-21.6-66.1-33.5-106-38.2-10.8-1.3-67.3-1.5-412.1-1.5"
/>
<path
fillRule="evenodd"
d="M939.5 185.4c33.5 6.1 61.7 21.9 83.2 46.5 17.6 20.1 27.6 40.3 33.4 67 4.2 19.7 3.7 56.3-1.3 79.1-10.6 49.7-36.5 83.1-81.3 105-15.9 7.8-27.3 11.6-38.6 13-14.1 1.8-71.1 2.5-78.1 1.1-11-2.3-19.3-10.4-22.3-21.7-2.3-8.8-2.3-261 0-269.8 2.8-10.8 10-18.1 20.8-21.1 7.6-2.2 71.2-1.5 84.2.9zM903.8 241H891v199h9.3c5 0 14.3-.5 20.6-1 9.5-.9 12.8-1.7 20.6-4.9 41.1-16.9 59.5-47.6 59.5-99.2 0-23.9-3.7-38.9-13.3-53.7-14.5-22.4-36.2-36-62.7-39.2-4.6-.5-14.2-1-21.2-1z"
d="M939.5 185.4c33.5 6.1 61.7 21.9 83.2 46.5 17.6 20.1 27.6 40.3 33.4 67 4.2 19.7 3.7 56.3-1.3 79.1-10.6 49.7-36.5 83.1-81.3 105-15.9 7.8-27.3 11.6-38.6 13-14.1 1.8-71.1 2.5-78.1 1.1-11-2.3-19.3-10.4-22.3-21.7-2.3-8.8-2.3-261 0-269.8 2.8-10.8 10-18.1 20.8-21.1 7.6-2.2 71.2-1.5 84.2.9M903.8 241H891v199h9.3c5 0 14.3-.5 20.6-1 9.5-.9 12.8-1.7 20.6-4.9 41.1-16.9 59.5-47.6 59.5-99.2 0-23.9-3.7-38.9-13.3-53.7-14.5-22.4-36.2-36-62.7-39.2-4.6-.5-14.2-1-21.2-1"
/>
<path
d="M561.8 245.6c-28.7 5.2-60.3 22.1-83.5 44.7l-6.2 6-9.8-9.4c-20.6-19.7-46.1-33.2-74.3-39.4-11.6-2.5-36.4-3.1-49-1.1-41.8 6.6-73 31-84.8 66.1-6 17.6-7.4 42.4-3.8 63 4.9 27.5 17.3 56.3 32.4 75.3C302 475 359.3 531.2 433 598c37.5 34 35.1 32.4 42 29.3 7.5-3.4 96.9-88.3 144.9-137.7 38.7-39.7 49.3-52.6 59-71.7 11.8-23.2 16.7-44.3 15.8-68.7-.7-22.4-6.3-40.4-17.7-57.1-16.1-23.8-44.3-41.1-75.7-46.6-10.5-1.8-29.2-1.8-39.5.1z"
d="M561.8 245.6c-28.7 5.2-60.3 22.1-83.5 44.7l-6.2 6-9.8-9.4c-20.6-19.7-46.1-33.2-74.3-39.4-11.6-2.5-36.4-3.1-49-1.1-41.8 6.6-73 31-84.8 66.1-6 17.6-7.4 42.4-3.8 63 4.9 27.5 17.3 56.3 32.4 75.3C302 475 359.3 531.2 433 598c37.5 34 35.1 32.4 42 29.3 7.5-3.4 96.9-88.3 144.9-137.7 38.7-39.7 49.3-52.6 59-71.7 11.8-23.2 16.7-44.3 15.8-68.7-.7-22.4-6.3-40.4-17.7-57.1-16.1-23.8-44.3-41.1-75.7-46.6-10.5-1.8-29.2-1.8-39.5.1"
style={{
fill: '#ff504f',
}}

View File

@@ -0,0 +1,51 @@
import PropTypes from 'prop-types';
import { SVGProps } from 'react';
interface SVGRProps {
title?: string;
titleId?: string;
size?: string;
}
const Trinket = ({
title,
titleId,
...props
}: SVGProps<SVGSVGElement> & SVGRProps) => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width={props.size || 16}
height={props.size || 16}
fill="none"
viewBox="0 0 364 472"
aria-labelledby={titleId}
{...props}
>
{title ? <title id={titleId}>{title}</title> : null}
<path
fill="#78A083"
d="M40.536 302.159c-6.366-1.843-13.102 1.822-14.118 8.371-1.599 10.309-1.49 20.912.345 31.493 2.538 14.638 8.327 28.947 17.037 42.11s18.895 21.898 32.45 31.582 32.017 14.639 48.355 19.37 34.674 9.982 51.306 9.04c16.633-.942 29.437-2.571 43.833-9.043s26.935-15.473 36.901-26.49c7.205-7.964 12.964-16.868 17.121-26.436 2.641-6.078-1.095-12.775-7.461-14.619L153.42 334.848zM323.254 168.504c6.37 1.832 13.099-1.846 14.102-8.397 1.579-10.312 1.449-20.915-.405-31.493-2.566-14.633-8.382-28.93-17.117-42.077s-18.937-21.862-32.511-31.52-32.044-14.578-48.391-19.278-34.693-9.916-51.324-8.942-29.432 2.626-43.815 9.126-26.905 15.525-36.851 26.56c-7.19 7.978-12.93 16.893-17.07 26.468-2.629 6.084 1.12 12.774 7.489 14.605l112.946 32.474z"
/>
<path
fill="url(#a)"
d="M75.577 127.413c2.38-5.473 3.57-8.209 5.537-9.963a12 12 0 0 1 6.168-2.906c2.604-.399 5.472.425 11.207 2.074l216.593 62.274c5.73 1.648 8.595 2.471 10.588 4.191a12 12 0 0 1 3.683 5.732c.736 2.528.295 5.476-.588 11.372l-10.644 71.096c-.14.937-.211 1.405-.317 1.865q-.141.614-.347 1.209c-.154.446-.343.881-.721 1.749l-28.861 66.269c-2.382 5.469-3.573 8.204-5.538 9.956a12 12 0 0 1-6.168 2.904c-2.603.398-5.469-.426-11.202-2.074L48.371 290.886c-5.732-1.648-8.597-2.472-10.59-4.191a12 12 0 0 1-3.684-5.735c-.735-2.527-.293-5.476.592-11.374l10.654-71.027c.14-.934.21-1.401.316-1.86q.142-.612.346-1.206c.153-.445.342-.878.718-1.744z"
/>
<defs>
<radialGradient
id="a"
cx={0}
cy={0}
r={1}
gradientTransform="matrix(-25.05324 87.13566 -130.70377 -37.57994 181.959 234.953)"
gradientUnits="userSpaceOnUse"
>
<stop stopColor="#FFF4BE" />
<stop offset={1} stopColor="#FFC374" />
</radialGradient>
</defs>
</svg>
);
};
Trinket.propTypes = {
title: PropTypes.string,
};
export default Trinket;

View File

@@ -1,3 +1,4 @@
export { default as Close } from './Close';
export { default as Cog } from './Cog';
export { default as CommanderTax } from './CommanderTax';
export { default as Cross } from './Cross';
@@ -13,3 +14,4 @@ export { default as PartnerTax } from './PartnerTax';
export { default as Poison } from './Poison';
export { default as ResetGame } from './ResetGame';
export { default as Skull } from './Skull';
export { default as Trinket } from './Trinket';

5
src/Icons/svgs/Close.svg Normal file
View File

@@ -0,0 +1,5 @@
<svg width="52" height="52" viewBox="0 0 52 52" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M26 48C38.1503 48 48 38.1503 48 26C48 13.8497 38.1503 4 26 4C13.8497 4 4 13.8497 4 26C4 38.1503 13.8497 48 26 48ZM26 52C40.3594 52 52 40.3594 52 26C52 11.6406 40.3594 0 26 0C11.6406 0 0 11.6406 0 26C0 40.3594 11.6406 52 26 52Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.5858 15.5858C16.3668 14.8047 17.6332 14.8047 18.4142 15.5858L36.4142 33.5858C37.1953 34.3668 37.1953 35.6332 36.4142 36.4142C35.6332 37.1953 34.3668 37.1953 33.5858 36.4142L15.5858 18.4142C14.8047 17.6332 14.8047 16.3668 15.5858 15.5858Z" fill="currentColor"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M36.4142 15.5858C37.1953 16.3668 37.1953 17.6332 36.4142 18.4142L18.4142 36.4142C17.6332 37.1953 16.3668 37.1953 15.5858 36.4142C14.8047 35.6332 14.8047 34.3668 15.5858 33.5858L33.5858 15.5858C34.3668 14.8047 35.6332 14.8047 36.4142 15.5858Z" fill="currentColor"/>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@@ -1,30 +1,3 @@
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
width="524.000000pt" height="524.000000pt" viewBox="0 0 524.000000 524.000000"
preserveAspectRatio="xMidYMid meet">
<g transform="translate(0.000000,524.000000) scale(0.100000,-0.100000)"
fill="currentColor" stroke="none">
<path d="M2367 4905 c-288 -36 -514 -102 -754 -220 -686 -337 -1151 -972
-1269 -1735 -25 -160 -25 -500 0 -660 116 -750 572 -1383 1241 -1722 329 -167
652 -243 1035 -243 221 0 342 14 545 62 311 73 654 243 908 452 91 74 270 255
343 346 250 313 418 701 480 1110 25 164 25 483 0 650 -114 762 -586 1408
-1269 1740 -232 112 -421 171 -677 210 -145 22 -447 28 -583 10z m573 -454
c746 -132 1336 -702 1496 -1444 86 -403 35 -820 -146 -1193 -385 -794 -1264
-1204 -2125 -993 -887 218 -1488 1076 -1394 1990 73 715 567 1338 1244 1568
122 41 271 74 405 91 118 14 388 4 520 -19z"/>
<path d="M2465 4120 c-208 -20 -362 -86 -485 -211 -115 -116 -193 -264 -275
-520 -34 -106 -36 -119 -24 -144 20 -41 58 -65 114 -71 74 -9 92 10 178 190
149 308 257 419 460 473 84 23 298 22 386 -1 212 -55 346 -195 359 -376 8
-111 -23 -164 -205 -352 -260 -268 -380 -456 -442 -692 -30 -113 -46 -316 -36
-460 7 -113 9 -121 35 -148 26 -25 35 -28 95 -28 57 0 69 3 90 25 14 13 25 32
26 42 1 10 2 99 3 198 2 203 16 281 71 402 76 166 237 360 425 513 224 182
281 279 280 478 -1 198 -61 354 -179 465 -86 81 -148 118 -266 157 -165 54
-413 78 -610 60z"/>
<path d="M2524 1511 c-42 -18 -54 -50 -54 -139 0 -46 5 -92 10 -103 18 -33 64
-49 140 -49 126 0 155 33 149 169 -6 113 -19 125 -137 128 -48 2 -97 -1 -108
-6z"/>
</g>
<svg width="52" height="52" viewBox="0 0 52 52" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M26 48C38.1503 48 48 38.1503 48 26C48 13.8497 38.1503 4 26 4C13.8497 4 4 13.8497 4 26C4 38.1503 13.8497 48 26 48ZM26 52C40.3594 52 52 40.3594 52 26C52 11.6406 40.3594 0 26 0C11.6406 0 0 11.6406 0 26C0 40.3594 11.6406 52 26 52ZM21.8089 15.1299L21.5454 15.3022C19.0317 16.9458 18.874 20.5718 21.2356 22.4274C22.1042 23.1098 22.2551 24.3671 21.5726 25.2356C20.8902 26.1042 19.6329 26.2551 18.7644 25.5726C14.2506 22.0261 14.5519 15.0957 19.3564 11.9543L19.62 11.782C23.4958 9.24777 28.5042 9.24777 32.3801 11.782L33.1496 12.2851C37.7056 15.2641 37.9913 21.8361 33.711 25.1992C33.2888 25.5309 32.834 25.8191 32.3537 26.0592L31.8138 26.3292C29.4764 27.4978 28 29.8868 28 32.5C28 33.6046 27.1046 34.5 26 34.5C24.8954 34.5 24 33.6046 24 32.5C24 28.3717 26.3325 24.5977 30.0249 22.7515L30.5649 22.4815C30.8037 22.3621 31.0298 22.2188 31.2397 22.0539C33.3679 20.3817 33.2258 17.1141 30.9606 15.633L30.1911 15.1299C27.645 13.4651 24.355 13.4651 21.8089 15.1299ZM26 42C27.6569 42 29 40.6569 29 39C29 37.3431 27.6569 36 26 36C24.3431 36 23 37.3431 23 39C23 40.6569 24.3431 42 26 42Z" fill="currentColor"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1,11 @@
<svg width="364" height="472" viewBox="0 0 364 472" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M40.5356 302.159C34.1697 300.316 27.4337 303.981 26.418 310.53C24.8192 320.839 24.9288 331.442 26.7633 342.023C29.3011 356.661 35.0901 370.97 43.7998 384.133C52.5096 397.296 62.695 406.031 76.2507 415.715C89.8064 425.399 108.267 430.354 124.605 435.085C140.943 439.816 159.279 445.067 175.911 444.125C192.544 443.183 205.348 441.554 219.744 435.082C234.14 428.61 246.679 419.609 256.645 408.592C263.85 400.628 269.609 391.724 273.766 382.156C276.407 376.078 272.671 369.381 266.305 367.537L153.42 334.848L40.5356 302.159Z" fill="#78A083"/>
<path d="M323.254 168.504C329.624 170.336 336.353 166.658 337.356 160.107C338.935 149.795 338.805 139.192 336.951 128.614C334.385 113.981 328.569 99.6837 319.834 86.5374C311.099 73.3911 300.897 64.6755 287.323 55.0171C273.749 45.3588 255.279 40.4391 238.932 35.7391C222.585 31.0391 204.239 25.8229 187.608 26.7968C170.977 27.7707 158.176 29.4234 143.793 35.923C129.41 42.4225 116.888 51.4477 106.942 62.4834C99.7528 70.4607 94.0113 79.3756 89.8724 88.9514C87.2431 95.035 90.9911 101.725 97.3605 103.556L210.307 136.03L323.254 168.504Z" fill="#78A083"/>
<path d="M75.5773 127.413C77.9577 121.94 79.1479 119.204 81.1136 117.45C82.8455 115.905 84.9883 114.896 87.2823 114.544C89.8859 114.145 92.7537 114.969 98.4892 116.618L315.082 178.892C320.812 180.54 323.677 181.363 325.67 183.083C327.426 184.597 328.705 186.589 329.353 188.815C330.089 191.343 329.648 194.291 328.765 200.187L318.121 271.283C317.981 272.22 317.91 272.688 317.804 273.148C317.71 273.557 317.594 273.961 317.457 274.357C317.303 274.803 317.114 275.238 316.736 276.106L287.875 342.375C285.493 347.844 284.302 350.579 282.337 352.331C280.605 353.875 278.462 354.883 276.169 355.235C273.566 355.633 270.7 354.809 264.967 353.161L48.371 290.886C42.6395 289.238 39.7737 288.414 37.7805 286.695C36.0242 285.179 34.7448 283.188 34.097 280.96C33.3618 278.433 33.8042 275.484 34.6888 269.586L45.3425 198.559C45.4826 197.625 45.5527 197.158 45.6588 196.699C45.753 196.291 45.8686 195.889 46.0048 195.493C46.1582 195.048 46.3466 194.615 46.7235 193.749L75.5773 127.413Z" fill="url(#paint0_radial_14799_77884)"/>
<defs>
<radialGradient id="paint0_radial_14799_77884" cx="0" cy="0" r="1" gradientUnits="userSpaceOnUse" gradientTransform="translate(181.959 234.953) rotate(106.041) scale(90.6658 135.999)">
<stop stop-color="#FFF4BE"/>
<stop offset="1" stop-color="#FFC374"/>
</radialGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

@@ -3,13 +3,18 @@ import { useWakeLock } from 'react-screen-wake-lock';
import {
GlobalSettingsContext,
GlobalSettingsContextType,
SavedGame,
} from '../Contexts/GlobalSettingsContext';
import { useAnalytics } from '../Hooks/useAnalytics';
import {
InitialGameSettings,
InitialGameSettingsSchema,
Settings,
defaultInitialGameSettings,
defaultSettings,
initialGameSettingsSchema,
settingsSchema,
} from '../Types/Settings';
import { gte as semverGreaterThanOrEqual } from 'semver';
export const GlobalSettingsProvider = ({
children,
@@ -18,60 +23,131 @@ export const GlobalSettingsProvider = ({
}) => {
const analytics = useAnalytics();
const savedShowPlay = localStorage.getItem('showPlay');
const savedGameSettings = localStorage.getItem('initialGameSettings');
const savedSettings = localStorage.getItem('settings');
const localSavedGame = localStorage.getItem('savedGame');
const [savedGame, setCurrentGame] = useState<SavedGame>(
localSavedGame ? JSON.parse(localSavedGame) : null
);
const setCurrentGameAndLocalStorage = (savedGame: SavedGame) => {
if (!savedGame) {
setCurrentGame(savedGame);
localStorage.removeItem('savedGame');
return;
}
setCurrentGame(savedGame);
localStorage.setItem('savedGame', JSON.stringify(savedGame));
};
const savedPlaying = localStorage.getItem('playing');
const [playing, setPlaying] = useState<boolean>(
savedPlaying ? savedPlaying === 'true' : false
);
const setPlayingAndLocalStorage = (playing: boolean) => {
setPlaying(playing);
localStorage.setItem('playing', String(playing));
};
const savedPreStartComplete = localStorage.getItem('preStartComplete');
const [preStartCompleted, setPreStartCompleted] = useState<boolean>(
savedPreStartComplete ? savedPreStartComplete === 'true' : false
);
const savedShowPlay = localStorage.getItem('showPlay');
const [showPlay, setShowPlay] = useState<boolean>(
savedShowPlay ? savedShowPlay === 'true' : false
);
const setShowPlayAndLocalStorage = (showPlay: boolean) => {
setShowPlay(showPlay);
localStorage.setItem('showPlay', String(showPlay));
};
const savedSettings = localStorage.getItem('settings');
const [randomizingPlayer, setRandomizingPlayer] = useState<boolean>(
savedSettings
? Boolean(JSON.parse(savedSettings).preStartMode === 'random-king')
: true
);
const [settings, setSettings] = useState<Settings>(
savedSettings ? JSON.parse(savedSettings) : defaultSettings
);
const setSettingsAndLocalStorage = (settings: Settings) => {
setSettings(settings);
localStorage.setItem('settings', JSON.stringify(settings));
};
const savedGameSettings = localStorage.getItem('initialGameSettings');
const [initialGameSettings, setInitialGameSettings] =
useState<InitialGameSettings | null>(
savedGameSettings ? JSON.parse(savedGameSettings) : null
useState<InitialGameSettings>(
savedGameSettings
? JSON.parse(savedGameSettings)
: defaultInitialGameSettings
);
const [settings, setSettings] = useState<Settings>(
savedSettings
? JSON.parse(savedSettings)
: { goFullscreenOnStart: true, keepAwake: true, showStartingPlayer: true }
);
const setInitialGameSettingsAndLocalStorage = (
initialGameSettings: InitialGameSettings
) => {
setInitialGameSettings(initialGameSettings);
localStorage.setItem(
'initialGameSettings',
JSON.stringify(initialGameSettings)
);
};
const removeLocalStorage = async () => {
localStorage.removeItem('initialGameSettings');
localStorage.removeItem('players');
localStorage.removeItem('playing');
localStorage.removeItem('showPlay');
localStorage.removeItem('preStartComplete');
setPlaying(false);
setShowPlay(false);
setPreStartCompleted(false);
};
// Set settings if they are not valid
useEffect(() => {
if (savedGameSettings && JSON.parse(savedGameSettings).gridAreas) {
removeLocalStorage();
window.location.reload();
// If there are no saved settings, set default settings
if (!savedSettings) {
setSettingsAndLocalStorage(defaultSettings);
return;
}
const parsedSettings = settingsSchema.safeParse(JSON.parse(savedSettings));
// If saved settings are not valid, remove them
if (!parsedSettings.success) {
console.error('invalid settings, resetting to default settings');
setSettingsAndLocalStorage(defaultSettings);
return;
}
localStorage.setItem('settings', JSON.stringify(parsedSettings.data));
}, [settings, savedSettings]);
// Set initial game settings if they are not valid
useEffect(() => {
if (!savedGameSettings) {
setInitialGameSettingsAndLocalStorage(defaultInitialGameSettings);
return;
}
//parse existing game settings with zod schema
const parsedInitialGameSettings =
InitialGameSettingsSchema.safeParse(initialGameSettings);
initialGameSettingsSchema.safeParse(initialGameSettings);
if (!parsedInitialGameSettings.success) {
removeLocalStorage();
window.location.reload();
console.error('invalid game settings, resetting to default settings');
setInitialGameSettingsAndLocalStorage(defaultInitialGameSettings);
return;
}
localStorage.setItem(
'initialGameSettings',
JSON.stringify(initialGameSettings)
JSON.stringify(parsedInitialGameSettings.data)
);
}, [initialGameSettings, savedGameSettings]);
useEffect(() => {
localStorage.setItem('settings', JSON.stringify(settings));
}, [settings]);
const [isFullscreen, setIsFullscreen] = useState(false);
useEffect(() => {
@@ -87,6 +163,11 @@ export const GlobalSettingsProvider = ({
};
}, []);
const [isLatestVersion, setIsLatestVersion] = useState(false);
const [remoteVersion, setRemoteVersion] = useState<string | undefined>(
undefined
);
const { isSupported, release, released, request, type } = useWakeLock();
const active = settings.keepAwake;
@@ -135,6 +216,56 @@ export const GlobalSettingsProvider = ({
}
};
const setPreStartCompletedAndLocalStorage = (preStartComplete: boolean) => {
setPreStartCompleted(preStartComplete);
localStorage.setItem('playing', String(playing));
};
async function checkForNewVersion(source: 'settings' | 'start_menu') {
try {
const result = await fetch(
'https://api.github.com/repos/Vikeo/LifeTrinket/releases/latest',
{
headers: {
Authorization: `Bearer ${
import.meta.env.VITE_REPO_READ_ACCESS_TOKEN
}`,
Accept: 'application/vnd.github+json',
'X-GitHub-Api-Version': '2022-11-28',
},
}
);
const data = await result.json();
if (!data.name) {
setRemoteVersion(undefined);
setIsLatestVersion(false);
return;
}
setRemoteVersion(data.name);
const isLatest = semverGreaterThanOrEqual(
import.meta.env.VITE_APP_VERSION,
data.name
);
if (isLatest) {
setIsLatestVersion(true);
return;
}
analytics.trackEvent(`${source}_has_new_version`, {
remoteVersion: data.name,
installedVersion: import.meta.env.VITE_APP_VERSION,
});
setIsLatestVersion(false);
} catch (error) {
console.error('error getting latest version string', error);
}
}
return {
fullscreen: { isFullscreen, enableFullscreen, disableFullscreen },
wakeLock: {
@@ -147,24 +278,45 @@ export const GlobalSettingsProvider = ({
},
goToStart,
showPlay,
setShowPlay,
setShowPlay: setShowPlayAndLocalStorage,
playing,
setPlaying: setPlayingAndLocalStorage,
initialGameSettings,
setInitialGameSettings,
settings,
setSettings,
setSettings: setSettingsAndLocalStorage,
randomizingPlayer,
setRandomizingPlayer,
isPWA: window?.matchMedia('(display-mode: standalone)').matches,
preStartCompleted,
setPreStartCompleted: setPreStartCompletedAndLocalStorage,
savedGame,
saveCurrentGame: setCurrentGameAndLocalStorage,
version: {
installedVersion: import.meta.env.VITE_APP_VERSION,
remoteVersion,
isLatest: isLatestVersion,
checkForNewVersion,
},
};
}, [
active,
analytics,
initialGameSettings,
isFullscreen,
isSupported,
release,
active,
request,
settings,
showPlay,
type,
showPlay,
playing,
initialGameSettings,
settings,
randomizingPlayer,
preStartCompleted,
savedGame,
remoteVersion,
isLatestVersion,
analytics,
]);
return (

View File

@@ -7,6 +7,17 @@ import { InitialGameSettings } from '../Types/Settings';
export const PlayersProvider = ({ children }: { children: ReactNode }) => {
const savedPlayers = localStorage.getItem('players');
const savedStartingPlayerIndex = localStorage.getItem('startingPlayerIndex');
const [startingPlayerIndex, setStartingPlayerIndex] = useState<number>(
savedStartingPlayerIndex ? parseInt(savedStartingPlayerIndex) : -1
);
const setStartingPlayerIndexAndLocalStorage = (index: number) => {
setStartingPlayerIndex(index);
localStorage.setItem('startingPlayerIndex', String(index));
};
const [players, setPlayers] = useState<Player[]>(
savedPlayers ? JSON.parse(savedPlayers) : []
);
@@ -50,9 +61,7 @@ export const PlayersProvider = ({ children }: { children: ReactNode }) => {
return;
}
const startingPlayerIndex = Math.floor(
Math.random() * initialGameSettings.numberOfPlayers
);
const newStartingPlayerIndex = Math.floor(Math.random() * players.length);
players.forEach((player: Player) => {
player.commanderDamage.map((damage) => {
@@ -65,16 +74,9 @@ export const PlayersProvider = ({ children }: { children: ReactNode }) => {
});
player.lifeTotal = initialGameSettings.startingLifeTotal;
player.hasLost = false;
const isStartingPlayer = player.index === startingPlayerIndex;
player.isStartingPlayer = isStartingPlayer;
if (player.isStartingPlayer) {
player.showStartingPlayer = true;
}
player.isStartingPlayer = newStartingPlayerIndex === player.index;
updatePlayer(player);
});
@@ -87,8 +89,10 @@ export const PlayersProvider = ({ children }: { children: ReactNode }) => {
updatePlayer,
updateLifeTotal,
resetCurrentGame,
startingPlayerIndex,
setStartingPlayerIndex: setStartingPlayerIndexAndLocalStorage,
};
}, [players]);
}, [players, startingPlayerIndex]);
return (
<PlayersContext.Provider value={ctxValue}>

View File

@@ -6,7 +6,6 @@ export type Player = {
commanderDamage: CommanderDamage[];
extraCounters: ExtraCounter[];
isStartingPlayer: boolean;
showStartingPlayer: boolean;
hasLost: boolean;
isSide: boolean;
};
@@ -14,10 +13,10 @@ export type Player = {
export type PlayerSettings = {
rotation: Rotation;
useCommanderDamage: boolean;
usePartner?: boolean;
usePoison?: boolean;
useEnergy?: boolean;
useExperience?: boolean;
usePartner: boolean;
usePoison: boolean;
useEnergy: boolean;
useExperience: boolean;
};
type ExtraCounter = {

View File

@@ -12,10 +12,20 @@ export enum GameFormat {
TwoHeadedGiant = 'two-headed-giant',
}
export enum PreStartMode {
None = 'none',
RandomKing = 'random-king',
FingerGame = 'finger-game',
Trivia = 'trivia',
}
export type Settings = {
keepAwake: boolean;
showStartingPlayer: boolean;
showPlayerMenuCog: boolean;
goFullscreenOnStart: boolean;
preStartMode: PreStartMode;
showAnimations: boolean;
};
export type InitialGameSettings = {
@@ -26,10 +36,36 @@ export type InitialGameSettings = {
orientation: Orientation;
};
export const InitialGameSettingsSchema = z.object({
startingLifeTotal: z.number().min(1).max(200).default(20),
useCommanderDamage: z.boolean().default(false),
gameFormat: z.nativeEnum(GameFormat).optional(),
numberOfPlayers: z.number().min(1).max(6).default(2),
orientation: z.nativeEnum(Orientation).default(Orientation.Landscape),
export const initialGameSettingsSchema = z.object({
startingLifeTotal: z.number().min(1).max(200),
useCommanderDamage: z.boolean(),
gameFormat: z.nativeEnum(GameFormat),
numberOfPlayers: z.number().min(1).max(6),
orientation: z.nativeEnum(Orientation),
});
export const defaultInitialGameSettings = {
numberOfPlayers: 4,
startingLifeTotal: 40,
useCommanderDamage: true,
orientation: Orientation.Landscape,
gameFormat: GameFormat.Commander,
};
export const settingsSchema = z.object({
keepAwake: z.boolean(),
showStartingPlayer: z.boolean(),
showPlayerMenuCog: z.boolean(),
goFullscreenOnStart: z.boolean(),
preStartMode: z.nativeEnum(PreStartMode),
showAnimations: z.boolean(),
});
export const defaultSettings: Settings = {
goFullscreenOnStart: true,
keepAwake: true,
showStartingPlayer: true,
showPlayerMenuCog: true,
preStartMode: PreStartMode.None,
showAnimations: true,
};

View File

@@ -0,0 +1,87 @@
type RGBA = {
red: number;
green: number;
blue: number;
alpha: number;
};
export const hexToRgb = (hex: string): RGBA => {
hex = hex.replace(/^#/, '');
let alpha = 255;
if (hex.length === 8) {
alpha = parseInt(hex.slice(6, 8), 16);
hex = hex.substring(0, 6);
}
if (hex.length === 4) {
alpha = parseInt(hex.slice(3, 4).repeat(2), 16);
hex = hex.substring(0, 3);
}
if (hex.length === 3) {
hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
}
const num = parseInt(hex, 16);
const red = num >> 16;
const green = (num >> 8) & 255;
const blue = num & 255;
return { red, green, blue, alpha };
};
export const luminance = (a: number, b: number) => {
const l1 = Math.max(a, b);
const l2 = Math.min(a, b);
return (l1 + 0.05) / (l2 + 0.05);
};
export const rgbContrast = (a: RGBA, b: RGBA) => {
return luminance(relativeLuminance(a), relativeLuminance(b));
};
// calculate the color contrast ratio
export const checkContrast = (hexC1: string, hexC2: string) => {
const color1rgb = hexToRgb(hexC1);
const color2rgb = hexToRgb(hexC2);
const contrast = rgbContrast(color1rgb, color2rgb);
if (contrast >= 7) {
return 'AAA';
}
if (contrast >= 4.5) {
return 'AA';
}
if (contrast >= 3) {
return 'AA Large';
}
return 'Fail';
};
// red, green, and blue coefficients
const rc = 0.2126;
const gc = 0.7152;
const bc = 0.0722;
// low-gamma adjust coefficient
const lowc = 1 / 12.92;
function adjustGamma(input: number) {
return Math.pow((input + 0.055) / 1.055, 2.4);
}
export const relativeLuminance = (rgb: RGBA) => {
const rsrgb = rgb.red / 255;
const gsrgb = rgb.green / 255;
const bsrgb = rgb.blue / 255;
const r = rsrgb <= 0.03928 ? rsrgb * lowc : adjustGamma(rsrgb);
const g = gsrgb <= 0.03928 ? gsrgb * lowc : adjustGamma(gsrgb);
const b = bsrgb <= 0.03928 ? bsrgb * lowc : adjustGamma(bsrgb);
return r * rc + g * gc + b * bc;
};

View File

@@ -2,8 +2,18 @@
@tailwind components;
@tailwind utilities;
html {
overflow: hidden;
}
body {
overflow: auto;
}
html,
body {
height: 100%;
position: relative;
background-color: theme('colors.background.default');
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
@@ -21,6 +31,37 @@ code {
monospace;
}
// hide scrollbar globally
::-webkit-scrollbar {
display: none;
}
/* width */
::-webkit-scrollbar {
width: 10px;
}
/* Track */
::-webkit-scrollbar-track {
background-color: theme('colors.background.default');
}
/* Handle */
::-webkit-scrollbar-thumb {
background: theme('colors.primary.dark');
border-radius: 32px;
}
/* Handle on hover */
::-webkit-scrollbar-thumb:hover {
background: theme('colors.primary.main');
}
* {
scrollbar-width: none;
-ms-overflow-style: none;
}
@layer utilities {
.pointer-events-all {
pointer-events: all;
@@ -33,4 +74,158 @@ code {
-webkit-user-select: none;
-ms-user-select: none;
}
.show-scrollbar {
scrollbar-width: auto;
-ms-overflow-style: auto;
}
}
@keyframes background-orb {
0% {
bottom: 10%;
}
50% {
bottom: 90%;
}
100% {
bottom: 10%;
}
}
@keyframes move-right-left {
0% {
rotate: 0deg;
right: 10%;
}
25% {
right: 70%;
}
50% {
rotate: 360deg;
right: 10%;
}
75% {
right: 90%;
}
100% {
rotate: 0deg;
right: 10%;
}
}
.spotlight1 {
background: theme('colors.primary.dark');
position: fixed;
height: 100px;
width: 300px;
border-radius: 100%;
transform: translate(50%, 50%);
animation-duration: 30s, 60s;
animation-name: background-orb, move-right-left;
animation-iteration-count: infinite, infinite;
animation-direction: alternate, alternate;
animation-timing-function: ease-in-out;
animation-delay: -15s, -15s;
opacity: 0.8;
mix-blend-mode: screen;
filter: blur(125px);
}
.spotlight2 {
background: theme('colors.primary.dark');
position: fixed;
height: 300px;
width: 100px;
border-radius: 100%;
transform: translate(50%, 50%);
animation-duration: 60s, 120s;
animation-name: background-orb, move-right-left;
animation-iteration-count: infinite, infinite;
animation-direction: reverse, reverse;
animation-timing-function: ease-in-out;
opacity: 0.8;
mix-blend-mode: screen;
filter: blur(125px);
}
input[type='range'] {
-webkit-appearance: none;
transition: background 450ms ease-in;
margin: 10px 0;
width: 100%;
background: theme('colors.secondary.main');
}
input[type='range']:focus {
outline: none;
}
input[type='range']::-webkit-slider-runnable-track {
width: 100%;
height: 0.875rem;
cursor: pointer;
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
border-radius: 25px;
border: 0px solid #000101;
}
input[type='range']::-webkit-slider-thumb {
-webkit-appearance: none;
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
border: 0px solid #000000;
height: 20px;
width: 20px;
border-radius: 100px;
background: theme('colors.primary.main');
cursor: pointer;
margin-top: -3px;
}
input[type='range']::-moz-range-track {
width: 100%;
height: 0.875rem;
cursor: pointer;
animate: 0.2s;
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
border-radius: 25px;
border: 0px solid #000101;
}
input[type='range']::-moz-range-thumb {
box-shadow: 0px 0px 0px #000000, 0px 0px 0px #0d0d0d;
border: 0px solid #000000;
height: 20px;
width: 20px;
border-radius: 100px;
background: theme('colors.primary.main');
cursor: pointer;
}
input[type='range']::-ms-track {
width: 100%;
height: 0.875rem;
cursor: pointer;
animate: 0.2s;
background: transparent;
border-color: transparent;
border-width: 39px 0;
color: transparent;
}
input[type='range']::-ms-thumb {
height: 20px;
width: 20px;
border-radius: 100px;
background: theme('colors.primary.main');
cursor: pointer;
margin-top: -3px;
}

10
src/vite-env.d.ts vendored
View File

@@ -1 +1,11 @@
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly VITE_APP_VERSION: string;
readonly VITE_REPO_READ_ACCESS_TOKEN: string;
readonly VITE_FIREBASE_ANALYTICS_API_KEY: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}

View File

@@ -2,6 +2,78 @@
import tailwindcssGridAreas from '@savvywombat/tailwindcss-grid-areas';
import type { Config } from 'tailwindcss';
export const baseColors = {
primary: {
main: '#78A083',
dark: '#608069',
},
secondary: {
main: '#5D7965',
dark: '#4a6151',
},
background: {
default: '#35374B',
backdrop: 'rgba(0, 0, 0, 0.3)',
settings: 'rgba(0, 0, 0, 0.8)',
},
icons: {
dark: '#00000080',
light: '#F9FFE34f',
},
text: {
primary: '#F9FFE3',
secondary: '#c7ccb6',
},
common: {
white: '#F9FFE3',
black: '#000000',
},
lifeCounter: {
text: 'rgba(0, 0, 0, 0.4)',
lostWrapper: '#000000',
},
interface: {
loseButton: {
background: '#43434380',
},
recentDifference: {
background: 'rgba(255, 255, 255, 0.6);',
text: '#333333',
},
},
};
export const twGridTemplateAreas = {
onePlayerLandscape: ['player0 player0'],
onePlayerPortrait: ['player0', 'player0'],
twoPlayersOppositeLandscape: ['player0', 'player1'],
twoPlayersOppositePortrait: ['player0 player1', 'player0 player1'],
twoPlayersSameSideLandscape: ['player0 player1'],
threePlayers: ['player0 player0', 'player1 player2'],
threePlayersSide: [
'player0 player0 player0 player2',
'player1 player1 player1 player2',
],
fourPlayerPortrait: [
'player0 player1 player1 player1 player1 player3',
'player0 player2 player2 player2 player2 player3',
],
fourPlayer: ['player0 player1', 'player2 player3'],
fivePlayers: [
'player0 player0 player0 player1 player1 player1',
'player2 player2 player3 player3 player4 player4',
],
fivePlayersSide: [
'player0 player0 player0 player0 player0 player1 player1 player1 player1 player1 player2',
'player3 player3 player3 player3 player3 player4 player4 player4 player4 player4 player2',
],
sixPlayers: ['player0 player1 player2', 'player3 player4 player5'],
sixPlayersSide: [
'player0 player1 player1 player1 player1 player1 player1 player2 player2 player2 player2 player2 player2 player3',
'player0 player4 player4 player4 player4 player4 player4 player5 player5 player5 player5 player5 player5 player3',
],
};
/** @type {import('tailwindcss').Config} */
export default {
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
@@ -10,75 +82,8 @@ export default {
modalSm: '548px',
},
extend: {
gridTemplateAreas: {
onePlayerLandscape: ['player0 player0'],
onePlayerPortrait: ['player0', 'player0'],
twoPlayersOppositeLandscape: ['player0', 'player1'],
twoPlayersOppositePortrait: ['player0 player1', 'player0 player1'],
twoPlayersSameSideLandscape: ['player0 player1'],
threePlayers: ['player0 player0', 'player1 player2'],
threePlayersSide: [
'player0 player0 player0 player2',
'player1 player1 player1 player2',
],
fourPlayerPortrait: [
'player0 player1 player1 player1 player1 player3',
'player0 player2 player2 player2 player2 player3',
],
fourPlayer: ['player0 player1', 'player2 player3'],
fivePlayers: [
'player0 player0 player0 player1 player1 player1',
'player2 player2 player3 player3 player4 player4',
],
fivePlayersSide: [
'player0 player0 player0 player0 player0 player1 player1 player1 player1 player1 player2',
'player3 player3 player3 player3 player3 player4 player4 player4 player4 player4 player2',
],
sixPlayers: ['player0 player1 player2', 'player3 player4 player5'],
sixPlayersSide: [
'player0 player1 player1 player1 player1 player2 player2 player2 player2 player3',
'player0 player4 player4 player4 player4 player5 player5 player5 player5 player3',
],
},
colors: {
primary: {
main: '#3E7D78',
dark: '#2D5F5B',
},
secondary: {
main: '#284F4C',
dark: '#1B3B38',
},
background: {
default: '#08253B',
backdrop: 'rgba(0, 0, 0, 0.3)',
settings: 'rgba(20, 20, 0, 0.9)',
},
text: {
primary: '#F5F5F5',
secondary: '#76A6A5',
},
action: {
disabled: '#234A47',
},
common: {
white: '#F9FFE3',
black: '#000000',
},
lifeCounter: {
text: 'rgba(0, 0, 0, 0.4)',
lostWrapper: '#000000',
},
interface: {
loseButton: {
background: '#43434380',
},
recentDifference: {
background: 'rgba(255, 255, 255, 0.6);',
text: '#333333',
},
},
},
gridTemplateAreas: twGridTemplateAreas,
colors: baseColors,
keyframes: {
fadeOut: {
'0%': {
@@ -95,6 +100,9 @@ export default {
animation: {
fadeOut: 'fadeOut 3s 1s ease-out forwards',
},
fontSize: {
xxs: ['0.625rem', '1rem'],
},
},
},
plugins: [tailwindcssGridAreas],

View File

@@ -1,11 +1,9 @@
import react from '@vitejs/plugin-react-swc';
import { defineConfig } from 'vite';
import { VitePWA } from 'vite-plugin-pwa';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [
react(),
VitePWA({
registerType: 'autoUpdate',
workbox: {
@@ -21,7 +19,14 @@ export default defineConfig({
},
},
define: {
APP_VERSION: JSON.stringify(process.env.npm_package_version),
REPO_READ_ACCESS_TOKEN: JSON.stringify(process.env.REPO_READ_ACCESS_TOKEN),
'import.meta.env.VITE_APP_VERSION': JSON.stringify(
process.env.npm_package_version
),
VITE_REPO_READ_ACCESS_TOKEN: JSON.stringify(
process.env.VITE_REPO_READ_ACCESS_TOKEN
),
VITE_FIREBASE_ANALYTICS_API_KEY: JSON.stringify(
process.env.VITE_FIREBASE_ANALYTICS_API_KEY
),
},
});

8867
yarn.lock

File diff suppressed because it is too large Load Diff