feat: migrated home page

This commit is contained in:
TrèsAbhi committed 2024-09-14 13:24:24 -05:00
1 parent fcac6e36fd
commit 292df5f5d9
21 files changed
+457 -288

No files matched your search

+1
View File
@@ -11,6 +11,7 @@
"apcr",
"applypatches",
"artefacts",
"astrojs",
"atgm",
"Avearges",
"AYUV",
BIN
View File
Binary file not shown.
+48 -48
View File
@@ -1,49 +1,49 @@
export * from './assertSecret';
export * from './asset';
export * from './availableProvisions';
export * from './averageDefinitions';
export * from './camouflageDefinitions';
export * from './checkConsumableProvisionInclusivity';
export * from './coefficient';
export * from './consumableDefinitions';
export * from './context';
export * from './createDefaultSkills';
export * from './degressiveStat';
export * from './discoveredIdDefinitions';
export * from './emblemURL';
export * from './equipmentDefinitions';
export * from './eventManager';
export * from './fetchCdonLz4';
export * from './flagUserActivity';
export * from './gameDefinitions';
export * from './getArchivedLatestSeasonNumber';
export * from './getArchivedRatingInfo';
export * from './getArchivedRatingLeaderboard';
export * from './getArchivedRatingMidnightLeaderboard';
export * from './getTimeDaysAgo';
export * from './isExplosive';
export * from './linkBlitzAndDiscord';
export * from './mapDefinitions';
export * from './modelDefinitions';
export * from './normalizeBoundingBox';
export * from './parseBkni';
export * from './patientFetch';
export * from './patientFetchJSON';
export * from './progressiveStat';
export * from './provisionDefinitions';
export * from './resolveDpm';
export * from './resolvePenetrationCoefficient';
export * from './reviews';
export * from './skillDefinitions';
export * from './sum';
export * from './superCompress';
export * from './superDecompress';
export * from './tankDefinitions';
export * from './tankIcon';
export * from './tankNames';
export * from './unionBoundingBox';
export * from './uniqueGuns';
export * from './unwrapBlitzkitResponse';
export * from './votes';
export * from './withCORSProxy';
export * from './youtubers';
// export * from './asset';
// export * from './availableProvisions';
// export * from './averageDefinitions';
// export * from './camouflageDefinitions';
// export * from './checkConsumableProvisionInclusivity';
// export * from './coefficient';
// export * from './consumableDefinitions';
// export * from './context';
// export * from './createDefaultSkills';
// export * from './degressiveStat';
// export * from './discoveredIdDefinitions';
// export * from './emblemURL';
// export * from './equipmentDefinitions';
// export * from './eventManager';
// export * from './fetchCdonLz4';
// export * from './flagUserActivity';
// export * from './gameDefinitions';
// export * from './getArchivedLatestSeasonNumber';
// export * from './getArchivedRatingInfo';
// export * from './getArchivedRatingLeaderboard';
// export * from './getArchivedRatingMidnightLeaderboard';
// export * from './getTimeDaysAgo';
// export * from './isExplosive';
// export * from './linkBlitzAndDiscord';
// export * from './mapDefinitions';
// export * from './modelDefinitions';
// export * from './normalizeBoundingBox';
// export * from './parseBkni';
// export * from './patientFetch';
// export * from './patientFetchJSON';
// export * from './progressiveStat';
// export * from './provisionDefinitions';
// export * from './resolveDpm';
// export * from './resolvePenetrationCoefficient';
// export * from './reviews';
// export * from './skillDefinitions';
// export * from './sum';
// export * from './superCompress';
// export * from './superDecompress';
// export * from './tankDefinitions';
// export * from './tankIcon';
// export * from './tankNames';
// export * from './unionBoundingBox';
// export * from './uniqueGuns';
// export * from './unwrapBlitzkitResponse';
// export * from './votes';
// export * from './withCORSProxy';
// export * from './youtubers';
+9 -9
View File
@@ -1,11 +1,11 @@
export * from './blitz';
// export * from './blitz';
export * from './blitzkit';
export * from './blitzstars';
export * from './databases';
// export * from './blitzstars';
// export * from './databases';
export * from './imgur';
export * from './math';
export * from './patreon';
export * from './protobuf';
export * from './statistics';
export * from './streams';
export * from './types';
// export * from './math';
// export * from './patreon';
// export * from './protobuf';
// export * from './statistics';
// export * from './streams';
// export * from './types';
@@ -1,4 +1,4 @@
import { parse } from 'protobufjs';
import protobuf from 'protobufjs';
import average_definitions from '../../protos/average_definitions.proto';
import reviews from '../../protos/reviews.proto';
@@ -7,5 +7,5 @@ export type ProtoSource = keyof typeof protos;
const protos = { reviews, average_definitions };
export function lookupProtobufType(source: ProtoSource, type: string) {
return parse(protos[source]).root.lookupType(type);
return protobuf.parse(protos[source]).root.lookupType(type);
}
+4
View File
@@ -0,0 +1,4 @@
declare module '*.proto' {
const value: string;
export default value;
}
+1 -1
View File
@@ -9,13 +9,13 @@
},
"dependencies": {
"@radix-ui/themes": "^3.1.3",
"@radix-ui/react-icons": "^1.3.0",
"@blitzkit/core": "workspace:*",
"fuzzysort": "^2.0.4",
"@nivo/bar": "^0.87.0",
"three": "0.159.0",
"lodash": "^4.17.21",
"next": "^14.2.7",
"@radix-ui/react-icons": "^1.3.0",
"three-stdlib": "^2.32.2",
"@react-three/drei": "^9.111.5",
"@react-three/fiber": "^8.17.6",
@@ -1,128 +0,0 @@
import { assertSecret, imgur, ImgurSize } from '@blitzkit/core';
import { CaretRightIcon } from '@radix-ui/react-icons';
import {
Box,
Button,
Code,
Flex,
FlexProps,
Heading,
Text,
} from '@radix-ui/themes';
import { Link } from '../../components/Link';
import { Tool } from '../../constants/tools';
type ToolCardProps = FlexProps & {
tool: Tool;
};
export function ToolCard({ tool, style, ...props }: ToolCardProps) {
const size = tool.significant
? ImgurSize.HugeThumbnail
: ImgurSize.LargeThumbnail;
const unavailableOnBranch = tool.branches?.every(
(branch) => branch !== assertSecret(process.env.NEXT_PUBLIC_ASSET_BRANCH),
);
return (
<Flex
style={{
opacity: unavailableOnBranch ? 0.25 : 1,
position: 'relative',
borderRadius: 'var(--radius-2)',
overflow: 'hidden',
backgroundImage: `url(${imgur(tool.image, { format: 'jpeg', size })})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
height: tool.significant ? 'min(320px, 50vh)' : '256px',
...style,
}}
flexGrow={tool.significant ? undefined : '1'}
flexBasis={tool.significant ? undefined : { initial: undefined, sm: '0' }}
{...props}
>
<Link
disabled={unavailableOnBranch}
href={tool.href ?? `/tools/${tool.id}`}
target={tool.href ? '_blank' : undefined}
style={{
display: 'flex',
width: '100%',
height: '100%',
flexDirection: 'column',
textDecoration: 'none',
color: 'inherit',
}}
>
<Box
flexGrow="1"
style={{
backgroundImage: `url(${imgur(tool.image, { format: 'jpeg', size })})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
}}
/>
<Flex
px={{ initial: '6', md: tool.significant ? '8' : '6' }}
py={{ initial: '4', sm: tool.significant ? '6' : '4' }}
gap="4"
align="center"
justify="between"
width="100%"
direction={{ initial: 'column', xs: 'row' }}
style={{
backgroundColor: 'var(--color-panel-translucent)',
backdropFilter: 'blur(64px)',
WebkitBackdropFilter: 'blur(64px)',
}}
>
<Flex
direction="column"
justify="center"
align={{ initial: 'center', xs: 'start' }}
>
<Heading
align={{ initial: 'center', sm: 'left' }}
size={{ initial: '6', sm: tool.significant ? '7' : '5' }}
weight="medium"
>
{tool.title}
</Heading>
<Text
align={{ initial: 'center', sm: 'left' }}
size={{ initial: '3', sm: tool.significant ? '4' : '3' }}
color="gray"
>
{unavailableOnBranch ? (
<>
Unavailable on{' '}
<Code>
{assertSecret(process.env.NEXT_PUBLIC_ASSET_BRANCH)}
</Code>
</>
) : (
tool.description
)}
</Text>
</Flex>
{!unavailableOnBranch && (
<Button
highContrast={tool.button.highContrast}
size={{
initial: undefined,
sm: tool.significant ? '3' : undefined,
}}
color={tool.button.color}
style={{ cursor: 'inherit' }}
>
{tool.button.text}
<CaretRightIcon />
</Button>
)}
</Flex>
</Link>
</Flex>
);
}
+68 -68
View File
@@ -10,97 +10,97 @@ import {
sessionTool,
tankopediaTool,
tankPerformanceTool,
} from '../constants/tools';
} from '../../../website/src/constants/tools';
import { useAdExempt } from '../hooks/useAdExempt';
import { Hero } from './components/Hero';
import { Plugs } from './components/Plugs';
import { ToolCard } from './components/ToolCard';
import { ToolCard } from '../../../website/src/components/ToolCard';
export default function Page() {
const exempt = useAdExempt();
return (
<>
<Hero />
<Hero />
<Plugs />
<Plugs />
<Flex p="4" justify="center" gap="4">
<Flex maxWidth="1024px" flexGrow="1" gap="4" direction="column">
<ToolCard tool={tankopediaTool} />
<Flex p="4" justify="center" gap="4">
<Flex maxWidth="1024px" flexGrow="1" gap="4" direction="column">
<ToolCard tool={tankopediaTool} />
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
{/* <ToolCard tool={playerStatsTool} /> */}
<ToolCard tool={compareTool} />
<ToolCard tool={tankPerformanceTool} />
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
{/* <ToolCard tool={playerStatsTool} /> */}
<ToolCard tool={compareTool} />
<ToolCard tool={tankPerformanceTool} />
</Flex>
{!exempt && (
<Flex justify="center">
<AdMidSectionResponsive />
</Flex>
)}
{!exempt && (
<Flex justify="center">
<AdMidSectionResponsive />
</Flex>
)}
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
<ToolCard tool={sessionTool} />
{/* <ToolCard tool={embedTool} /> */}
<ToolCard tool={ratingTool} />
</Flex>
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
<ToolCard tool={sessionTool} />
{/* <ToolCard tool={embedTool} /> */}
<ToolCard tool={ratingTool} />
{!exempt && (
<Flex
justify="center"
display={{
initial: 'flex',
md: 'none',
}}
>
<AdMidSectionResponsive />
</Flex>
)}
{!exempt && (
<Flex
justify="center"
display={{
initial: 'flex',
md: 'none',
}}
>
<AdMidSectionResponsive />
</Flex>
)}
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
<ToolCard tool={discordTool} />
<ToolCard tool={moreTool} />
</Flex>
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
<ToolCard tool={discordTool} />
<ToolCard tool={moreTool} />
</Flex>
{!exempt && <AdMidSectionResponsive />}
{!exempt && <AdMidSectionResponsive />}
<Heading>Other cool projects</Heading>
<Heading>Other cool projects</Heading>
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
<ToolCard
tool={{
button: {
text: 'Analyze',
color: 'blue',
},
description: 'Rich historic average stats',
id: 'blitz-analysis',
image: 'j76YXGl',
title: 'BlitzAnalysis[]',
href: 'https://blitzanalysiz.com/',
}}
/>
<ToolCard
tool={{
button: {
color: 'purple',
text: 'Install',
highContrast: true,
},
image: 'zYrrYbR',
description: 'In-game session stats',
id: 'blitz-insider',
title: 'Blitz Insider',
href: 'https://discord.gg/UjWf9eGgtR',
}}
/>
</Flex>
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
<ToolCard
tool={{
button: {
text: 'Analyze',
color: 'blue',
},
description: 'Rich historic average stats',
id: 'blitz-analysis',
image: 'j76YXGl',
title: 'BlitzAnalysis[]',
href: 'https://blitzanalysiz.com/',
}}
/>
<ToolCard
tool={{
button: {
color: 'purple',
text: 'Install',
highContrast: true,
},
image: 'zYrrYbR',
description: 'In-game session stats',
id: 'blitz-insider',
title: 'Blitz Insider',
href: 'https://discord.gg/UjWf9eGgtR',
}}
/>
</Flex>
</Flex>
</Flex>
<div style={{ flex: 1 }} />
<div style={{ flex: 1 }} />
</>
);
}
@@ -4,7 +4,7 @@ import { imgur, ImgurSize } from '@blitzkit/core';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { ReactNode } from 'react';
import { TOOLS } from '../../constants/tools';
import { TOOLS } from '../../../../website/src/constants/tools';
export default function Layout({ children }: { children: ReactNode }) {
const pathname = usePathname();
@@ -30,7 +30,7 @@ import {
import { usePathname } from 'next/navigation';
import { Fragment, Suspense, useState } from 'react';
import { BRANCH_NAMES } from '../../app/components/Hero/constants';
import { homeTool, TOOLS } from '../../constants/tools';
import { homeTool, TOOLS } from '../../../../website/src/constants/tools';
import * as App from '../../stores/app';
import { Link } from '../Link';
import { PatreonIcon } from '../PatreonIcon';
+1 -1
View File
@@ -12,5 +12,5 @@
".next/types/**/*.ts",
"../../dist/website/types/**/*.ts",
"dist/website/types/**/*.ts"
]
, "../website/src/components/ToolCard.tsx", "../website/src/constants/tools.tsx" ]
}
+11 -2
View File
@@ -1,5 +1,14 @@
// @ts-check
import react from '@astrojs/react';
import { vanillaExtractPlugin } from '@vanilla-extract/vite-plugin';
import purgecss from 'astro-purgecss';
import { defineConfig } from 'astro/config';
// https://astro.build/config
export default defineConfig({});
export default defineConfig({
integrations: [react(), purgecss()],
vite: { plugins: [vanillaExtractPlugin()] },
devToolbar: { enabled: false },
outDir: '../../dist/website',
});
+13 -3
View File
@@ -1,7 +1,6 @@
{
"name": "@blitzkit/website",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"start": "astro dev",
@@ -10,8 +9,19 @@
"astro": "astro"
},
"dependencies": {
"astro": "^4.15.6",
"@astrojs/check": "^0.9.3",
"typescript": "^5.6.2"
"@astrojs/react": "^3.6.2",
"@blitzkit/core": "workspace:*",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/themes": "^3.1.3",
"@vanilla-extract/css": "^1.15.5",
"astro": "^4.15.6",
"astro-purgecss": "^4.6.0",
"purgecss": "^6.0.0",
"react": "^18.3.1",
"react-dom": "^18.3.1"
},
"devDependencies": {
"@vanilla-extract/vite-plugin": "^4.0.15"
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 692 B

-9
View File
@@ -1,9 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 128 128">
<path d="M50.4 78.5a75.1 75.1 0 0 0-28.5 6.9l24.2-65.7c.7-2 1.9-3.2 3.4-3.2h29c1.5 0 2.7 1.2 3.4 3.2l24.2 65.7s-11.6-7-28.5-7L67 45.5c-.4-1.7-1.6-2.8-2.9-2.8-1.3 0-2.5 1.1-2.9 2.7L50.4 78.5Zm-1.1 28.2Zm-4.2-20.2c-2 6.6-.6 15.8 4.2 20.2a17.5 17.5 0 0 1 .2-.7 5.5 5.5 0 0 1 5.7-4.5c2.8.1 4.3 1.5 4.7 4.7.2 1.1.2 2.3.2 3.5v.4c0 2.7.7 5.2 2.2 7.4a13 13 0 0 0 5.7 4.9v-.3l-.2-.3c-1.8-5.6-.5-9.5 4.4-12.8l1.5-1a73 73 0 0 0 3.2-2.2 16 16 0 0 0 6.8-11.4c.3-2 .1-4-.6-6l-.8.6-1.6 1a37 37 0 0 1-22.4 2.7c-5-.7-9.7-2-13.2-6.2Z" />
<style>
path { fill: #000; }
@media (prefers-color-scheme: dark) {
path { fill: #FFF; }
}
</style>
</svg>

Before

Width:  |  Height:  |  Size: 749 B

@@ -0,0 +1,136 @@
---
import { assertSecret, imgur, ImgurSize } from '@blitzkit/core';
import { CaretRightIcon } from '@radix-ui/react-icons';
import { Box, Button, Code, Flex, Heading, Link, Text } from '@radix-ui/themes';
import type { Tool } from '../constants/tools';
interface Props {
tool: Tool;
}
const { tool } = Astro.props;
const disabled = tool.branches?.every(
(branch) => branch !== assertSecret(process.env.PUBLIC_ASSET_BRANCH),
);
---
<style>
.container {
border-radius: var(--radius-2);
background-size: cover;
background-position: center;
height: 16rem;
&[data-disabled='true'] {
opacity: 0.25;
}
&[data-significant='true'] {
height: min(20rem, 50vh);
}
}
.link {
display: flex;
width: 100%;
height: 100%;
flex-direction: column;
color: inherit;
}
</style>
<Flex
data-disabled={disabled}
data-significant={tool.significant}
className="container"
position="relative"
overflow="hidden"
style={{
backgroundImage: `url(${imgur(tool.image, {
format: 'jpeg',
size: tool.significant
? ImgurSize.HugeThumbnail
: ImgurSize.LargeThumbnail,
})})`,
}}
flexGrow={tool.significant ? undefined : '1'}
flexBasis={tool.significant ? undefined : { initial: undefined, sm: '0' }}
>
<Link
className="link"
underline="none"
href={disabled ? '#' : (tool.href ?? `/tools/${tool.id}`)}
target={tool.href ? '_blank' : undefined}
>
<Box
flexGrow="1"
style={{
// backgroundImage: `url(${imgur(tool.image, { format: 'jpeg', size })})`,
backgroundSize: 'cover',
backgroundPosition: 'center',
}}
/>
<Flex
px={{ initial: '6', md: tool.significant ? '8' : '6' }}
py={{ initial: '4', sm: tool.significant ? '6' : '4' }}
gap="4"
align="center"
justify="between"
width="100%"
direction={{ initial: 'column', xs: 'row' }}
style={{
backgroundColor: 'var(--color-panel-translucent)',
backdropFilter: 'blur(64px)',
WebkitBackdropFilter: 'blur(64px)',
}}
>
<Flex
direction="column"
justify="center"
align={{ initial: 'center', xs: 'start' }}
>
<Heading
align={{ initial: 'center', sm: 'left' }}
size={{ initial: '6', sm: tool.significant ? '7' : '5' }}
weight="medium"
>
{tool.title}
</Heading>
<Text
align={{ initial: 'center', sm: 'left' }}
size={{ initial: '3', sm: tool.significant ? '4' : '3' }}
color="gray"
>
{
disabled ? (
<>
Unavailable on{' '}
<Code>{assertSecret(process.env.PUBLIC_ASSET_BRANCH)}</Code>
</>
) : (
tool.description
)
}
</Text>
</Flex>
{
!disabled && (
<Button
highContrast={tool.button.highContrast}
size={{
initial: undefined,
sm: tool.significant ? '3' : undefined,
}}
color={tool.button.color}
style={{ cursor: 'inherit' }}
>
{tool.button.text}
<CaretRightIcon />
</Button>
)
}
</Flex>
</Link>
</Flex>
@@ -1,5 +1,5 @@
import { Button } from '@radix-ui/themes';
import { ComponentProps } from 'react';
import type { ComponentProps } from 'react';
export interface Tool {
id: string;
@@ -0,0 +1,57 @@
---
import { Flex, Theme } from '@radix-ui/themes';
import '@radix-ui/themes/styles.css';
const { pathname } = Astro.url;
const isRoot = pathname === '/';
---
<style>
body {
margin: 0;
}
</style>
<!-- MIGRATION TODO: roboto flex font -->
<html lang="en">
<head>
{
isRoot && (
<>
<title>BlitzKit</title>
<meta
name="description"
content="🎉 Tools for everything World of Tanks Blitz"
/>
</>
)
}
<meta property="og:site_name" content="BlitzKit" />
<link rel="icon" type="image/x-icon" href="/favicon.png" />
<!-- <Party3 /> -->
</head>
<body>
<Theme
appearance="dark"
panelBackground="solid"
radius="full"
accentColor="amber"
suppressHydrationWarning
suppressContentEditableWarning
>
<Flex direction="column" minHeight="100vh">
<!-- {!hideNav && <Navbar />} -->
<!-- <Checks /> -->
<!-- <Suspense fallback={(<PageLoader />)}> -->
<slot />
<!-- </Suspense> -->
<!-- {!hideNav && <Footer />} -->
</Flex>
</Theme>
</body>
</html>
+98 -13
View File
@@ -1,16 +1,101 @@
---
import { Flex, Heading } from '@radix-ui/themes';
import ToolCard from '../components/ToolCard.astro';
import {
compareTool,
discordTool,
moreTool,
ratingTool,
sessionTool,
tankopediaTool,
tankPerformanceTool,
} from '../constants/tools';
import RootLayout from '../layouts/RootLayout.astro';
---
---
<RootLayout>
<!-- <Hero /> -->
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<meta name="viewport" content="width=device-width" />
<meta name="generator" content={Astro.generator} />
<title>Astro</title>
</head>
<body>
<h1>Astro</h1>
</body>
</html>
<!-- <Plugs /> -->
<Flex p="4" justify="center" gap="4">
<Flex maxWidth="1024px" flexGrow="1" gap="4" direction="column">
<ToolCard tool={tankopediaTool} />
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
{/* <ToolCard tool={playerStatsTool} /> */}
<ToolCard tool={compareTool} />
<ToolCard tool={tankPerformanceTool} />
</Flex>
<!-- {
!exempt && (
<Flex justify="center">
<AdMidSectionResponsive />
</Flex>
)
} -->
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
<ToolCard tool={sessionTool} />
{/* <ToolCard tool={embedTool} /> */}
<ToolCard tool={ratingTool} />
</Flex>
<!-- {
!exempt && (
<Flex
justify="center"
display={{
initial: 'flex',
md: 'none',
}}
>
<AdMidSectionResponsive />
</Flex>
)
} -->
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
<ToolCard tool={discordTool} />
<ToolCard tool={moreTool} />
</Flex>
<!-- {!exempt && <AdMidSectionResponsive />} -->
<Heading>Other cool projects</Heading>
<Flex gap="4" direction={{ initial: 'column', sm: 'row' }}>
<ToolCard
tool={{
button: {
text: 'Analyze',
color: 'blue',
},
description: 'Rich historic average stats',
id: 'blitz-analysis',
image: 'j76YXGl',
title: 'BlitzAnalysis[]',
href: 'https://blitzanalysiz.com/',
}}
/>
<ToolCard
tool={{
button: {
color: 'purple',
text: 'Install',
highContrast: true,
},
image: 'zYrrYbR',
description: 'In-game session stats',
id: 'blitz-insider',
title: 'Blitz Insider',
href: 'https://discord.gg/UjWf9eGgtR',
}}
/>
</Flex>
</Flex>
</Flex>
<div style={{ flex: 1 }}></div>
</RootLayout>
+5 -1
View File
@@ -1,3 +1,7 @@
{
"extends": "astro/tsconfigs/strict"
"extends": "astro/tsconfigs/strict",
"compilerOptions": {
"jsx": "react-jsx",
"jsxImportSource": "react"
}
}