Compare commits

...

21 Commits

Author SHA1 Message Date
Atash03 b612711883 fix: some types and UI changes 2026-03-27 15:07:59 +05:00
Atash03 cd3b3d3ad1 contact phone change 2026-02-26 16:46:21 +05:00
Atash03 ea4f0f5c65 fix: contact phones and svg favicon 2026-02-20 15:00:12 +05:00
Atash03 497d8596e7 fix: favicon 2026-02-12 02:19:55 +05:00
Atash03 f53753487f feat: migrate i18n to next-intl with locale-based URL routing
Replace manual cookie-based language system with next-intl v4. All routes
now use /ru and /en URL prefixes, translation strings live in JSON files,
and components use useTranslations/getTranslations instead of useLang/Redux.
2026-02-12 01:45:37 +05:00
Batyr 7940c7b2f4 style 2025-12-04 14:18:22 +05:00
Batyr c1f4e13827 style: changed design 2025-12-04 14:18:17 +05:00
Batyr ad98db48fb Merge branch 'main' of ssh://216.250.8.93:2018/~/repos/turkmen-expo 2025-12-03 15:36:29 +05:00
Batyr 22daef2c73 Merge branch 'main' of https://github.com/aw-batyr/turkmen-expo 2025-12-03 15:27:42 +05:00
Batyr dbf2291534 change 2025-12-03 14:32:15 +05:00
Batyr efae1916f8 added 2025 2025-11-22 21:37:30 +05:00
Batyr ec34e10c09 added pt for page 2025-11-21 16:33:09 +05:00
Batyr b76467e111 added pt for page 2025-11-21 16:03:10 +05:00
Batyr c9f5fea14f added pt for pages 2025-11-21 15:58:32 +05:00
Batyr 88c1a2f935 added reviews 2025-11-21 15:53:33 +05:00
Batyr 0f4cd2b374 video added into hero banner 2025-11-21 15:28:26 +05:00
Batyr e1dbfa0720 renamed 2025-11-21 12:06:13 +05:00
Batyr b0f094000a renamed 2025-11-21 11:56:33 +05:00
Batyr fff9e63d43 renamed 2025-11-21 11:16:42 +05:00
Batyr 53441d56e0 Add links to events in Events component 2025-11-21 09:08:24 +05:00
Batyr a11de84ae5 Update layout and styles for HomePage and BurgerMenu components 2025-11-06 11:55:45 +05:00
78 changed files with 3043 additions and 1220 deletions

3
.gitignore vendored
View File

@ -33,3 +33,6 @@ yarn-error.log*
# typescript # typescript
*.tsbuildinfo *.tsbuildinfo
next-env.d.ts next-env.d.ts
.claude
.agents

View File

@ -1,16 +1,15 @@
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { getAbout } from "@/services/about"; import { getAbout } from "@/services/about";
import { cookies } from "next/headers"; import { getLocale, getTranslations } from "next-intl/server";
export default async function AboutPage() { export default async function AboutPage() {
const lang = cookies().get("lang")?.value ?? "ru"; const lang = await getLocale();
const t = await getTranslations("about");
const data = await getAbout(lang); const data = await getAbout(lang);
const aboutText = lang === "en" ? "About us" : "Коротко о нас";
return ( return (
<LayoutWithSidebar second={aboutText} title={aboutText}> <LayoutWithSidebar second={t("title")} title={t("title")}>
<div <div
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: data, __html: data,

View File

@ -3,7 +3,7 @@ import React from "react";
const CompanyLayout = ({ children }: { children: React.ReactNode }) => { const CompanyLayout = ({ children }: { children: React.ReactNode }) => {
return ( return (
<div className="lg:bg-blueBg bg-transparent"> <div className="lg:bg-blueBg bg-transparent pt-12">
<div className="container"> <div className="container">
<div className="flex w-full"> <div className="flex w-full">
<aside className="w-[25%] hidden tab:block"> <aside className="w-[25%] hidden tab:block">

View File

@ -5,26 +5,28 @@ import Image from "next/image";
import { GreenBtn } from "@/components/ui/Buttons"; import { GreenBtn } from "@/components/ui/Buttons";
import { useAppDispatch, useAppSelector } from "@/redux/hooks"; import { useAppDispatch } from "@/redux/hooks";
import { selectHeader, setShowInput } from "@/redux/slices/headerSlice"; import { setShowInput } from "@/redux/slices/headerSlice";
import { baseAPI } from "@/lib/API"; import { baseAPI } from "@/lib/API";
import { NewsPageType } from "@/lib/types/NewsPage.type"; import { NewsPageType } from "@/lib/types/NewsPage.type";
import Link from "next/link"; import { Link } from "@/i18n/navigation";
import { BreadCrumbs } from "@/components/ui/bread-crumbs"; import { BreadCrumbs } from "@/components/ui/bread-crumbs";
import { Title } from "@/components/ui/title"; import { Title } from "@/components/ui/title";
import Loader from "@/components/ui/Loader"; import Loader from "@/components/ui/Loader";
import { useLocale, useTranslations } from "next-intl";
export default function SingleNewsPage({ params }: { params: { id: string } }) { export default function SingleNewsPage({ params }: { params: { id: string } }) {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const locale = useLocale();
const t = useTranslations("news");
const { activeLang } = useAppSelector(selectHeader);
const [newsItemData, setNewsItemData] = React.useState<NewsPageType>(); const [newsItemData, setNewsItemData] = React.useState<NewsPageType>();
const fetchData = async () => { const fetchData = async () => {
try { try {
const response = await fetch(`${baseAPI}news/${params.id}`, { const response = await fetch(`${baseAPI}news/${params.id}`, {
headers: { headers: {
"Accept-Language": activeLang.localization, "Accept-Language": locale,
}, },
}); });
@ -43,11 +45,11 @@ export default function SingleNewsPage({ params }: { params: { id: string } }) {
React.useEffect(() => { React.useEffect(() => {
fetchData(); fetchData();
dispatch(setShowInput(false)); dispatch(setShowInput(false));
}, [activeLang.localization]); }, [locale]);
return ( return (
<div className="section-mb w-full"> <div className="section-mb w-full">
<BreadCrumbs second="Новости" path="/news" third="Статья" /> <BreadCrumbs second={t("title")} path="/news" third={t("article")} />
{newsItemData ? ( {newsItemData ? (
<div className="mb-5"> <div className="mb-5">
<Title text={newsItemData.data.title} /> <Title text={newsItemData.data.title} />
@ -84,7 +86,7 @@ export default function SingleNewsPage({ params }: { params: { id: string } }) {
</div> </div>
<Link href="/news" className="flex justify-center"> <Link href="/news" className="flex justify-center">
<GreenBtn text="Все новости" px /> <GreenBtn text={t("allNews")} px />
</Link> </Link>
</div> </div>
); );

View File

@ -2,9 +2,7 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { useLang } from "@/utils/useLang"; import { useLocale, useTranslations } from "next-intl";
import { useAppSelector } from "@/redux/hooks";
import { selectHeader } from "@/redux/slices/headerSlice";
import { NewsData } from "@/lib/types/NewsData.type"; import { NewsData } from "@/lib/types/NewsData.type";
import { baseAPI } from "@/lib/API"; import { baseAPI } from "@/lib/API";
import Loader from "@/components/ui/Loader"; import Loader from "@/components/ui/Loader";
@ -12,12 +10,13 @@ import clsx from "clsx";
import { Card } from "@/components/shared/Card"; import { Card } from "@/components/shared/Card";
import { BorderBtn } from "@/components/ui/Buttons"; import { BorderBtn } from "@/components/ui/Buttons";
import { Pagination } from "@/components/ui/Pagination"; import { Pagination } from "@/components/ui/Pagination";
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
const News = () => { const News = () => {
const { activeLang } = useAppSelector(selectHeader); const locale = useLocale();
const t = useTranslations("news");
const tCommon = useTranslations("common");
const menu = ["Новости", "СМИ о нас"];
const [current, setCurrent] = React.useState<number>(1); const [current, setCurrent] = React.useState<number>(1);
const [perPage, setPerPage] = React.useState<number>(6); const [perPage, setPerPage] = React.useState<number>(6);
const [totalNews, setTotalNews] = React.useState<number>(0); const [totalNews, setTotalNews] = React.useState<number>(0);
@ -36,7 +35,7 @@ const News = () => {
`${baseAPI}news?page=${current}&per_page=${perPage}`, `${baseAPI}news?page=${current}&per_page=${perPage}`,
{ {
headers: { headers: {
"Accept-Language": activeLang.localization, "Accept-Language": locale,
}, },
} }
); );
@ -57,7 +56,7 @@ const News = () => {
React.useEffect(() => { React.useEffect(() => {
fetchNews(); fetchNews();
}, [current, perPage, activeLang.localization]); }, [current, perPage, locale]);
const handleOnClickButton = () => { const handleOnClickButton = () => {
setPerPage((prev) => prev + 6); setPerPage((prev) => prev + 6);
@ -70,23 +69,13 @@ const News = () => {
return ( return (
<div> <div>
<LayoutWithSidebar <LayoutWithSidebar
title={useLang("News", "Новости", activeLang.localization)} title={t("title")}
second={useLang("News", "Новости", activeLang.localization)} second={t("title")}
cursor={false} cursor={false}
> >
<div> <div>
<div className="flex flex-col"> <div className="flex flex-col">
<div className="flex flex-col"> <div className="flex flex-col">
<div className="hidden sm:flex justify-between items-center pb-[5px] ">
<div className="pointer-events-none opacity-0 flex items-center gap-5">
{menu.map((item, i) => (
<p key={i} className="cursor-pointer leading-[130%]">
{item}
</p>
))}
</div>
</div>
<div <div
className={clsx( className={clsx(
"mb-[48px] lg:mb-[108px]", "mb-[48px] lg:mb-[108px]",
@ -112,7 +101,7 @@ const News = () => {
<div className="hidden sm:flex flex-col gap-6 w-full max-w-[180px] mx-auto justify-center items-center"> <div className="hidden sm:flex flex-col gap-6 w-full max-w-[180px] mx-auto justify-center items-center">
{newsData && totalNews > perPage && perPage >= totalNews && ( {newsData && totalNews > perPage && perPage >= totalNews && (
<div onClick={handleOnClickButton}> <div onClick={handleOnClickButton}>
<BorderBtn px text={"Показать ещё"} /> <BorderBtn px text={tCommon("showMore")} />
</div> </div>
)} )}

View File

@ -1,8 +1,10 @@
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { getServices } from "@/services/services"; import { getServices } from "@/services/services";
import { getLocale } from "next-intl/server";
export default async function AdvertisingPage() { export default async function AdvertisingPage() {
const { data } = await getServices(); const lang = await getLocale();
const { data } = await getServices(lang);
return ( return (
<LayoutWithSidebar <LayoutWithSidebar

View File

@ -1,8 +1,10 @@
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { getServices } from "@/services/services"; import { getServices } from "@/services/services";
import { getLocale } from "next-intl/server";
export default async function AdvertisingPage() { export default async function AdvertisingPage() {
const data = await getServices(); const lang = await getLocale();
const data = await getServices(lang);
return ( return (
<LayoutWithSidebar <LayoutWithSidebar
@ -12,7 +14,7 @@ export default async function AdvertisingPage() {
<div <div
className="select-inner" className="select-inner"
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: data ? data.data[1].content : "", __html: data?.data ? data.data[1].content : "",
}} }}
/> />
</LayoutWithSidebar> </LayoutWithSidebar>

View File

@ -1,8 +1,10 @@
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { getServices } from "@/services/services"; import { getServices } from "@/services/services";
import { getLocale } from "next-intl/server";
export default async function BusinessTours() { export default async function BusinessTours() {
const { data } = await getServices(); const lang = await getLocale();
const { data } = await getServices(lang);
return ( return (
<LayoutWithSidebar <LayoutWithSidebar

View File

@ -1,8 +1,10 @@
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { getServices } from "@/services/services"; import { getServices } from "@/services/services";
import { getLocale } from "next-intl/server";
export default async function CertificationPage() { export default async function CertificationPage() {
const data = await getServices(); const lang = await getLocale();
const data = await getServices(lang);
return ( return (
<LayoutWithSidebar <LayoutWithSidebar
@ -12,7 +14,7 @@ export default async function CertificationPage() {
<div <div
className="select-inner" className="select-inner"
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: data ? data.data[3].content : "", __html: data?.data ? data.data[3].content : "",
}} }}
/> />
</LayoutWithSidebar> </LayoutWithSidebar>

View File

@ -1,8 +1,10 @@
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { getServices } from "@/services/services"; import { getServices } from "@/services/services";
import { getLocale } from "next-intl/server";
export default async function ForwardingPage() { export default async function ForwardingPage() {
const data = await getServices(); const lang = await getLocale();
const data = await getServices(lang);
return ( return (
<LayoutWithSidebar <LayoutWithSidebar
@ -12,7 +14,7 @@ export default async function ForwardingPage() {
<div <div
className="select-inner" className="select-inner"
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: data ? data.data[4].content : "", __html: data?.data ? data.data[4].content : "",
}} }}
/> />
</LayoutWithSidebar> </LayoutWithSidebar>

View File

@ -1,8 +1,10 @@
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { getServices } from "@/services/services"; import { getServices } from "@/services/services";
import { getLocale } from "next-intl/server";
export default async function HybridsPage() { export default async function HybridsPage() {
const data = await getServices(); const lang = await getLocale();
const data = await getServices(lang);
return ( return (
<LayoutWithSidebar <LayoutWithSidebar
@ -12,7 +14,7 @@ export default async function HybridsPage() {
<div <div
className="select-inner" className="select-inner"
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: data ? data.data[2].content : "", __html: data?.data ? data.data[2].content : "",
}} }}
/> />
</LayoutWithSidebar> </LayoutWithSidebar>

View File

@ -1,8 +1,10 @@
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { getServices } from "@/services/services"; import { getServices } from "@/services/services";
import { getLocale } from "next-intl/server";
export default async function MeetingsPage() { export default async function MeetingsPage() {
const data = await getServices(); const lang = await getLocale();
const data = await getServices(lang);
return ( return (
<LayoutWithSidebar <LayoutWithSidebar
@ -12,7 +14,7 @@ export default async function MeetingsPage() {
<div <div
className="select-inner" className="select-inner"
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: data ? data.data[9].content : "", __html: data?.data ? data.data[9].content : "",
}} }}
/> />
</LayoutWithSidebar> </LayoutWithSidebar>

View File

@ -1,8 +1,10 @@
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { getServices } from "@/services/services"; import { getServices } from "@/services/services";
import { getLocale } from "next-intl/server";
export default async function MissionsPage() { export default async function MissionsPage() {
const data = await getServices(); const lang = await getLocale();
const data = await getServices(lang);
return ( return (
<LayoutWithSidebar <LayoutWithSidebar
@ -12,7 +14,7 @@ export default async function MissionsPage() {
<div <div
className="select-inner" className="select-inner"
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: data ? data.data[10].content : "", __html: data?.data ? data.data[10].content : "",
}} }}
/> />
</LayoutWithSidebar> </LayoutWithSidebar>

View File

@ -1,8 +1,10 @@
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { getServices } from "@/services/services"; import { getServices } from "@/services/services";
import { getLocale } from "next-intl/server";
export default async function OrganizationPage() { export default async function OrganizationPage() {
const data = await getServices(); const lang = await getLocale();
const data = await getServices(lang);
return ( return (
<LayoutWithSidebar <LayoutWithSidebar

View File

@ -1,8 +1,10 @@
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { getServices } from "@/services/services"; import { getServices } from "@/services/services";
import { getLocale } from "next-intl/server";
export default async function OutsourcingPage() { export default async function OutsourcingPage() {
const data = await getServices(); const lang = await getLocale();
const data = await getServices(lang);
return ( return (
<LayoutWithSidebar <LayoutWithSidebar
@ -12,7 +14,7 @@ export default async function OutsourcingPage() {
<div <div
className="select-inner" className="select-inner"
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: data ? data.data[5].content : "", __html: data?.data ? data.data[5].content : "",
}} }}
/> />
</LayoutWithSidebar> </LayoutWithSidebar>

View File

@ -1,8 +1,10 @@
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { getServices } from "@/services/services"; import { getServices } from "@/services/services";
import { getLocale } from "next-intl/server";
export default async function PersonalTrainingPage() { export default async function PersonalTrainingPage() {
const data = await getServices(); const lang = await getLocale();
const data = await getServices(lang);
return ( return (
<LayoutWithSidebar <LayoutWithSidebar
@ -12,7 +14,7 @@ export default async function PersonalTrainingPage() {
<div <div
className="select-inner" className="select-inner"
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: data ? data.data[6].content : "", __html: data?.data ? data.data[6].content : "",
}} }}
/> />
</LayoutWithSidebar> </LayoutWithSidebar>

View File

@ -1,21 +1,20 @@
"use client"; "use client";
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { baseAPI } from "@/lib/API"; import { baseAPI } from "@/lib/API";
import { useAppSelector } from "@/redux/hooks"; import { useLocale, useTranslations } from "next-intl";
import { selectHeader } from "@/redux/slices/headerSlice";
import { useLang } from "@/utils/useLang";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
const Visitors = () => { const Visitors = () => {
const [visitorsData, setVisitorsData] = useState<string>(); const [visitorsData, setVisitorsData] = useState<string>();
const { activeLang } = useAppSelector(selectHeader); const locale = useLocale();
const t = useTranslations("visitors");
const fetchVisitors = async () => { const fetchVisitors = async () => {
try { try {
const res = await fetch(`${baseAPI}settings/visitors_page`, { const res = await fetch(`${baseAPI}settings/visitors_page`, {
headers: { headers: {
"Accept-Language": activeLang.localization, "Accept-Language": locale,
}, },
}); });
@ -33,17 +32,13 @@ const Visitors = () => {
useEffect(() => { useEffect(() => {
fetchVisitors(); fetchVisitors();
}, []); }, [locale]);
return ( return (
<div> <div>
<LayoutWithSidebar <LayoutWithSidebar
title={useLang( title={t("information")}
"Information for visitors", second={t("title")}
"Информация для посетителей",
activeLang.localization
)}
second={useLang("For visitors", "Посетителям", activeLang.localization)}
> >
<div <div
dangerouslySetInnerHTML={{ __html: visitorsData ? visitorsData : "" }} dangerouslySetInnerHTML={{ __html: visitorsData ? visitorsData : "" }}

View File

@ -1,21 +1,20 @@
"use client"; "use client";
import { LayoutWithSidebar } from "@/components/page/layout-with-sidebar"; import { LayoutWithSidebar } from "@/components/page/LayoutWithSidebar";
import { baseAPI } from "@/lib/API"; import { baseAPI } from "@/lib/API";
import { useAppSelector } from "@/redux/hooks"; import { useLocale, useTranslations } from "next-intl";
import { selectHeader } from "@/redux/slices/headerSlice";
import { useLang } from "@/utils/useLang";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
const RulesForVisitors = () => { const RulesForVisitors = () => {
const [visitorsData, setVisitorsData] = useState<string>(); const [visitorsData, setVisitorsData] = useState<string>();
const { activeLang } = useAppSelector(selectHeader); const locale = useLocale();
const t = useTranslations("visitors");
const fetchVisitors = async () => { const fetchVisitors = async () => {
try { try {
const res = await fetch(`${baseAPI}settings/visiting_rules`, { const res = await fetch(`${baseAPI}settings/visiting_rules`, {
headers: { headers: {
"Accept-Language": activeLang.localization, "Accept-Language": locale,
}, },
}); });
@ -33,23 +32,15 @@ const RulesForVisitors = () => {
useEffect(() => { useEffect(() => {
fetchVisitors(); fetchVisitors();
}, []); }, [locale]);
return ( return (
<div> <div>
<LayoutWithSidebar <LayoutWithSidebar
title={useLang( title={t("rules")}
"Entrance rules", second={t("title")}
"Порядок регистрации посетителей",
activeLang.localization
)}
second={useLang("Visitors", "Посетителям", activeLang.localization)}
path="/visitors" path="/visitors"
third={useLang( third={t("rules")}
"Entrance rules",
"Порядок регистрации посетителей",
activeLang.localization
)}
> >
<div <div
dangerouslySetInnerHTML={{ __html: visitorsData ? visitorsData : "" }} dangerouslySetInnerHTML={{ __html: visitorsData ? visitorsData : "" }}

View File

@ -1,6 +1,6 @@
import { EventPageButtons } from "@/components/shared/event-page-buttons"; import { EventPageButtons } from "@/components/shared/event-page-buttons";
import { getEventPage } from "@/services/calendar"; import { getEventPage } from "@/services/calendar";
import { cookies } from "next/headers"; import { getLocale, getTranslations } from "next-intl/server";
import Image from "next/image"; import Image from "next/image";
export default async function EventPage({ export default async function EventPage({
@ -10,12 +10,13 @@ export default async function EventPage({
}) { }) {
const { id } = params; const { id } = params;
const lang = cookies().get("lang")?.value ?? "ru"; const lang = await getLocale();
const t = await getTranslations("events");
const data = await getEventPage(id, lang); const data = await getEventPage(id, lang);
return ( return (
<div className="flex flex-col container gap-20 pt-16 section-mb"> <div className="flex flex-col container gap-20 pt-32 section-mb">
<h1 className="md:text-[48px] text-[28px] text-ON_SURFACE leading-[115%] font-medium"> <h1 className="md:text-[48px] text-[28px] text-ON_SURFACE leading-[115%] font-medium">
{data?.title ? data?.title : null} {data?.title ? data?.title : null}
</h1> </h1>
@ -24,7 +25,7 @@ export default async function EventPage({
<div className="flex flex-col gap-20 w-full"> <div className="flex flex-col gap-20 w-full">
<div className="flex flex-col gap-8 event-block "> <div className="flex flex-col gap-8 event-block ">
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<h4>{lang === "en" ? "Date" : "Дата"}</h4> <h4>{t("date")}</h4>
<h5>{data?.date}</h5> <h5>{data?.date}</h5>
</div> </div>
@ -32,7 +33,7 @@ export default async function EventPage({
{data?.location && ( {data?.location && (
<> <>
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<h4>{lang === "en" ? "Venue" : "Место"}</h4> <h4>{t("venue")}</h4>
<h5>{data?.location}</h5> <h5>{data?.location}</h5>
</div> </div>
<hr /> <hr />
@ -42,7 +43,7 @@ export default async function EventPage({
{data?.organizers.length > 0 && ( {data?.organizers.length > 0 && (
<> <>
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<h4>{lang === "en" ? "Organiser" : "Организатор"}</h4> <h4>{t("organiser")}</h4>
<h5>{data?.organizers[0]?.name}</h5> <h5>{data?.organizers[0]?.name}</h5>
</div> </div>
</> </>
@ -53,7 +54,7 @@ export default async function EventPage({
<hr /> <hr />
<div className="flex justify-between items-center"> <div className="flex justify-between items-center">
<h4>{lang === "en" ? "Co-organiser" : "Со-организатор"}</h4> <h4>{t("coOrganiser")}</h4>
<h5>{data?.coorganizers[0]?.name}</h5> <h5>{data?.coorganizers[0]?.name}</h5>
</div> </div>
@ -61,12 +62,15 @@ export default async function EventPage({
)} )}
</div> </div>
{data?.url_detailed || data?.url_registration || data?.url_web || data?.web_site ? (
<EventPageButtons <EventPageButtons
once={Boolean(data?.our)} once={Boolean(data?.our)}
details={data?.url_detailed} details={data?.url_detailed ? data?.url_detailed : data?.web_site}
register={data?.url_registration} register={data?.url_registration}
visit={data?.url_web} visit={data?.url_web ? data?.url_web : data?.web_site}
/> />
) : null}
</div> </div>
<Image <Image
@ -79,20 +83,20 @@ export default async function EventPage({
</div> </div>
<div className="flex flex-col gap-8"> <div className="flex flex-col gap-8">
<div className="flex flex-col lg:flex-row gap-6"> {data?.description ?? <div className="flex flex-col lg:flex-row gap-6">
<h4 className="text_24 lg:flex-[0_0_392px]"> <h4 className="text_24 lg:flex-[0_0_392px]">
{lang === "en" ? "Description" : "Описание"} {t("description")}
</h4> </h4>
<p className="flex-1 text_16">{data?.description}</p> <p className="flex-1 text_16">{data.description}</p>
</div> </div>}
{data?.event_topic && ( {/* {data?.event_topic && (
<> <>
<hr className="border-OUTLINE_VAR" /> <hr className="border-OUTLINE_VAR" />
<div className="flex flex-col lg:flex-row gap-6"> <div className="flex flex-col lg:flex-row gap-6">
<h4 className="text_24 lg:flex-[0_0_392px]"> <h4 className="text_24 lg:flex-[0_0_392px]">
{lang === "en" ? "Theme of event" : "Тематика мероприятия"} {t("theme")}
</h4> </h4>
<div <div
className="flex-1 text_16" className="flex-1 text_16"
@ -100,7 +104,7 @@ export default async function EventPage({
/> />
</div> </div>
</> </>
)} )} */}
</div> </div>
</div> </div>
); );

View File

@ -3,30 +3,30 @@ import { BreadCrumbs } from "@/components/ui/bread-crumbs";
import { Title } from "@/components/ui/title"; import { Title } from "@/components/ui/title";
import { getCalendar } from "@/services/calendar"; import { getCalendar } from "@/services/calendar";
import { Metadata } from "next"; import { Metadata } from "next";
import { cookies } from "next/headers"; import { getLocale, getTranslations } from "next-intl/server";
export const metadata: Metadata = { export const metadata: Metadata = {
title: "TurkmenExpo | Calendar", title: "TurkmenExpo | Calendar",
}; };
export default async function CalendarPage() { export default async function CalendarPage() {
const lang = cookies().get("lang")?.value ?? "ru"; const lang = await getLocale();
const t = await getTranslations("calendar");
const data = await getCalendar(lang); const data = await getCalendar(lang);
const title = lang === "en" ? "Calendar of events" : "Календарь мероприятий";
return ( return (
<div className="section-mb"> <div className="section-mb pt-10">
<div className="container flex flex-col items-start pt-5 gap-10 md:gap-12"> <div className="container flex flex-col items-start pt-5 gap-10 md:gap-12">
<div> <div>
<div className="mb-[24px]"> <div className="mb-[24px]">
<BreadCrumbs second={title} /> <BreadCrumbs second={t("title")} />
</div> </div>
<Title text={title} /> <Title text={t("title")} />
</div> </div>
<div className="flex flex-col gap-6 w-full"> <div className="flex flex-col gap-6 w-full">
{data.data.map((item, i) => ( {data.data.map((item, i) => (
<EventCard dark={true} key={i} {...item} /> <EventCard dark={true} key={i} {...item} starts_at={item.starts_at_text} ends_at={item.ends_at_text} />
))} ))}
</div> </div>
</div> </div>

View File

@ -2,32 +2,34 @@ import React from "react";
import { BreadCrumbs } from "@/components/ui/bread-crumbs"; import { BreadCrumbs } from "@/components/ui/bread-crumbs";
import { ContactsForm } from "@/components/shared/contacts-form"; import { ContactsForm } from "@/components/shared/contacts-form";
import { cookies } from "next/headers"; import { getTranslations } from "next-intl/server";
export default async function ContactsPage() { export default async function ContactsPage() {
const lang = cookies().get("lang")?.value; const t = await getTranslations("contacts");
return ( return (
<main className="bg-blueBg h-full w-full"> <main className="bg-blueBg h-full w-full pt-12">
<div className="container flex flex-col items-start"> <div className="container flex flex-col items-start">
<div className="mt-5"> <div className="mt-5">
<BreadCrumbs second={lang === "ru" ? "Контакты" : "Contacts"} /> <BreadCrumbs second={t("title")} />
</div> </div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 w-full"> <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 w-full">
<ContactsForm /> <ContactsForm />
<div className="p-6 bg-bg_surface_container rounded-[8px]"> <div className="p-6 bg-bg_surface_container rounded-[8px]">
<h2 className="h2 mb-10 xl:mb-8 text-3xl font-normal">Контакты</h2> <h2 className="h2 mb-10 xl:mb-8 text-3xl font-normal">
{t("title")}
</h2>
<div className="flex flex-col gap-20"> <div className="flex flex-col gap-20">
<div className="flex items-center gap-6"> <div className="flex items-center gap-6">
<img src="/assets/icons/contacts/address.svg" alt="address" /> <img src="/assets/icons/contacts/address.svg" alt="address" />
<div> <div>
<h3 className="text-xl mb-2">Адрес:</h3> <h3 className="text-xl mb-2">{t("address")}</h3>
<address className="text-base normal not-italic"> <address className="text-base normal not-italic">
744000, г. Ашхабад, просп. Битарап Туркменистан, 183 {t("addressValue")}
</address> </address>
</div> </div>
</div> </div>
@ -36,9 +38,7 @@ export default async function ContactsPage() {
<div> <div>
<h3 className="text-xl mb-2"></h3> <h3 className="text-xl mb-2"></h3>
<h4 className="text-base normal"> <h4 className="text-base normal">{t("phoneNumbers")}</h4>
+99371871814; 99363719588
</h4>
</div> </div>
</div> </div>

View File

@ -1,24 +1,24 @@
import { Events } from "@/components/shared/Events"; import { Events } from "@/components/shared/Events";
import { News } from "@/components/shared/News"; import { News } from "@/components/shared/News";
import { Partners } from "@/components/shared/Partners"; import { Partners } from "@/components/shared/Partners";
import { Reviews } from "@/components/shared/Reviews";
import { Slider } from "@/components/shared/Slider"; import { Slider } from "@/components/shared/Slider";
import { Video } from "@/components/shared/Video";
import Loader from "@/components/ui/Loader"; import Loader from "@/components/ui/Loader";
import { cookies } from "next/headers"; import { getLocale } from "next-intl/server";
import { Suspense } from "react"; import { Suspense } from "react";
export default async function HomePage() { export default async function HomePage() {
const lang = cookies().get("lang")?.value ?? "ru"; const lang = await getLocale();
return ( return (
<div className="bg-blueBg flex flex-col gap-[60px] md:gap-20 pb-20"> <div className="bg-blueBg flex flex-col gap-[60px] md:gap-20 pb-20 mt-[70px]">
<Slider lang={lang} /> <Slider lang={lang} />
<Suspense fallback={<Loader />}> <Suspense fallback={<Loader />}>
<Events lang={lang} /> <Events lang={lang} />
</Suspense> </Suspense>
<News /> <News />
{/* <Video /> */} <Reviews />
<Partners /> <Partners />
</div> </div>
); );

45
app/[locale]/layout.tsx Normal file
View File

@ -0,0 +1,45 @@
import { Roboto } from "next/font/google";
import clsx from "clsx";
import { NextIntlClientProvider } from "next-intl";
import { getMessages, setRequestLocale } from "next-intl/server";
import { notFound } from "next/navigation";
import { locales } from "@/i18n/config";
import StoreProvider from "../StoreProvider";
import "../globals.css";
const roboto = Roboto({
subsets: ["latin"],
weight: ["300", "400", "500", "700"],
variable: "--font-roboto",
});
export function generateStaticParams() {
return locales.map((locale) => ({ locale }));
}
export default async function LocaleLayout({
children,
params,
}: {
children: React.ReactNode;
params: { locale: string };
}) {
const { locale } = params;
if (!locales.includes(locale as any)) notFound();
setRequestLocale(locale);
const messages = await getMessages();
return (
<html lang={locale}>
<StoreProvider>
<body className={clsx("antialiased font-roboto", roboto.variable)}>
<NextIntlClientProvider locale={locale} messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</StoreProvider>
</html>
);
}

View File

@ -386,6 +386,15 @@ p img {
transform: translate(-50%, -50%) scale(1); transform: translate(-50%, -50%) scale(1);
} }
/* Stretch swiper slides to equal height */
.testimonials-swiper .swiper-wrapper {
align-items: stretch;
}
.testimonials-swiper .swiper-slide {
height: auto;
}
.autoplay-progress { .autoplay-progress {
z-index: 10; z-index: 10;
width: 63px; width: 63px;
@ -416,6 +425,22 @@ p img {
overflow: hidden; overflow: hidden;
} }
.dot {
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #d1d5db;
cursor: pointer;
transition: all 0.3s ease;
margin: 0 4px;
}
.dot-active {
@apply bg-PRIMARY;
transform: scale(1.2);
}
.input { .input {
@apply flex h-14 rounded-[2px] p-4 focus:ring-2 border-0 focus:outline-none focus:ring-white transition-all hover:ring-white ring-slate-300 ring-[1px] bg-[#E3E8E5] text-base file:border-0 file:bg-SECONDARY_CONTAINER file:outline-none file:text-sm file:w-fit file:text-ON_SECONDARY_CONTAINER file:font-medium focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50; @apply flex h-14 rounded-[2px] p-4 focus:ring-2 border-0 focus:outline-none focus:ring-white transition-all hover:ring-white ring-slate-300 ring-[1px] bg-[#E3E8E5] text-base file:border-0 file:bg-SECONDARY_CONTAINER file:outline-none file:text-sm file:w-fit file:text-ON_SECONDARY_CONTAINER file:font-medium focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50;
} }

View File

@ -1,26 +1,10 @@
import type { Metadata } from "next"; import type { Metadata } from "next";
import { Roboto } from "next/font/google";
import StoreProvider from "./StoreProvider";
import "./globals.css";
import clsx from "clsx";
const roboto = Roboto({
subsets: ["latin"],
weight: ["300", "400", "500", "700"],
variable: "--font-roboto",
});
export const metadata: Metadata = { export const metadata: Metadata = {
title: "TurkmenExpo", title: "TurkmenExpo",
description: "", description: "",
icons: { icons: {
icon: [ icon: "/assets/icons/logo.svg",
{
url: "/assets/icons/logo.svg",
href: "/assets/icons/logo.svg",
},
],
}, },
}; };
@ -29,13 +13,5 @@ export default function RootLayout({
}: Readonly<{ }: Readonly<{
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
return ( return children;
<html>
<StoreProvider>
<body className={clsx("antialiased font-roboto", roboto.variable)}>
{children}
</body>
</StoreProvider>
</html>
);
} }

View File

@ -1,31 +0,0 @@
// middleware.ts
import { NextRequest, NextResponse } from "next/server";
export function middleware(request: NextRequest) {
// 1. Проверяем существующую куку
let lang = request.cookies.get("lang")?.value;
// 2. Если куки нет, определяем язык из браузера
if (!lang) {
lang =
request.headers
.get("Accept-Language")
?.split(",")[0] // Берём первый язык из списка
.split("-")[0] // Убираем регион (en-US → en)
.toLowerCase() || "en"; // Fallback на английский
}
// 3. Сохраняем язык в куки
const response = NextResponse.next();
if (!request.cookies.has("lang")) {
response.cookies.set("lang", lang, {
maxAge: 60 * 60 * 24 * 365, // 1 год
httpOnly: true,
});
}
// 4. Добавляем язык в заголовки ВСЕХ исходящих запросов
response.headers.set("Accept-Language", lang);
return response;
}

941
bun.lock Normal file
View File

@ -0,0 +1,941 @@
{
"lockfileVersion": 1,
"workspaces": {
"": {
"name": "turkmen_expo_client",
"dependencies": {
"@hookform/resolvers": "^3.3.4",
"@react-google-maps/api": "^2.19.3",
"@reduxjs/toolkit": "^2.2.1",
"@types/uuid": "^9.0.8",
"clsx": "^2.1.0",
"framer-motion": "^11.0.25",
"next": "14.1.0",
"pm2": "^5.3.1",
"react": "^18",
"react-dom": "^18",
"react-hook-form": "^7.50.1",
"react-redux": "^9.1.0",
"serve": "^14.2.1",
"sharp": "^0.33.2",
"swiper": "^11.0.6",
"use-debounce": "^10.0.0",
"usehooks-ts": "^3.1.0",
"uuid": "^9.0.1",
"zod": "^3.22.4",
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"autoprefixer": "^10.0.1",
"postcss": "^8",
"tailwindcss": "^3.3.0",
"typescript": "^5",
},
},
},
"packages": {
"@alloc/quick-lru": ["@alloc/quick-lru@5.2.0", "", {}, "sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw=="],
"@emnapi/runtime": ["@emnapi/runtime@0.45.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-Txumi3td7J4A/xTTwlssKieHKTGl3j4A1tglBx72auZ49YK7ePY6XZricgIg9mnZT4xPfA+UPCUdnhRuEFDL+w=="],
"@googlemaps/js-api-loader": ["@googlemaps/js-api-loader@1.16.2", "", { "dependencies": { "fast-deep-equal": "^3.1.3" } }, "sha512-psGw5u0QM6humao48Hn4lrChOM2/rA43ZCm3tKK9qQsEj1/VzqkCqnvGfEOshDbBQflydfaRovbKwZMF4AyqbA=="],
"@googlemaps/markerclusterer": ["@googlemaps/markerclusterer@2.5.3", "", { "dependencies": { "fast-deep-equal": "^3.1.3", "supercluster": "^8.0.1" } }, "sha512-x7lX0R5yYOoiNectr10wLgCBasNcXFHiADIBdmn7jQllF2B5ENQw5XtZK+hIw4xnV0Df0xhN4LN98XqA5jaiOw=="],
"@hookform/resolvers": ["@hookform/resolvers@3.3.4", "", { "peerDependencies": { "react-hook-form": "^7.0.0" } }, "sha512-o5cgpGOuJYrd+iMKvkttOclgwRW86EsWJZZRC23prf0uU2i48Htq4PuT73AVb9ionFyZrwYEITuOFGF+BydEtQ=="],
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.33.2", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.0.1" }, "os": "darwin", "cpu": "arm64" }, "sha512-itHBs1rPmsmGF9p4qRe++CzCgd+kFYktnsoR1sbIAfsRMrJZau0Tt1AH9KVnufc2/tU02Gf6Ibujx+15qRE03w=="],
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.33.2", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.0.1" }, "os": "darwin", "cpu": "x64" }, "sha512-/rK/69Rrp9x5kaWBjVN07KixZanRr+W1OiyKdXcbjQD6KbW+obaTeBBtLUAtbBsnlTTmWthw99xqoOS7SsySDg=="],
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.0.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-kQyrSNd6lmBV7O0BUiyu/OEw9yeNGFbQhbxswS1i6rMDwBBSX+e+rPzu3S+MwAiGU3HdLze3PanQ4Xkfemgzcw=="],
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.0.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-eVU/JYLPVjhhrd8Tk6gosl5pVlvsqiFlt50wotCvdkFGf+mDNBJxMh+bvav+Wt3EBnNZWq8Sp2I7XfSjm8siog=="],
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.0.1", "", { "os": "linux", "cpu": "arm" }, "sha512-FtdMvR4R99FTsD53IA3LxYGghQ82t3yt0ZQ93WMZ2xV3dqrb0E8zq4VHaTOuLEAuA83oDawHV3fd+BsAPadHIQ=="],
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.0.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-bnGG+MJjdX70mAQcSLxgeJco11G+MxTz+ebxlz8Y3dxyeb3Nkl7LgLI0mXupoO+u1wRNx/iRj5yHtzA4sde1yA=="],
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.0.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-3+rzfAR1YpMOeA2zZNp+aYEzGNWK4zF3+sdMxuCS3ey9HhDbJ66w6hDSHDMoap32DueFwhhs3vwooAB2MaK4XQ=="],
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.0.1", "", { "os": "linux", "cpu": "x64" }, "sha512-3NR1mxFsaSgMMzz1bAnnKbSAI+lHXVTqAHgc1bgzjHuXjo4hlscpUxc0vFSAPKI3yuzdzcZOkq7nDPrP2F8Jgw=="],
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.0.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-5aBRcjHDG/T6jwC3Edl3lP8nl9U2Yo8+oTl5drd1dh9Z1EBfzUKAJFUDTDisDjUwc7N4AjnPGfCA3jl3hY8uDg=="],
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.0.1", "", { "os": "linux", "cpu": "x64" }, "sha512-dcT7inI9DBFK6ovfeWRe3hG30h51cBAP5JXlZfx6pzc/Mnf9HFCQDLtYf4MCBjxaaTfjCCjkBxcy3XzOAo5txw=="],
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.33.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.0.1" }, "os": "linux", "cpu": "arm" }, "sha512-Fndk/4Zq3vAc4G/qyfXASbS3HBZbKrlnKZLEJzPLrXoJuipFNNwTes71+Ki1hwYW5lch26niRYoZFAtZVf3EGA=="],
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.33.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.0.1" }, "os": "linux", "cpu": "arm64" }, "sha512-pz0NNo882vVfqJ0yNInuG9YH71smP4gRSdeL09ukC2YLE6ZyZePAlWKEHgAzJGTiOh8Qkaov6mMIMlEhmLdKew=="],
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.33.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.0.1" }, "os": "linux", "cpu": "s390x" }, "sha512-MBoInDXDppMfhSzbMmOQtGfloVAflS2rP1qPcUIiITMi36Mm5YR7r0ASND99razjQUpHTzjrU1flO76hKvP5RA=="],
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.33.2", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.0.1" }, "os": "linux", "cpu": "x64" }, "sha512-xUT82H5IbXewKkeF5aiooajoO1tQV4PnKfS/OZtb5DDdxS/FCI/uXTVZ35GQ97RZXsycojz/AJ0asoz6p2/H/A=="],
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.33.2", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.0.1" }, "os": "linux", "cpu": "arm64" }, "sha512-F+0z8JCu/UnMzg8IYW1TMeiViIWBVg7IWP6nE0p5S5EPQxlLd76c8jYemG21X99UzFwgkRo5yz2DS+zbrnxZeA=="],
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.33.2", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.0.1" }, "os": "linux", "cpu": "x64" }, "sha512-+ZLE3SQmSL+Fn1gmSaM8uFusW5Y3J9VOf+wMGNnTtJUMUxFhv+P4UPaYEYT8tqnyYVaOVGgMN/zsOxn9pSsO2A=="],
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.33.2", "", { "dependencies": { "@emnapi/runtime": "^0.45.0" }, "cpu": "none" }, "sha512-fLbTaESVKuQcpm8ffgBD7jLb/CQLcATju/jxtTXR1XCLwbOQt+OL5zPHSDMmp2JZIeq82e18yE0Vv7zh6+6BfQ=="],
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.33.2", "", { "os": "win32", "cpu": "ia32" }, "sha512-okBpql96hIGuZ4lN3+nsAjGeggxKm7hIRu9zyec0lnfB8E7Z6p95BuRZzDDXZOl2e8UmR4RhYt631i7mfmKU8g=="],
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.33.2", "", { "os": "win32", "cpu": "x64" }, "sha512-E4magOks77DK47FwHUIGH0RYWSgRBfGdK56kIHSVeB9uIS4pPFr4N2kIVsXdQQo4LzOsENKV5KAhRlRL7eMAdg=="],
"@isaacs/cliui": ["@isaacs/cliui@8.0.2", "", { "dependencies": { "string-width": "^5.1.2", "string-width-cjs": "npm:string-width@^4.2.0", "strip-ansi": "^7.0.1", "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", "wrap-ansi": "^8.1.0", "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" } }, "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA=="],
"@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.3", "", { "dependencies": { "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" } }, "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ=="],
"@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
"@jridgewell/set-array": ["@jridgewell/set-array@1.1.2", "", {}, "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw=="],
"@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.4.15", "", {}, "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg=="],
"@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.22", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-Wf963MzWtA2sjrNt+g18IAln9lKnlRp+K2eH4jjIoF1wYeq3aMREpG09xhlhdzS0EjwU7qmUJYangWa+151vZw=="],
"@next/env": ["@next/env@14.1.0", "", {}, "sha512-Py8zIo+02ht82brwwhTg36iogzFqGLPXlRGKQw5s+qP/kMNc4MAyDeEwBKDijk6zTIbegEgu8Qy7C1LboslQAw=="],
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@14.1.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-nUDn7TOGcIeyQni6lZHfzNoo9S0euXnu0jhsbMOmMJUBfgsnESdjN97kM7cBqQxZa8L/bM9om/S5/1dzCrW6wQ=="],
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@14.1.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-1jgudN5haWxiAl3O1ljUS2GfupPmcftu2RYJqZiMJmmbBT5M1XDffjUtRUzP4W3cBHsrvkfOFdQ71hAreNQP6g=="],
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@14.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-RHo7Tcj+jllXUbK7xk2NyIDod3YcCPDZxj1WLIYxd709BQ7WuRYl3OWUNG+WUfqeQBds6kvZYlc42NJJTNi4tQ=="],
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@14.1.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-v6kP8sHYxjO8RwHmWMJSq7VZP2nYCkRVQ0qolh2l6xroe9QjbgV8siTbduED4u0hlk0+tjS6/Tuy4n5XCp+l6g=="],
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@14.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-zJ2pnoFYB1F4vmEVlb/eSe+VH679zT1VdXlZKX+pE66grOgjmKJHKacf82g/sWE4MQ4Rk2FMBCRnX+l6/TVYzQ=="],
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@14.1.0", "", { "os": "linux", "cpu": "x64" }, "sha512-rbaIYFt2X9YZBSbH/CwGAjbBG2/MrACCVu2X0+kSykHzHnYH5FjHxwXLkcoJ10cX0aWCEynpu+rP76x0914atg=="],
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@14.1.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-o1N5TsYc8f/HpGt39OUQpQ9AKIGApd3QLueu7hXk//2xq5Z9OxmV6sQfNp8C7qYmiOlHYODOGqNNa0e9jvchGQ=="],
"@next/swc-win32-ia32-msvc": ["@next/swc-win32-ia32-msvc@14.1.0", "", { "os": "win32", "cpu": "ia32" }, "sha512-XXIuB1DBRCFwNO6EEzCTMHT5pauwaSj4SWs7CYnME57eaReAKBXCnkUE80p/pAZcewm7hs+vGvNqDPacEXHVkw=="],
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@14.1.0", "", { "os": "win32", "cpu": "x64" }, "sha512-9WEbVRRAqJ3YFVqEZIxUqkiO8l1nool1LmNxygr5HWF8AcSYsEpneUDhmjUVJEzO2A04+oPtZdombzzPPkTtgg=="],
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
"@opencensus/core": ["@opencensus/core@0.0.9", "", { "dependencies": { "continuation-local-storage": "^3.2.1", "log-driver": "^1.2.7", "semver": "^5.5.0", "shimmer": "^1.2.0", "uuid": "^3.2.1" } }, "sha512-31Q4VWtbzXpVUd2m9JS6HEaPjlKvNMOiF7lWKNmXF84yUcgfAFL5re7/hjDmdyQbOp32oGc+RFV78jXIldVz6Q=="],
"@opencensus/propagation-b3": ["@opencensus/propagation-b3@0.0.8", "", { "dependencies": { "@opencensus/core": "^0.0.8", "uuid": "^3.2.1" } }, "sha512-PffXX2AL8Sh0VHQ52jJC4u3T0H6wDK6N/4bg7xh4ngMYOIi13aR1kzVvX1sVDBgfGwDOkMbl4c54Xm3tlPx/+A=="],
"@pkgjs/parseargs": ["@pkgjs/parseargs@0.11.0", "", {}, "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg=="],
"@pm2/agent": ["@pm2/agent@2.0.3", "", { "dependencies": { "async": "~3.2.0", "chalk": "~3.0.0", "dayjs": "~1.8.24", "debug": "~4.3.1", "eventemitter2": "~5.0.1", "fast-json-patch": "^3.0.0-1", "fclone": "~1.0.11", "nssocket": "0.6.0", "pm2-axon": "~4.0.1", "pm2-axon-rpc": "~0.7.0", "proxy-agent": "~6.3.0", "semver": "~7.5.0", "ws": "~7.4.0" } }, "sha512-xkqqCoTf5VsciMqN0vb9jthW7olVAi4KRFNddCc7ZkeJZ3i8QwZANr4NSH2H5DvseRFHq7MiPspRY/EWAFWWTg=="],
"@pm2/io": ["@pm2/io@5.0.2", "", { "dependencies": { "@opencensus/core": "0.0.9", "@opencensus/propagation-b3": "0.0.8", "async": "~2.6.1", "debug": "~4.3.1", "eventemitter2": "^6.3.1", "require-in-the-middle": "^5.0.0", "semver": "~7.5.4", "shimmer": "^1.2.0", "signal-exit": "^3.0.3", "tslib": "1.9.3" } }, "sha512-XAvrNoQPKOyO/jJyCu8jPhLzlyp35MEf7w/carHXmWKddPzeNOFSEpSEqMzPDawsvpxbE+i918cNN+MwgVsStA=="],
"@pm2/js-api": ["@pm2/js-api@0.8.0", "", { "dependencies": { "async": "^2.6.3", "debug": "~4.3.1", "eventemitter2": "^6.3.1", "extrareqp2": "^1.0.0", "ws": "^7.0.0" } }, "sha512-nmWzrA/BQZik3VBz+npRcNIu01kdBhWL0mxKmP1ciF/gTcujPTQqt027N9fc1pK9ERM8RipFhymw7RcmCyOEYA=="],
"@pm2/pm2-version-check": ["@pm2/pm2-version-check@1.0.4", "", { "dependencies": { "debug": "^4.3.1" } }, "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA=="],
"@react-google-maps/api": ["@react-google-maps/api@2.19.3", "", { "dependencies": { "@googlemaps/js-api-loader": "1.16.2", "@googlemaps/markerclusterer": "2.5.3", "@react-google-maps/infobox": "2.19.2", "@react-google-maps/marker-clusterer": "2.19.2", "@types/google.maps": "3.55.2", "invariant": "2.2.4" }, "peerDependencies": { "react": "^16.8 || ^17 || ^18", "react-dom": "^16.8 || ^17 || ^18" } }, "sha512-jiLqvuOt5lOowkLeq7d077AByTyJp+s6hZVlLhlq7SBacBD37aUNpXBz2OsazfeR6Aw4a+9RRhAEjEFvrR1f5A=="],
"@react-google-maps/infobox": ["@react-google-maps/infobox@2.19.2", "", {}, "sha512-6wvBqeJsQ/eFSvoxg+9VoncQvNoVCdmxzxRpLvmjPD+nNC6mHM0vJH1xSqaKijkMrfLJT0nfkTGpovrF896jwg=="],
"@react-google-maps/marker-clusterer": ["@react-google-maps/marker-clusterer@2.19.2", "", {}, "sha512-x9ibmsP0ZVqzyCo1Pitbw+4b6iEXRw/r1TCy3vOUR3eKrzWLnHYZMR325BkZW2r8fnuWE/V3Fp4QZOP9qYORCw=="],
"@reduxjs/toolkit": ["@reduxjs/toolkit@2.2.1", "", { "dependencies": { "immer": "^10.0.3", "redux": "^5.0.1", "redux-thunk": "^3.1.0", "reselect": "^5.0.1" }, "peerDependencies": { "react": "^16.9.0 || ^17.0.0 || ^18", "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" } }, "sha512-8CREoqJovQW/5I4yvvijm/emUiCCmcs4Ev4XPWd4mizSO+dD3g5G6w34QK5AGeNrSH7qM8Fl66j4vuV7dpOdkw=="],
"@swc/helpers": ["@swc/helpers@0.5.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-E4KcWTpoLHqwPHLxidpOqQbcrZVgi0rsmmZXUle1jXmJfuIf/UWpczUJ7MZZ5tlxytgJXyp0w4PGkkeLiuIdZw=="],
"@tootallnate/quickjs-emscripten": ["@tootallnate/quickjs-emscripten@0.23.0", "", {}, "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA=="],
"@types/google.maps": ["@types/google.maps@3.55.2", "", {}, "sha512-JcTwzkxskR8DN/nnX96Pie3gGN3WHiPpuxzuQ9z3516o1bB243d8w8DHUJ8BohuzoT1o3HUFta2ns/mkZC8KRw=="],
"@types/node": ["@types/node@20.11.19", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-7xMnVEcZFu0DikYjWOlRq7NTPETrm7teqUT2WkQjrTIkEgUyyGdWsj/Zg8bEJt5TNklzbPD1X3fqfsHw3SpapQ=="],
"@types/prop-types": ["@types/prop-types@15.7.11", "", {}, "sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng=="],
"@types/react": ["@types/react@18.2.57", "", { "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", "csstype": "^3.0.2" } }, "sha512-ZvQsktJgSYrQiMirAN60y4O/LRevIV8hUzSOSNB6gfR3/o3wCBFQx3sPwIYtuDMeiVgsSS3UzCV26tEzgnfvQw=="],
"@types/react-dom": ["@types/react-dom@18.2.19", "", { "dependencies": { "@types/react": "*" } }, "sha512-aZvQL6uUbIJpjZk4U8JZGbau9KDeAwMfmhyWorxgBkqDIEf6ROjRozcmPIicqsUwPUjbkDfHKgGee1Lq65APcA=="],
"@types/scheduler": ["@types/scheduler@0.16.8", "", {}, "sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A=="],
"@types/use-sync-external-store": ["@types/use-sync-external-store@0.0.3", "", {}, "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="],
"@types/uuid": ["@types/uuid@9.0.8", "", {}, "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA=="],
"@zeit/schemas": ["@zeit/schemas@2.29.0", "", {}, "sha512-g5QiLIfbg3pLuYUJPlisNKY+epQJTcMDsOnVNkscrDP1oi7vmJnzOANYJI/1pZcVJ6umUkBv3aFtlg1UvUHGzA=="],
"accepts": ["accepts@1.3.8", "", { "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" } }, "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw=="],
"agent-base": ["agent-base@7.1.1", "", { "dependencies": { "debug": "^4.3.4" } }, "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA=="],
"ajv": ["ajv@8.11.0", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "json-schema-traverse": "^1.0.0", "require-from-string": "^2.0.2", "uri-js": "^4.2.2" } }, "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg=="],
"amp": ["amp@0.3.1", "", {}, "sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw=="],
"amp-message": ["amp-message@0.1.2", "", { "dependencies": { "amp": "0.3.1" } }, "sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg=="],
"ansi-align": ["ansi-align@3.0.1", "", { "dependencies": { "string-width": "^4.1.0" } }, "sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w=="],
"ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="],
"ansi-regex": ["ansi-regex@6.0.1", "", {}, "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA=="],
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"any-promise": ["any-promise@1.3.0", "", {}, "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A=="],
"anymatch": ["anymatch@3.1.3", "", { "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw=="],
"arch": ["arch@2.2.0", "", {}, "sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ=="],
"arg": ["arg@5.0.2", "", {}, "sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg=="],
"argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
"ast-types": ["ast-types@0.13.4", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w=="],
"async": ["async@3.2.5", "", {}, "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg=="],
"async-listener": ["async-listener@0.6.10", "", { "dependencies": { "semver": "^5.3.0", "shimmer": "^1.1.0" } }, "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw=="],
"autoprefixer": ["autoprefixer@10.4.17", "", { "dependencies": { "browserslist": "^4.22.2", "caniuse-lite": "^1.0.30001578", "fraction.js": "^4.3.7", "normalize-range": "^0.1.2", "picocolors": "^1.0.0", "postcss-value-parser": "^4.2.0" }, "peerDependencies": { "postcss": "^8.1.0" }, "bin": "bin/autoprefixer" }, "sha512-/cpVNRLSfhOtcGflT13P2794gVSgmPgTR+erw5ifnMLZb0UnSlkK4tquLmkd3BhA+nLo5tX8Cu0upUsGKvKbmg=="],
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"basic-ftp": ["basic-ftp@5.0.5", "", {}, "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg=="],
"binary-extensions": ["binary-extensions@2.2.0", "", {}, "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="],
"blessed": ["blessed@0.1.81", "", { "bin": "bin/tput.js" }, "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ=="],
"bodec": ["bodec@0.1.0", "", {}, "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ=="],
"boxen": ["boxen@7.0.0", "", { "dependencies": { "ansi-align": "^3.0.1", "camelcase": "^7.0.0", "chalk": "^5.0.1", "cli-boxes": "^3.0.0", "string-width": "^5.1.2", "type-fest": "^2.13.0", "widest-line": "^4.0.1", "wrap-ansi": "^8.0.1" } }, "sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg=="],
"brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
"braces": ["braces@3.0.2", "", { "dependencies": { "fill-range": "^7.0.1" } }, "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A=="],
"browserslist": ["browserslist@4.23.0", "", { "dependencies": { "caniuse-lite": "^1.0.30001587", "electron-to-chromium": "^1.4.668", "node-releases": "^2.0.14", "update-browserslist-db": "^1.0.13" }, "bin": "cli.js" }, "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ=="],
"buffer-from": ["buffer-from@1.1.2", "", {}, "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="],
"busboy": ["busboy@1.6.0", "", { "dependencies": { "streamsearch": "^1.1.0" } }, "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA=="],
"bytes": ["bytes@3.0.0", "", {}, "sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw=="],
"camelcase": ["camelcase@7.0.1", "", {}, "sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw=="],
"camelcase-css": ["camelcase-css@2.0.1", "", {}, "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA=="],
"caniuse-lite": ["caniuse-lite@1.0.30001588", "", {}, "sha512-+hVY9jE44uKLkH0SrUTqxjxqNTOWHsbnQDIKjwkZ3lNTzUUVdBLBGXtj/q5Mp5u98r3droaZAewQuEDzjQdZlQ=="],
"chalk": ["chalk@3.0.0", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="],
"chalk-template": ["chalk-template@0.4.0", "", { "dependencies": { "chalk": "^4.1.2" } }, "sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg=="],
"charm": ["charm@0.1.2", "", {}, "sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ=="],
"chokidar": ["chokidar@3.6.0", "", { "dependencies": { "anymatch": "~3.1.2", "braces": "~3.0.2", "glob-parent": "~5.1.2", "is-binary-path": "~2.1.0", "is-glob": "~4.0.1", "normalize-path": "~3.0.0", "readdirp": "~3.6.0" }, "optionalDependencies": { "fsevents": "~2.3.2" } }, "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw=="],
"cli-boxes": ["cli-boxes@3.0.0", "", {}, "sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g=="],
"cli-tableau": ["cli-tableau@2.0.1", "", { "dependencies": { "chalk": "3.0.0" } }, "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ=="],
"client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
"clipboardy": ["clipboardy@3.0.0", "", { "dependencies": { "arch": "^2.2.0", "execa": "^5.1.1", "is-wsl": "^2.2.0" } }, "sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg=="],
"clsx": ["clsx@2.1.0", "", {}, "sha512-m3iNNWpd9rl3jvvcBnu70ylMdrXt8Vlq4HYadnU5fwcOtvkSQWPmj7amUcDT2qYI7risszBjI5AUIUox9D16pg=="],
"color": ["color@4.2.3", "", { "dependencies": { "color-convert": "^2.0.1", "color-string": "^1.9.0" } }, "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A=="],
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
"color-string": ["color-string@1.9.1", "", { "dependencies": { "color-name": "^1.0.0", "simple-swizzle": "^0.2.2" } }, "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg=="],
"commander": ["commander@2.15.1", "", {}, "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag=="],
"compressible": ["compressible@2.0.18", "", { "dependencies": { "mime-db": ">= 1.43.0 < 2" } }, "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg=="],
"compression": ["compression@1.7.4", "", { "dependencies": { "accepts": "~1.3.5", "bytes": "3.0.0", "compressible": "~2.0.16", "debug": "2.6.9", "on-headers": "~1.0.2", "safe-buffer": "5.1.2", "vary": "~1.1.2" } }, "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ=="],
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
"content-disposition": ["content-disposition@0.5.2", "", {}, "sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA=="],
"continuation-local-storage": ["continuation-local-storage@3.2.1", "", { "dependencies": { "async-listener": "^0.6.0", "emitter-listener": "^1.1.1" } }, "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA=="],
"croner": ["croner@4.1.97", "", {}, "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ=="],
"cross-spawn": ["cross-spawn@7.0.3", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w=="],
"cssesc": ["cssesc@3.0.0", "", { "bin": "bin/cssesc" }, "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
"culvert": ["culvert@0.1.2", "", {}, "sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg=="],
"data-uri-to-buffer": ["data-uri-to-buffer@6.0.2", "", {}, "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw=="],
"dayjs": ["dayjs@1.11.10", "", {}, "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ=="],
"debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
"degenerator": ["degenerator@5.0.1", "", { "dependencies": { "ast-types": "^0.13.4", "escodegen": "^2.1.0", "esprima": "^4.0.1" } }, "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ=="],
"detect-libc": ["detect-libc@2.0.2", "", {}, "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw=="],
"didyoumean": ["didyoumean@1.2.2", "", {}, "sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw=="],
"dlv": ["dlv@1.1.3", "", {}, "sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA=="],
"eastasianwidth": ["eastasianwidth@0.2.0", "", {}, "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="],
"electron-to-chromium": ["electron-to-chromium@1.4.677", "", {}, "sha512-erDa3CaDzwJOpyvfKhOiJjBVNnMM0qxHq47RheVVwsSQrgBA9ZSGV9kdaOfZDPXcHzhG7lBxhj6A7KvfLJBd6Q=="],
"emitter-listener": ["emitter-listener@1.1.2", "", { "dependencies": { "shimmer": "^1.2.0" } }, "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ=="],
"emoji-regex": ["emoji-regex@9.2.2", "", {}, "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="],
"enquirer": ["enquirer@2.3.6", "", { "dependencies": { "ansi-colors": "^4.1.1" } }, "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg=="],
"escalade": ["escalade@3.1.2", "", {}, "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA=="],
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
"escodegen": ["escodegen@2.1.0", "", { "dependencies": { "esprima": "^4.0.1", "estraverse": "^5.2.0", "esutils": "^2.0.2" }, "optionalDependencies": { "source-map": "~0.6.1" }, "bin": { "escodegen": "bin/escodegen.js", "esgenerate": "bin/esgenerate.js" } }, "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w=="],
"esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
"estraverse": ["estraverse@5.3.0", "", {}, "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA=="],
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
"eventemitter2": ["eventemitter2@5.0.1", "", {}, "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg=="],
"execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="],
"extrareqp2": ["extrareqp2@1.0.0", "", { "dependencies": { "follow-redirects": "^1.14.0" } }, "sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA=="],
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
"fast-glob": ["fast-glob@3.3.2", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.4" } }, "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow=="],
"fast-json-patch": ["fast-json-patch@3.1.1", "", {}, "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ=="],
"fast-url-parser": ["fast-url-parser@1.1.3", "", { "dependencies": { "punycode": "^1.3.2" } }, "sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ=="],
"fastq": ["fastq@1.17.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w=="],
"fclone": ["fclone@1.0.11", "", {}, "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw=="],
"fill-range": ["fill-range@7.0.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ=="],
"follow-redirects": ["follow-redirects@1.15.6", "", {}, "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="],
"foreground-child": ["foreground-child@3.1.1", "", { "dependencies": { "cross-spawn": "^7.0.0", "signal-exit": "^4.0.1" } }, "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg=="],
"fraction.js": ["fraction.js@4.3.7", "", {}, "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew=="],
"framer-motion": ["framer-motion@11.0.25", "", { "dependencies": { "tslib": "^2.4.0" }, "peerDependencies": { "@emotion/is-prop-valid": "*", "react": "^18.0.0", "react-dom": "^18.0.0" }, "optionalPeers": ["@emotion/is-prop-valid"] }, "sha512-mRt7vQGzA7++wTgb+PW1TrlXXgndqR6hCiJ48fXr2X9alte2hPQiAq556HRwDCt0Q5X98MNvcSe4KUa27Gm5Lg=="],
"fs-extra": ["fs-extra@11.2.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw=="],
"fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="],
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
"get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
"get-uri": ["get-uri@6.0.3", "", { "dependencies": { "basic-ftp": "^5.0.2", "data-uri-to-buffer": "^6.0.2", "debug": "^4.3.4", "fs-extra": "^11.2.0" } }, "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw=="],
"git-node-fs": ["git-node-fs@1.0.0", "", {}, "sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ=="],
"git-sha1": ["git-sha1@0.1.2", "", {}, "sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg=="],
"glob": ["glob@10.3.10", "", { "dependencies": { "foreground-child": "^3.1.0", "jackspeak": "^2.3.5", "minimatch": "^9.0.1", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", "path-scurry": "^1.10.1" }, "bin": "dist/esm/bin.mjs" }, "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g=="],
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
"hasown": ["hasown@2.0.1", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-1/th4MHjnwncwXsIW6QMzlvYL9kG5e/CpVvLRZe4XPa8TOUNbCELqmvhDmnkNsAjwaG4+I8gJJL0JBvTTLO9qA=="],
"http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
"https-proxy-agent": ["https-proxy-agent@7.0.4", "", { "dependencies": { "agent-base": "^7.0.2", "debug": "4" } }, "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg=="],
"human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="],
"iconv-lite": ["iconv-lite@0.4.24", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3" } }, "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA=="],
"immer": ["immer@10.0.3", "", {}, "sha512-pwupu3eWfouuaowscykeckFmVTpqbzW+rXFCX8rQLkZzM9ftBmU/++Ra+o+L27mz03zJTlyV4UUr+fdKNffo4A=="],
"inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="],
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
"ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
"invariant": ["invariant@2.2.4", "", { "dependencies": { "loose-envify": "^1.0.0" } }, "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA=="],
"ip-address": ["ip-address@9.0.5", "", { "dependencies": { "jsbn": "1.1.0", "sprintf-js": "^1.1.3" } }, "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g=="],
"is-arrayish": ["is-arrayish@0.3.2", "", {}, "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ=="],
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
"is-core-module": ["is-core-module@2.13.1", "", { "dependencies": { "hasown": "^2.0.0" } }, "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw=="],
"is-docker": ["is-docker@2.2.1", "", { "bin": "cli.js" }, "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ=="],
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
"is-port-reachable": ["is-port-reachable@4.0.0", "", {}, "sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig=="],
"is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
"is-wsl": ["is-wsl@2.2.0", "", { "dependencies": { "is-docker": "^2.0.0" } }, "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww=="],
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
"jackspeak": ["jackspeak@2.3.6", "", { "dependencies": { "@isaacs/cliui": "^8.0.2" }, "optionalDependencies": { "@pkgjs/parseargs": "^0.11.0" } }, "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ=="],
"jiti": ["jiti@1.21.0", "", { "bin": "bin/jiti.js" }, "sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q=="],
"js-git": ["js-git@0.7.8", "", { "dependencies": { "bodec": "^0.1.0", "culvert": "^0.1.2", "git-sha1": "^0.1.2", "pako": "^0.2.5" } }, "sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA=="],
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
"jsbn": ["jsbn@1.1.0", "", {}, "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A=="],
"json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
"json-stringify-safe": ["json-stringify-safe@5.0.1", "", {}, "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA=="],
"jsonfile": ["jsonfile@6.1.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ=="],
"kdbush": ["kdbush@4.0.2", "", {}, "sha512-WbCVYJ27Sz8zi9Q7Q0xHC+05iwkm3Znipc2XTlrnJbsHMYktW4hPhXUE8Ys1engBrvffoSCqbil1JQAa7clRpA=="],
"lazy": ["lazy@1.0.11", "", {}, "sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA=="],
"lilconfig": ["lilconfig@2.1.0", "", {}, "sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ=="],
"lines-and-columns": ["lines-and-columns@1.2.4", "", {}, "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg=="],
"lodash": ["lodash@4.17.21", "", {}, "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="],
"lodash.debounce": ["lodash.debounce@4.0.8", "", {}, "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow=="],
"log-driver": ["log-driver@1.2.7", "", {}, "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg=="],
"loose-envify": ["loose-envify@1.4.0", "", { "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, "bin": "cli.js" }, "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q=="],
"lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
"merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
"micromatch": ["micromatch@4.0.5", "", { "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" } }, "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA=="],
"mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
"mime-types": ["mime-types@2.1.18", "", { "dependencies": { "mime-db": "~1.33.0" } }, "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ=="],
"mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
"minipass": ["minipass@7.0.4", "", {}, "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ=="],
"mkdirp": ["mkdirp@1.0.4", "", { "bin": "bin/cmd.js" }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
"module-details-from-path": ["module-details-from-path@1.0.3", "", {}, "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A=="],
"ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"mute-stream": ["mute-stream@0.0.8", "", {}, "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA=="],
"mz": ["mz@2.7.0", "", { "dependencies": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", "thenify-all": "^1.0.0" } }, "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q=="],
"nanoid": ["nanoid@3.3.7", "", { "bin": "bin/nanoid.cjs" }, "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g=="],
"needle": ["needle@2.4.0", "", { "dependencies": { "debug": "^3.2.6", "iconv-lite": "^0.4.4", "sax": "^1.2.4" }, "bin": "bin/needle" }, "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg=="],
"negotiator": ["negotiator@0.6.3", "", {}, "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg=="],
"netmask": ["netmask@2.0.2", "", {}, "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg=="],
"next": ["next@14.1.0", "", { "dependencies": { "@next/env": "14.1.0", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001579", "graceful-fs": "^4.2.11", "postcss": "8.4.31", "styled-jsx": "5.1.1" }, "optionalDependencies": { "@next/swc-darwin-arm64": "14.1.0", "@next/swc-darwin-x64": "14.1.0", "@next/swc-linux-arm64-gnu": "14.1.0", "@next/swc-linux-arm64-musl": "14.1.0", "@next/swc-linux-x64-gnu": "14.1.0", "@next/swc-linux-x64-musl": "14.1.0", "@next/swc-win32-arm64-msvc": "14.1.0", "@next/swc-win32-ia32-msvc": "14.1.0", "@next/swc-win32-x64-msvc": "14.1.0" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "react": "^18.2.0", "react-dom": "^18.2.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "sass"], "bin": "dist/bin/next" }, "sha512-wlzrsbfeSU48YQBjZhDzOwhWhGsy+uQycR8bHAOt1LY1bn3zZEcDyHQOEoN3aWzQ8LHCAJ1nqrWCc9XF2+O45Q=="],
"node-releases": ["node-releases@2.0.14", "", {}, "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw=="],
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
"normalize-range": ["normalize-range@0.1.2", "", {}, "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA=="],
"npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="],
"nssocket": ["nssocket@0.6.0", "", { "dependencies": { "eventemitter2": "~0.4.14", "lazy": "~1.0.11" } }, "sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w=="],
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
"object-hash": ["object-hash@3.0.0", "", {}, "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw=="],
"on-headers": ["on-headers@1.0.2", "", {}, "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA=="],
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
"onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
"pac-proxy-agent": ["pac-proxy-agent@7.0.1", "", { "dependencies": { "@tootallnate/quickjs-emscripten": "^0.23.0", "agent-base": "^7.0.2", "debug": "^4.3.4", "get-uri": "^6.0.1", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", "pac-resolver": "^7.0.0", "socks-proxy-agent": "^8.0.2" } }, "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A=="],
"pac-resolver": ["pac-resolver@7.0.1", "", { "dependencies": { "degenerator": "^5.0.0", "netmask": "^2.0.2" } }, "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg=="],
"pako": ["pako@0.2.9", "", {}, "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA=="],
"path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="],
"path-is-inside": ["path-is-inside@1.0.2", "", {}, "sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w=="],
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
"path-scurry": ["path-scurry@1.10.1", "", { "dependencies": { "lru-cache": "^9.1.1 || ^10.0.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" } }, "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ=="],
"path-to-regexp": ["path-to-regexp@2.2.1", "", {}, "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ=="],
"picocolors": ["picocolors@1.0.0", "", {}, "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ=="],
"picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"pidusage": ["pidusage@3.0.2", "", { "dependencies": { "safe-buffer": "^5.2.1" } }, "sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w=="],
"pify": ["pify@2.3.0", "", {}, "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="],
"pirates": ["pirates@4.0.6", "", {}, "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg=="],
"pm2": ["pm2@5.3.1", "", { "dependencies": { "@pm2/agent": "~2.0.0", "@pm2/io": "~5.0.0", "@pm2/js-api": "~0.8.0", "@pm2/pm2-version-check": "latest", "async": "~3.2.0", "blessed": "0.1.81", "chalk": "3.0.0", "chokidar": "^3.5.3", "cli-tableau": "^2.0.0", "commander": "2.15.1", "croner": "~4.1.92", "dayjs": "~1.11.5", "debug": "^4.3.1", "enquirer": "2.3.6", "eventemitter2": "5.0.1", "fclone": "1.0.11", "mkdirp": "1.0.4", "needle": "2.4.0", "pidusage": "~3.0", "pm2-axon": "~4.0.1", "pm2-axon-rpc": "~0.7.1", "pm2-deploy": "~1.0.2", "pm2-multimeter": "^0.1.2", "promptly": "^2", "semver": "^7.2", "source-map-support": "0.5.21", "sprintf-js": "1.1.2", "vizion": "~2.2.1", "yamljs": "0.3.0" }, "optionalDependencies": { "pm2-sysmonit": "^1.2.8" }, "bin": { "pm2": "bin/pm2", "pm2-dev": "bin/pm2-dev", "pm2-docker": "bin/pm2-docker", "pm2-runtime": "bin/pm2-runtime" } }, "sha512-DLVQHpSR1EegaTaRH3KbRXxpPVaqYwAp3uHSCtCsS++LSErvk07WSxuUnntFblBRqNU/w2KQyqs12mSq5wurkg=="],
"pm2-axon": ["pm2-axon@4.0.1", "", { "dependencies": { "amp": "~0.3.1", "amp-message": "~0.1.1", "debug": "^4.3.1", "escape-string-regexp": "^4.0.0" } }, "sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg=="],
"pm2-axon-rpc": ["pm2-axon-rpc@0.7.1", "", { "dependencies": { "debug": "^4.3.1" } }, "sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw=="],
"pm2-deploy": ["pm2-deploy@1.0.2", "", { "dependencies": { "run-series": "^1.1.8", "tv4": "^1.3.0" } }, "sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg=="],
"pm2-multimeter": ["pm2-multimeter@0.1.2", "", { "dependencies": { "charm": "~0.1.1" } }, "sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA=="],
"pm2-sysmonit": ["pm2-sysmonit@1.2.8", "", { "dependencies": { "async": "^3.2.0", "debug": "^4.3.1", "pidusage": "^2.0.21", "systeminformation": "^5.7", "tx2": "~1.0.4" } }, "sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA=="],
"postcss": ["postcss@8.4.35", "", { "dependencies": { "nanoid": "^3.3.7", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-u5U8qYpBCpN13BsiEB0CbR1Hhh4Gc0zLFuedrHJKMctHCHAGrMdG0PRM/KErzAL3CU6/eckEtmHNB3x6e3c0vA=="],
"postcss-import": ["postcss-import@15.1.0", "", { "dependencies": { "postcss-value-parser": "^4.0.0", "read-cache": "^1.0.0", "resolve": "^1.1.7" }, "peerDependencies": { "postcss": "^8.0.0" } }, "sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew=="],
"postcss-js": ["postcss-js@4.0.1", "", { "dependencies": { "camelcase-css": "^2.0.1" }, "peerDependencies": { "postcss": "^8.4.21" } }, "sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw=="],
"postcss-load-config": ["postcss-load-config@4.0.2", "", { "dependencies": { "lilconfig": "^3.0.0", "yaml": "^2.3.4" }, "peerDependencies": { "postcss": ">=8.0.9", "ts-node": ">=9.0.0" }, "optionalPeers": ["ts-node"] }, "sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ=="],
"postcss-nested": ["postcss-nested@6.0.1", "", { "dependencies": { "postcss-selector-parser": "^6.0.11" }, "peerDependencies": { "postcss": "^8.2.14" } }, "sha512-mEp4xPMi5bSWiMbsgoPfcP74lsWLHkQbZc3sY+jWYd65CUwXrUaTp0fmNpa01ZcETKlIgUdFN/MpS2xZtqL9dQ=="],
"postcss-selector-parser": ["postcss-selector-parser@6.0.15", "", { "dependencies": { "cssesc": "^3.0.0", "util-deprecate": "^1.0.2" } }, "sha512-rEYkQOMUCEMhsKbK66tbEU9QVIxbhN18YiniAwA7XQYTVBqrBy+P2p5JcdqsHgKM2zWylp8d7J6eszocfds5Sw=="],
"postcss-value-parser": ["postcss-value-parser@4.2.0", "", {}, "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="],
"promptly": ["promptly@2.2.0", "", { "dependencies": { "read": "^1.0.4" } }, "sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA=="],
"proxy-agent": ["proxy-agent@6.3.1", "", { "dependencies": { "agent-base": "^7.0.2", "debug": "^4.3.4", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", "lru-cache": "^7.14.1", "pac-proxy-agent": "^7.0.1", "proxy-from-env": "^1.1.0", "socks-proxy-agent": "^8.0.2" } }, "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ=="],
"proxy-from-env": ["proxy-from-env@1.1.0", "", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
"range-parser": ["range-parser@1.2.0", "", {}, "sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A=="],
"rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": "cli.js" }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
"react": ["react@18.2.0", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ=="],
"react-dom": ["react-dom@18.2.0", "", { "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.0" }, "peerDependencies": { "react": "^18.2.0" } }, "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g=="],
"react-hook-form": ["react-hook-form@7.50.1", "", { "peerDependencies": { "react": "^16.8.0 || ^17 || ^18" } }, "sha512-3PCY82oE0WgeOgUtIr3nYNNtNvqtJ7BZjsbxh6TnYNbXButaD5WpjOmTjdxZfheuHKR68qfeFnEDVYoSSFPMTQ=="],
"react-redux": ["react-redux@9.1.0", "", { "dependencies": { "@types/use-sync-external-store": "^0.0.3", "use-sync-external-store": "^1.0.0" }, "peerDependencies": { "@types/react": "^18.2.25", "react": "^18.0", "react-native": ">=0.69", "redux": "^5.0.0" }, "optionalPeers": ["react-native"] }, "sha512-6qoDzIO+gbrza8h3hjMA9aq4nwVFCKFtY2iLxCtVT38Swyy2C/dJCGBXHeHLtx6qlg/8qzc2MrhOeduf5K32wQ=="],
"read": ["read@1.0.7", "", { "dependencies": { "mute-stream": "~0.0.4" } }, "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ=="],
"read-cache": ["read-cache@1.0.0", "", { "dependencies": { "pify": "^2.3.0" } }, "sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA=="],
"readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
"redux": ["redux@5.0.1", "", {}, "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w=="],
"redux-thunk": ["redux-thunk@3.1.0", "", { "peerDependencies": { "redux": "^5.0.0" } }, "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw=="],
"registry-auth-token": ["registry-auth-token@3.3.2", "", { "dependencies": { "rc": "^1.1.6", "safe-buffer": "^5.0.1" } }, "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ=="],
"registry-url": ["registry-url@3.1.0", "", { "dependencies": { "rc": "^1.0.1" } }, "sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA=="],
"require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
"require-in-the-middle": ["require-in-the-middle@5.2.0", "", { "dependencies": { "debug": "^4.1.1", "module-details-from-path": "^1.0.3", "resolve": "^1.22.1" } }, "sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg=="],
"reselect": ["reselect@5.1.0", "", {}, "sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg=="],
"resolve": ["resolve@1.22.8", "", { "dependencies": { "is-core-module": "^2.13.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": "bin/resolve" }, "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw=="],
"reusify": ["reusify@1.0.4", "", {}, "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="],
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
"run-series": ["run-series@1.1.9", "", {}, "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g=="],
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
"sax": ["sax@1.3.0", "", {}, "sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA=="],
"scheduler": ["scheduler@0.23.0", "", { "dependencies": { "loose-envify": "^1.1.0" } }, "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw=="],
"semver": ["semver@7.6.0", "", { "dependencies": { "lru-cache": "^6.0.0" }, "bin": "bin/semver.js" }, "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg=="],
"serve": ["serve@14.2.1", "", { "dependencies": { "@zeit/schemas": "2.29.0", "ajv": "8.11.0", "arg": "5.0.2", "boxen": "7.0.0", "chalk": "5.0.1", "chalk-template": "0.4.0", "clipboardy": "3.0.0", "compression": "1.7.4", "is-port-reachable": "4.0.0", "serve-handler": "6.1.5", "update-check": "1.5.4" }, "bin": "build/main.js" }, "sha512-48er5fzHh7GCShLnNyPBRPEjs2I6QBozeGr02gaacROiyS/8ARADlj595j39iZXAqBbJHH/ivJJyPRWY9sQWZA=="],
"serve-handler": ["serve-handler@6.1.5", "", { "dependencies": { "bytes": "3.0.0", "content-disposition": "0.5.2", "fast-url-parser": "1.1.3", "mime-types": "2.1.18", "minimatch": "3.1.2", "path-is-inside": "1.0.2", "path-to-regexp": "2.2.1", "range-parser": "1.2.0" } }, "sha512-ijPFle6Hwe8zfmBxJdE+5fta53fdIY0lHISJvuikXB3VYFafRjMRpOffSPvCYsbKyBA7pvy9oYr/BT1O3EArlg=="],
"sharp": ["sharp@0.33.2", "", { "dependencies": { "color": "^4.2.3", "detect-libc": "^2.0.2", "semver": "^7.5.4" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.33.2", "@img/sharp-darwin-x64": "0.33.2", "@img/sharp-libvips-darwin-arm64": "1.0.1", "@img/sharp-libvips-darwin-x64": "1.0.1", "@img/sharp-libvips-linux-arm": "1.0.1", "@img/sharp-libvips-linux-arm64": "1.0.1", "@img/sharp-libvips-linux-s390x": "1.0.1", "@img/sharp-libvips-linux-x64": "1.0.1", "@img/sharp-libvips-linuxmusl-arm64": "1.0.1", "@img/sharp-libvips-linuxmusl-x64": "1.0.1", "@img/sharp-linux-arm": "0.33.2", "@img/sharp-linux-arm64": "0.33.2", "@img/sharp-linux-s390x": "0.33.2", "@img/sharp-linux-x64": "0.33.2", "@img/sharp-linuxmusl-arm64": "0.33.2", "@img/sharp-linuxmusl-x64": "0.33.2", "@img/sharp-wasm32": "0.33.2", "@img/sharp-win32-ia32": "0.33.2", "@img/sharp-win32-x64": "0.33.2" } }, "sha512-WlYOPyyPDiiM07j/UO+E720ju6gtNtHjEGg5vovUk1Lgxyjm2LFO+37Nt/UI3MMh2l6hxTWQWi7qk3cXJTutcQ=="],
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
"shimmer": ["shimmer@1.2.1", "", {}, "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw=="],
"signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
"simple-swizzle": ["simple-swizzle@0.2.2", "", { "dependencies": { "is-arrayish": "^0.3.1" } }, "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg=="],
"smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="],
"socks": ["socks@2.8.3", "", { "dependencies": { "ip-address": "^9.0.5", "smart-buffer": "^4.2.0" } }, "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw=="],
"socks-proxy-agent": ["socks-proxy-agent@8.0.3", "", { "dependencies": { "agent-base": "^7.1.1", "debug": "^4.3.4", "socks": "^2.7.1" } }, "sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A=="],
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
"source-map-js": ["source-map-js@1.0.2", "", {}, "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw=="],
"source-map-support": ["source-map-support@0.5.21", "", { "dependencies": { "buffer-from": "^1.0.0", "source-map": "^0.6.0" } }, "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w=="],
"sprintf-js": ["sprintf-js@1.1.2", "", {}, "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug=="],
"streamsearch": ["streamsearch@1.1.0", "", {}, "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg=="],
"string-width": ["string-width@5.1.2", "", { "dependencies": { "eastasianwidth": "^0.2.0", "emoji-regex": "^9.2.2", "strip-ansi": "^7.0.1" } }, "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA=="],
"string-width-cjs": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"strip-ansi": ["strip-ansi@7.1.0", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ=="],
"strip-ansi-cjs": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="],
"strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
"styled-jsx": ["styled-jsx@5.1.1", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0" } }, "sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw=="],
"sucrase": ["sucrase@3.35.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.2", "commander": "^4.0.0", "glob": "^10.3.10", "lines-and-columns": "^1.1.6", "mz": "^2.7.0", "pirates": "^4.0.1", "ts-interface-checker": "^0.1.9" }, "bin": { "sucrase": "bin/sucrase", "sucrase-node": "bin/sucrase-node" } }, "sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA=="],
"supercluster": ["supercluster@8.0.1", "", { "dependencies": { "kdbush": "^4.0.2" } }, "sha512-IiOea5kJ9iqzD2t7QJq/cREyLHTtSmUT6gQsweojg9WH2sYJqZK9SswTu6jrscO6D1G5v5vYZ9ru/eq85lXeZQ=="],
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
"swiper": ["swiper@11.0.6", "", {}, "sha512-W/Me7MQl5rNgdM5x9i3Gll76WsyVpnHn91GhBOyL7RCFUeg62aVnflzlVfIpXzZ/87FtJOfAoDH79ZH2Yq76zA=="],
"systeminformation": ["systeminformation@5.22.7", "", { "os": "!aix", "bin": "lib/cli.js" }, "sha512-AWxlP05KeHbpGdgvZkcudJpsmChc2Y5Eo/GvxG/iUA/Aws5LZKHAMSeAo+V+nD+nxWZaxrwpWcnx4SH3oxNL3A=="],
"tailwindcss": ["tailwindcss@3.4.1", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.5.3", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.3.0", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.19.1", "lilconfig": "^2.1.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", "postcss": "^8.4.23", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.1", "postcss-nested": "^6.0.1", "postcss-selector-parser": "^6.0.11", "resolve": "^1.22.2", "sucrase": "^3.32.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-qAYmXRfk3ENzuPBakNK0SRrUDipP8NQnEY6772uDhflcQz5EhRdD7JNZxyrFHVQNCwULPBn6FNPp9brpO7ctcA=="],
"thenify": ["thenify@3.3.1", "", { "dependencies": { "any-promise": "^1.0.0" } }, "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw=="],
"thenify-all": ["thenify-all@1.6.0", "", { "dependencies": { "thenify": ">= 3.1.0 < 4" } }, "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA=="],
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
"tslib": ["tslib@2.6.2", "", {}, "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q=="],
"tv4": ["tv4@1.3.0", "", {}, "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw=="],
"tx2": ["tx2@1.0.5", "", { "dependencies": { "json-stringify-safe": "^5.0.1" } }, "sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg=="],
"type-fest": ["type-fest@2.19.0", "", {}, "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA=="],
"typescript": ["typescript@5.3.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw=="],
"undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
"update-browserslist-db": ["update-browserslist-db@1.0.13", "", { "dependencies": { "escalade": "^3.1.1", "picocolors": "^1.0.0" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": "cli.js" }, "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg=="],
"update-check": ["update-check@1.5.4", "", { "dependencies": { "registry-auth-token": "3.3.2", "registry-url": "3.1.0" } }, "sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ=="],
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
"use-debounce": ["use-debounce@10.0.0", "", { "peerDependencies": { "react": ">=16.8.0" } }, "sha512-XRjvlvCB46bah9IBXVnq/ACP2lxqXyZj0D9hj4K5OzNroMDpTEBg8Anuh1/UfRTRs7pLhQ+RiNxxwZu9+MVl1A=="],
"use-sync-external-store": ["use-sync-external-store@1.2.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA=="],
"usehooks-ts": ["usehooks-ts@3.1.0", "", { "dependencies": { "lodash.debounce": "^4.0.8" }, "peerDependencies": { "react": "^16.8.0 || ^17 || ^18" } }, "sha512-bBIa7yUyPhE1BCc0GmR96VU/15l/9gP1Ch5mYdLcFBaFGQsdmXkvjV0TtOqW1yUd6VjIwDunm+flSciCQXujiw=="],
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
"uuid": ["uuid@9.0.1", "", { "bin": "dist/bin/uuid" }, "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA=="],
"vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
"vizion": ["vizion@2.2.1", "", { "dependencies": { "async": "^2.6.3", "git-node-fs": "^1.0.0", "ini": "^1.3.5", "js-git": "^0.7.8" } }, "sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww=="],
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
"widest-line": ["widest-line@4.0.1", "", { "dependencies": { "string-width": "^5.0.1" } }, "sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig=="],
"wrap-ansi": ["wrap-ansi@8.1.0", "", { "dependencies": { "ansi-styles": "^6.1.0", "string-width": "^5.0.1", "strip-ansi": "^7.0.1" } }, "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ=="],
"wrap-ansi-cjs": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
"ws": ["ws@7.4.6", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": "^5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A=="],
"yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
"yaml": ["yaml@2.3.4", "", {}, "sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA=="],
"yamljs": ["yamljs@0.3.0", "", { "dependencies": { "argparse": "^1.0.7", "glob": "^7.0.5" }, "bin": { "json2yaml": "bin/json2yaml", "yaml2json": "bin/yaml2json" } }, "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ=="],
"zod": ["zod@3.22.4", "", {}, "sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg=="],
"@opencensus/core/semver": ["semver@5.7.2", "", { "bin": "bin/semver" }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="],
"@opencensus/core/uuid": ["uuid@3.4.0", "", { "bin": "bin/uuid" }, "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="],
"@opencensus/propagation-b3/@opencensus/core": ["@opencensus/core@0.0.8", "", { "dependencies": { "continuation-local-storage": "^3.2.1", "log-driver": "^1.2.7", "semver": "^5.5.0", "shimmer": "^1.2.0", "uuid": "^3.2.1" } }, "sha512-yUFT59SFhGMYQgX0PhoTR0LBff2BEhPrD9io1jWfF/VDbakRfs6Pq60rjv0Z7iaTav5gQlttJCX2+VPxFWCuoQ=="],
"@opencensus/propagation-b3/uuid": ["uuid@3.4.0", "", { "bin": "bin/uuid" }, "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A=="],
"@pm2/agent/chalk": ["chalk@3.0.0", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="],
"@pm2/agent/dayjs": ["dayjs@1.8.36", "", {}, "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw=="],
"@pm2/agent/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"@pm2/agent/semver": ["semver@7.5.4", "", { "dependencies": { "lru-cache": "^6.0.0" }, "bin": "bin/semver.js" }, "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA=="],
"@pm2/io/async": ["async@2.6.4", "", { "dependencies": { "lodash": "^4.17.14" } }, "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA=="],
"@pm2/io/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"@pm2/io/eventemitter2": ["eventemitter2@6.4.9", "", {}, "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg=="],
"@pm2/io/semver": ["semver@7.5.4", "", { "dependencies": { "lru-cache": "^6.0.0" }, "bin": "bin/semver.js" }, "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA=="],
"@pm2/io/tslib": ["tslib@1.9.3", "", {}, "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ=="],
"@pm2/js-api/async": ["async@2.6.4", "", { "dependencies": { "lodash": "^4.17.14" } }, "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA=="],
"@pm2/js-api/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"@pm2/js-api/eventemitter2": ["eventemitter2@6.4.9", "", {}, "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg=="],
"@pm2/pm2-version-check/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"accepts/mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
"agent-base/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"ansi-align/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"argparse/sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="],
"async-listener/semver": ["semver@5.7.2", "", { "bin": "bin/semver" }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="],
"boxen/chalk": ["chalk@5.0.1", "", {}, "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w=="],
"chalk-template/chalk": ["chalk@4.1.2", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA=="],
"chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"cli-tableau/chalk": ["chalk@3.0.0", "", { "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" } }, "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg=="],
"compression/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
"compression/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
"execa/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"fast-url-parser/punycode": ["punycode@1.4.1", "", {}, "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="],
"foreground-child/signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
"get-uri/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"glob/minimatch": ["minimatch@9.0.3", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg=="],
"http-proxy-agent/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"https-proxy-agent/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"ip-address/sprintf-js": ["sprintf-js@1.1.3", "", {}, "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA=="],
"mime-types/mime-db": ["mime-db@1.33.0", "", {}, "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="],
"needle/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
"next/postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
"nssocket/eventemitter2": ["eventemitter2@0.4.14", "", {}, "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ=="],
"pac-proxy-agent/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"path-scurry/lru-cache": ["lru-cache@10.2.0", "", {}, "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q=="],
"pm2-axon/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"pm2-axon-rpc/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"pm2-sysmonit/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"pm2-sysmonit/pidusage": ["pidusage@2.0.21", "", { "dependencies": { "safe-buffer": "^5.2.1" } }, "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA=="],
"postcss-load-config/lilconfig": ["lilconfig@3.1.1", "", {}, "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ=="],
"proxy-agent/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"proxy-agent/lru-cache": ["lru-cache@7.18.3", "", {}, "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA=="],
"registry-auth-token/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
"require-in-the-middle/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"serve/chalk": ["chalk@5.0.1", "", {}, "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w=="],
"socks-proxy-agent/debug": ["debug@4.3.4", "", { "dependencies": { "ms": "2.1.2" } }, "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ=="],
"string-width-cjs/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"string-width-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"strip-ansi-cjs/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"sucrase/commander": ["commander@4.1.1", "", {}, "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA=="],
"vizion/async": ["async@2.6.4", "", { "dependencies": { "lodash": "^4.17.14" } }, "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA=="],
"wrap-ansi/ansi-styles": ["ansi-styles@6.2.1", "", {}, "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="],
"wrap-ansi-cjs/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"wrap-ansi-cjs/string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"wrap-ansi-cjs/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"yamljs/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
"@opencensus/propagation-b3/@opencensus/core/semver": ["semver@5.7.2", "", { "bin": "bin/semver" }, "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g=="],
"@pm2/agent/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"@pm2/agent/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"@pm2/agent/semver/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
"@pm2/io/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"@pm2/io/semver/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
"@pm2/js-api/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"@pm2/pm2-version-check/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"agent-base/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"ansi-align/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"ansi-align/string-width/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"chalk-template/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"cli-tableau/chalk/ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"compression/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"get-uri/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"glob/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
"http-proxy-agent/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"https-proxy-agent/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"needle/debug/ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"pac-proxy-agent/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"pm2-axon-rpc/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"pm2-axon/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"pm2-sysmonit/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"pm2-sysmonit/pidusage/safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
"proxy-agent/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"require-in-the-middle/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"socks-proxy-agent/debug/ms": ["ms@2.1.2", "", {}, "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="],
"string-width-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"wrap-ansi-cjs/string-width/emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"wrap-ansi-cjs/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"yamljs/glob/minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"ansi-align/string-width/strip-ansi/ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"yamljs/glob/minimatch/brace-expansion": ["brace-expansion@1.1.11", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA=="],
}
}

View File

@ -2,9 +2,9 @@
import React from "react"; import React from "react";
import { BreadCrumbs } from "../ui/bread-crumbs"; import { BreadCrumbs } from "../ui/bread-crumbs";
import { usePathname } from "next/navigation"; import { useTranslations } from "next-intl";
import { useAppSelector } from "@/redux/hooks";
import { Title } from "../ui/title"; import { Title } from "../ui/title";
import { usePathname } from "@/i18n/navigation";
interface Props { interface Props {
title: string; title: string;
@ -26,20 +26,14 @@ export const LayoutWithSidebar = ({
cursor = false, cursor = false,
}: Props) => { }: Props) => {
const pathname = usePathname(); const pathname = usePathname();
const lang = useAppSelector( const t = useTranslations("services");
(state) => state.headerSlice.activeLang.localization
);
return ( return (
<div className="flex bg-white px-6 py-4 rounded-lg flex-col md:gap-6 gap-10 section-mb w-full"> <div className="flex bg-white px-6 py-4 rounded-lg flex-col md:gap-6 gap-10 section-mb w-full">
<div> <div>
<BreadCrumbs <BreadCrumbs
second={ second={
pathname.includes("/services") pathname.includes("/services") ? t("breadcrumb") : second ?? ""
? lang === "en"
? "Services"
: "Сервисы"
: second ?? ""
} }
path={path} path={path}
path2={path2} path2={path2}

View File

@ -1,19 +0,0 @@
"use client";
import React from "react";
import Link from "next/link";
import { topMenu } from "@/lib/database/pathnames";
export const Pathnames = ({ sort }: { sort: string }) => {
return (
<div className="text-[12px] text-gray4 flex items-center mob:mb-6 mb-5">
<Link href={"/"}>{"Главная "}</Link>
{topMenu
.filter((item) => item.path === sort)
.map((obj, i) =>
obj.links.map((item) => <p key={i}>{item.default}</p>)
)}
</div>
);
};

View File

@ -1,6 +1,6 @@
import React from "react"; import React from "react";
import Image from "next/image"; import Image from "next/image";
import Link from "next/link"; import { Link } from "@/i18n/navigation";
interface Props { interface Props {
img: string; img: string;

View File

@ -1,18 +1,20 @@
import { getEvents } from "@/services/home"; import { getTranslations } from "next-intl/server";
import { EventsMobile } from "./events-mobile";
const events = [ const events = [
{ {
link: "https://kids.turkmenexpo.com/",
video: video:
"https://editor.turkmenexpo.com/storage/app/media/video/KidsExpo%202024_%20Turkmenistan.mp4", "https://editor.turkmenexpo.com/storage/app/media/video/KidsExpo%202024_%20Turkmenistan.mp4",
logo: "https://kids.turkmenexpo.com/logo.svg", logo: "https://kids.turkmenexpo.com/logo.svg",
}, },
{ {
link: "https://turkmentextile.turkmenexpo.com/",
video: video:
"https://turkmentextile.turkmenexpo.com/app/storage/app/media/video/Textile2025.mp4", "https://turkmentextile.turkmenexpo.com/app/storage/app/media/video/Textile2025.mp4",
logo: "/assets/icons/turkmen-textile.png", logo: "/assets/icons/turkmen-textile.png",
}, },
{ {
link: "https://itse.turkmenexpo.com/",
video: video:
"https://itse.turkmenexpo.com/app/storage/app/media/video/itse2025.mp4", "https://itse.turkmenexpo.com/app/storage/app/media/video/itse2025.mp4",
logo: "https://itse.turkmenexpo.com/logo.svg", logo: "https://itse.turkmenexpo.com/logo.svg",
@ -20,44 +22,18 @@ const events = [
]; ];
export const Events = async ({ lang }: { lang: string }) => { export const Events = async ({ lang }: { lang: string }) => {
const data = await getEvents(lang); const t = await getTranslations("home");
const btnText =
lang === "en" ? "Show more" : lang === "ru" ? "Показать еще" : "Show more";
const title = lang === "en" ? "Exhibitions" : "Выставки";
const linkText = lang === "en" ? "Go to website" : "Перейти на сайт";
return ( return (
<section> <section>
<div className="container md:block"> <div className="container md:block">
<div className="sm:mb-10"> <div className="sm:mb-10">
<h2 className="text-center font-semibold text-3xl mb-8"> <h2 className="text-center font-semibold text-3xl mb-8">
{title} <span className="text-PRIMARY">Turkmen</span> {t("exhibitions")} <span className="text-PRIMARY">Turkmen</span>
<span className="text-red">Expo</span> <span className="text-red">Expo 2025</span>
</h2> </h2>
{/* <Title
text={
lang === "en"
? "Upcoming exhibitions and events"
: lang === "ru"
? "Ближайшие выставки и мероприятия"
: "Upcoming exhibitions and events"
}
/> */}
</div> </div>
{/* <div className="w-full flex flex-col items-center gap-8"> */}
<div className="w-full flex flex-col items-center gap-8 lg:flex-row"> <div className="w-full flex flex-col items-center gap-8 lg:flex-row">
{/* {data.data.slice(0, 2).map((item, i) => (
<EventCard
coorganizers={item.coorganizers}
dark
key={i}
{...item}
/>
))}
<LinkButton href="/calendar">{btnText}</LinkButton> */}
{events.map((item, i) => ( {events.map((item, i) => (
<article <article
key={i} key={i}
@ -81,19 +57,17 @@ export const Events = async ({ lang }: { lang: string }) => {
className="h-10 w-auto object-cover" className="h-10 w-auto object-cover"
/> />
<a <a
href={events[0].logo.slice(0, -8)} href={events[i].link}
target="_blank" target="_blank"
className="text-PRIMARY underline" className="text-PRIMARY underline"
> >
{linkText} {t("goToWebsite")}
</a> </a>
</div> </div>
</article> </article>
))} ))}
</div> </div>
</div> </div>
{/* <EventsMobile data={data.data.slice(0, 5)} /> */}
</section> </section>
); );
}; };

View File

@ -1,11 +1,10 @@
"use client"; "use client";
import React from "react"; import React from "react";
import Link from "next/link"; import { useTranslations } from "next-intl";
import { footerInfo, headerMenu2 } from "@/lib/database/pathnames"; import { headerMenu2 } from "@/lib/database/pathnames";
import { useAppSelector } from "@/redux/hooks"; import { Link } from "@/i18n/navigation";
import clsx from "clsx";
export const socials = [ export const socials = [
{ href: "https://www.linkedin.com/company/turkmen-expo", icon: "linkedin" }, { href: "https://www.linkedin.com/company/turkmen-expo", icon: "linkedin" },
@ -24,9 +23,7 @@ export const socials = [
]; ];
export const Footer = () => { export const Footer = () => {
const localization = useAppSelector( const t = useTranslations();
(state) => state.headerSlice.activeLang.localization
);
return ( return (
<footer className="bg-PRIMARY text-white pt-6 pb-5 mob:py-[40px]"> <footer className="bg-PRIMARY text-white pt-6 pb-5 mob:py-[40px]">
@ -36,11 +33,9 @@ export const Footer = () => {
<img className="h-12" src="/assets/icons/white-logo.svg" /> <img className="h-12" src="/assets/icons/white-logo.svg" />
<div className="flex flex-col mt-8 lg:flex-row items-center font-medium gap-12"> <div className="flex flex-col mt-8 lg:flex-row items-center font-medium gap-12">
{headerMenu2 {headerMenu2.map((item, i) => (
.filter((item) => (localization === "en" ? item.en : !item.en))
.map((item, i) => (
<Link key={i} href={item.link} className="cursor-pointer"> <Link key={i} href={item.link} className="cursor-pointer">
{item.title} {t(item.titleKey)}
</Link> </Link>
))} ))}
</div> </div>
@ -48,28 +43,20 @@ export const Footer = () => {
<div className="flex flex-col lg:flex-row lg:justify-between justify-center text-center lg:text-left lg:items-end items-center gap-6"> <div className="flex flex-col lg:flex-row lg:justify-between justify-center text-center lg:text-left lg:items-end items-center gap-6">
<div className="flex flex-col justify-end w-full"> <div className="flex flex-col justify-end w-full">
{localization === "ru" ? (
<div className="flex flex-col md:gap-y-[10px] gap-2"> <div className="flex flex-col md:gap-y-[10px] gap-2">
{footerInfo.slice(0, 4).map((item, i) => ( <p className="text-[12px] leading-[130%]">
<p {t("footer.address")}
className={clsx("text-[12px] leading-[130%]", {
"ml-8": i === 2,
})}
key={i}
>
{item}
</p> </p>
))} <p className="text-[12px] leading-[130%]">
</div> {t("footer.phone")}
) : localization === "en" ? ( </p>
<div className="flex flex-col md:gap-y-[10px] gap-0"> <p className="text-[12px] leading-[130%] ml-8">
{footerInfo.slice(3, 7).map((item, i) => ( {t("footer.phone2")}
<p className="text-[12px] leading-[130%]" key={i}> </p>
{item} <p className="text-[12px] leading-[130%]">
{t("footer.email")}
</p> </p>
))}
</div> </div>
) : null}
</div> </div>
<div className="flex items-center gap-6"> <div className="flex items-center gap-6">

View File

@ -1,32 +1,30 @@
"use client"; "use client";
import React, { Suspense, useEffect, useState } from "react"; import React, { Suspense, useState } from "react";
import clsx from "clsx"; import clsx from "clsx";
import Link from "next/link";
import Image from "next/image"; import Image from "next/image";
import { AnimatePresence } from "framer-motion"; import { AnimatePresence } from "framer-motion";
import { useTranslations } from "next-intl";
import logo from "@/public/assets/icons/logo.svg"; import logo from "@/public/assets/icons/logo.svg";
import search from "@/public/assets/icons/header/search.svg"; import search from "@/public/assets/icons/header/search.svg";
import searchMob from "@/public/assets/icons/header/mob-search.svg"; import searchMob from "@/public/assets/icons/header/mob-search.svg";
import { LangMenu } from "../ui/lang-menu"; import { LangMenu } from "../ui/LangMenu";
import { SearchInput } from "./search-input"; import { SearchInput } from "./search-input";
import { headerMenu2 } from "@/lib/database/pathnames"; import { headerMenu2 } from "@/lib/database/pathnames";
import { BurgerMenu } from "../ui/burger-menu"; import { BurgerMenu } from "../ui/burger-menu";
import { useAppDispatch, useAppSelector } from "@/redux/hooks"; import { useAppDispatch, useAppSelector } from "@/redux/hooks";
import { selectHeader, setShowInput } from "@/redux/slices/headerSlice"; import { selectHeader, setShowInput } from "@/redux/slices/headerSlice";
import { selectBurger, setBurgerOpen } from "@/redux/slices/burgerSlice"; import { selectBurger, setBurgerOpen } from "@/redux/slices/burgerSlice";
import { useStorage } from "@/hooks/useStorage"; import { Link } from "@/i18n/navigation";
import { usePathname, useRouter } from "next/navigation";
export const Header = () => { export const Header = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const { showInput } = useAppSelector(selectHeader); const { showInput } = useAppSelector(selectHeader);
const { burgerOpen } = useAppSelector(selectBurger); const { burgerOpen } = useAppSelector(selectBurger);
const { activeLang } = useAppSelector(selectHeader);
const [activeLink, setActiveLink] = useState(""); const [activeLink, setActiveLink] = useState("");
const pathname = usePathname(); const t = useTranslations();
const toggleMenu = () => { const toggleMenu = () => {
dispatch(setBurgerOpen(!burgerOpen)); dispatch(setBurgerOpen(!burgerOpen));
@ -38,12 +36,6 @@ export const Header = () => {
dispatch(setBurgerOpen(false)); dispatch(setBurgerOpen(false));
}; };
const { setItem } = useStorage("language");
useEffect(() => {
setItem(activeLang);
}, [activeLang]);
return ( return (
<> <>
<AnimatePresence> <AnimatePresence>
@ -54,21 +46,17 @@ export const Header = () => {
)} )}
</AnimatePresence> </AnimatePresence>
{/* Mobile */} <div className="h-[70px]">
<header <header
className={clsx( className={clsx(
"bg-[#EEF1F0] border-b border-[#DFE2E1] tab:hidden relative z-[50] flex items-center justify-between px-4 py-6", "bg-[#EEF1F0] border-b z-30 border-[#DFE2E1] tab:hidden fixed top-0 left-0 right-0 flex items-center justify-between px-4 py-6"
{
// 'fixed w-full top-0': burgerOpen,
}
)} )}
> >
<Image <Image
src={searchMob} src={searchMob}
height={32} height={32}
width={32} width={32}
alt="поиск" alt="search"
className="cursor-pointer" className="cursor-pointer"
onClick={onSearch} onClick={onSearch}
/> />
@ -84,7 +72,7 @@ export const Header = () => {
src={logo} src={logo}
height={24} height={24}
width={160} width={160}
alt="лого" alt="logo"
className="cursor-pointer" className="cursor-pointer"
/> />
</Link> </Link>
@ -122,9 +110,7 @@ export const Header = () => {
<AnimatePresence>{burgerOpen && <BurgerMenu />}</AnimatePresence> <AnimatePresence>{burgerOpen && <BurgerMenu />}</AnimatePresence>
</header> </header>
{/* Desktop */} <header className="hidden border-b border-[#DFE2E1] fixed top-0 left-0 right-0 z-30 tab:flex flex-col">
<header className="hidden border-b border-[#DFE2E1] relative z-[3000] tab:flex flex-col">
<div className="bg-[#EEF1F0] text-black"> <div className="bg-[#EEF1F0] text-black">
<div className="container py-[17px] flex items-center justify-between"> <div className="container py-[17px] flex items-center justify-between">
<div className="flex items-center"> <div className="flex items-center">
@ -137,7 +123,7 @@ export const Header = () => {
</Suspense> </Suspense>
<Image <Image
src={search} src={search}
alt="поиск" alt="search"
onClick={() => dispatch(setShowInput(true))} onClick={() => dispatch(setShowInput(true))}
className="cursor-pointer" className="cursor-pointer"
/> />
@ -145,23 +131,20 @@ export const Header = () => {
</div> </div>
<nav className="flex items-center gap-x-5 font-medium"> <nav className="flex items-center gap-x-5 font-medium">
{headerMenu2 {headerMenu2.map((item, i) => (
.filter((item) =>
activeLang.localization === "en" ? item.en : !item.en
)
.map((item, i) => (
<Link <Link
key={i} key={i}
href={item.link} href={item.link}
onClick={() => setActiveLink(item.link)} onClick={() => setActiveLink(item.link)}
> >
{item.title} {t(item.titleKey)}
</Link> </Link>
))} ))}
</nav> </nav>
</div> </div>
</div> </div>
</header> </header>
</div>
</> </>
); );
}; };

View File

@ -7,8 +7,6 @@ import { Navigation } from "swiper/modules";
import { NewsCard } from "./news-card"; import { NewsCard } from "./news-card";
import { NavBtn } from "../home/ui/NavBtn"; import { NavBtn } from "../home/ui/NavBtn";
import { useAppSelector } from "@/redux/hooks";
import { selectHeader } from "@/redux/slices/headerSlice";
import { NewsData } from "@/lib/types/NewsData.type"; import { NewsData } from "@/lib/types/NewsData.type";
import "swiper/css/bundle"; import "swiper/css/bundle";
@ -17,17 +15,18 @@ import "swiper/css";
import "swiper/css/navigation"; import "swiper/css/navigation";
import "swiper/css/pagination"; import "swiper/css/pagination";
import "swiper/css/scrollbar"; import "swiper/css/scrollbar";
import Link from "next/link"; import { useTranslations, useLocale } from "next-intl";
import { useLang } from "@/utils/useLang";
import { GreenBtn } from "../ui/Buttons"; import { GreenBtn } from "../ui/Buttons";
import { Title } from "../ui/title"; import { Title } from "../ui/title";
import Loader from "@/components/ui/Loader"; import Loader from "@/components/ui/Loader";
import { Link } from "@/i18n/navigation";
export const News = () => { export const News = () => {
const [newsData, setNewsData] = useState<NewsData>(); const [newsData, setNewsData] = useState<NewsData>();
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const { activeLang } = useAppSelector(selectHeader); const t = useTranslations("home");
const locale = useLocale();
const fetchNews = async () => { const fetchNews = async () => {
try { try {
@ -35,7 +34,7 @@ export const News = () => {
const response = await fetch(`https://turkmenexpo.com/app/api/v1/news`, { const response = await fetch(`https://turkmenexpo.com/app/api/v1/news`, {
next: { revalidate: 1800 }, next: { revalidate: 1800 },
headers: { headers: {
"Accept-Language": activeLang.localization, "Accept-Language": locale,
}, },
}); });
@ -54,7 +53,7 @@ export const News = () => {
useEffect(() => { useEffect(() => {
fetchNews(); fetchNews();
}, [activeLang.localization]); }, [locale]);
if (loading) { if (loading) {
<Loader className="h-[300px] w-full mx-auto" />; <Loader className="h-[300px] w-full mx-auto" />;
@ -64,7 +63,7 @@ export const News = () => {
<section> <section>
<div className="container w-full"> <div className="container w-full">
<header className="flex items-center mb-5 sm:mb-[43px] justify-between"> <header className="flex items-center mb-5 sm:mb-[43px] justify-between">
<Title text={useLang("News", "Новости", activeLang.localization)} /> <Title text={t("news")} />
<div className="hidden sm:flex items-center gap-5"> <div className="hidden sm:flex items-center gap-5">
<NavBtn left /> <NavBtn left />
<NavBtn /> <NavBtn />
@ -105,9 +104,7 @@ export const News = () => {
</div> </div>
<Link href={"/news"} className="hidden sm:flex justify-center"> <Link href={"/news"} className="hidden sm:flex justify-center">
<GreenBtn <GreenBtn text={t("allNews")} />
text={useLang("All news", "Все новости", activeLang.localization)}
/>
</Link> </Link>
</div> </div>
</section> </section>

View File

@ -5,22 +5,21 @@ import Image from "next/image";
import { Swiper, SwiperSlide } from "swiper/react"; import { Swiper, SwiperSlide } from "swiper/react";
import { Autoplay, Pagination } from "swiper/modules"; import { Autoplay, Pagination } from "swiper/modules";
import { useAppSelector } from "@/redux/hooks";
import { selectHeader } from "@/redux/slices/headerSlice";
import { PartnersType } from "@/lib/types/PartnersData.type"; import { PartnersType } from "@/lib/types/PartnersData.type";
import { baseAPI } from "@/lib/API"; import { baseAPI } from "@/lib/API";
import { useLang } from "@/utils/useLang"; import { useTranslations, useLocale } from "next-intl";
import { Title } from "../ui/title"; import { Title } from "../ui/title";
export const Partners = () => { export const Partners = () => {
const { activeLang } = useAppSelector(selectHeader); const locale = useLocale();
const t = useTranslations("home");
const [partnersData, setPartnersData] = useState<PartnersType>(); const [partnersData, setPartnersData] = useState<PartnersType>();
const fetchPartners = async () => { const fetchPartners = async () => {
try { try {
const res = await fetch(`${baseAPI}partners`, { const res = await fetch(`${baseAPI}partners`, {
headers: { headers: {
"Accept-Language": activeLang.localization, "Accept-Language": locale,
}, },
}); });
@ -34,14 +33,12 @@ export const Partners = () => {
useEffect(() => { useEffect(() => {
fetchPartners(); fetchPartners();
}, [activeLang.localization]); }, [locale]);
return ( return (
<section className="container"> <section className="container">
<div className="mb-[40px]"> <div className="mb-[40px]">
<Title <Title text={t("partners")} />
text={useLang("Partners", "Партнёры", activeLang.localization)}
/>
</div> </div>
<div className="flex items-center"> <div className="flex items-center">

View File

@ -0,0 +1,84 @@
"use client";
import { Swiper, SwiperSlide } from "swiper/react";
import { Autoplay, Pagination } from "swiper/modules";
import "swiper/css";
import "swiper/css/pagination";
import { useFetch } from "@/hooks/useFetch";
import { ReviewsType } from "@/lib/types/Reviews.type";
import { useTranslations } from "next-intl";
import { Title } from "../ui/title";
import Image from "next/image";
export const Reviews = () => {
const { data } = useFetch<ReviewsType>("reviews");
const t = useTranslations("home");
return (
<section className="container my-20 pb-20 overflow-hidden">
<Title text={t("feedback")} className="!text-center mb-10" />
<div className="max-w-[1200px] mx-auto px-4 md:px-0">
<Swiper
modules={[Autoplay, Pagination]}
style={{ overflow: "visible" }}
freeMode
speed={1000}
pagination={{
clickable: true,
el: ".custom-pagination",
bulletClass:
"dot transition-all duration-300 bg-gray-300 rounded-full w-3 h-3 mx-1",
bulletActiveClass: "dot-active !bg-PRIMARY scale-125",
}}
spaceBetween={24}
slidesPerView={3}
slidesPerGroup={3}
breakpoints={{
0: { slidesPerView: 1, slidesPerGroup: 1, spaceBetween: 16 },
768: { slidesPerView: 2, slidesPerGroup: 2, spaceBetween: 20 },
1024: { slidesPerView: 3, slidesPerGroup: 3, spaceBetween: 24 },
}}
className="testimonials-swiper"
>
{data?.data?.map((item, i) => (
<SwiperSlide
key={item?.id ?? i}
className="flex-[0_0_auto] min-h-[300px] pb-10 h-full flex items-stretch relative"
>
<article className="bg-white p-10 size-full rounded-[38px] flex flex-col gap-5 h-full flex-1">
<Image
src="/assets/icons/quotes.svg"
alt=""
height={35}
width={35}
/>
<p className="text-sm text-[#171C1B]">{item?.text}</p>
<div className="flex flex-col gap-5 items-center absolute left-1/2 -translate-x-1/2 top-[82%]">
<div className="flex justify-center items-center overflow-hidden rounded-full border-4 border-PRIMARY size-[70px]">
<Image
src={item?.image?.path ?? ""}
alt={item?.name}
height={50}
width={50}
className="obejct-contain"
/>
</div>
<div className="text-center flex flex-col gap-1.5">
<h3 className="text-base font-bold">{item?.name}</h3>
<p className="text-sm">{item?.job_title}</p>
</div>
</div>
</article>
</SwiperSlide>
))}
</Swiper>
<div className="custom-pagination flex justify-center items-center mt-60"></div>
</div>
</section>
);
};

View File

@ -14,7 +14,7 @@ import { useMediaQuery } from "usehooks-ts";
import { Autoplay, Pagination } from "swiper/modules"; import { Autoplay, Pagination } from "swiper/modules";
import Loader from "../ui/Loader"; import Loader from "../ui/Loader";
import { baseAPI } from "@/lib/API"; import { baseAPI } from "@/lib/API";
import Link from "next/link"; import { Link } from "@/i18n/navigation";
import clsx from "clsx"; import clsx from "clsx";
export const Slider = ({ lang }: { lang: string }) => { export const Slider = ({ lang }: { lang: string }) => {
@ -59,7 +59,7 @@ export const Slider = ({ lang }: { lang: string }) => {
<Swiper <Swiper
modules={[Autoplay, Pagination]} modules={[Autoplay, Pagination]}
loop loop
autoplay={{ delay: 3000 }} autoplay={{ delay: 5000 }}
speed={5000} speed={5000}
slidesPerView={1} slidesPerView={1}
slidesPerGroup={1} slidesPerGroup={1}
@ -73,6 +73,14 @@ export const Slider = ({ lang }: { lang: string }) => {
target="_blank" target="_blank"
className="size-full" className="size-full"
> >
{item.image.includes(".mp4") ? (
<video
src={item.image}
className="size-full object-contain"
autoPlay
muted
/>
) : (
<Image <Image
ref={imgRef} ref={imgRef}
height={600} height={600}
@ -81,6 +89,7 @@ export const Slider = ({ lang }: { lang: string }) => {
alt={item?.title} alt={item?.title}
className="object-contain size-full" className="object-contain size-full"
/> />
)}
</Link> </Link>
</SwiperSlide> </SwiperSlide>
))} ))}

View File

@ -1,28 +1,36 @@
"use client"; "use client";
import { FC, useState } from "react"; import { FC, useState } from "react";
import { Form, useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod"; import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod"; import { z } from "zod";
import clsx from "clsx"; import clsx from "clsx";
import { postContacts } from "@/services/contacts"; import { postContacts } from "@/services/contacts";
import { useTranslations } from "next-intl";
interface Props { interface Props {
className?: string; className?: string;
} }
const formSchema = z.object({ export type FormType = {
name: z.string().min(2, "Имя необходимо"), name: string;
email: z.string().email("Email необходим"), email: string;
phone: z.string().min(8, "Номер телефона необходим"), phone: string;
company: z.string().optional(), company?: string;
msg: z.string().min(5, "Сообщение необходимо"), msg: string;
}); };
export type FormType = z.infer<typeof formSchema>;
export const ContactsForm: FC<Props> = ({ className }) => { export const ContactsForm: FC<Props> = ({ className }) => {
const [status, setStatus] = useState(false); const [status, setStatus] = useState(false);
const t = useTranslations();
const formSchema = z.object({
name: z.string().min(2, t("validation.nameRequired")),
email: z.string().email(t("validation.emailRequired")),
phone: z.string().min(8, t("validation.phoneRequired")),
company: z.string().optional(),
msg: z.string().min(5, t("validation.messageRequired")),
});
const { register, handleSubmit, formState, reset } = useForm({ const { register, handleSubmit, formState, reset } = useForm({
resolver: zodResolver(formSchema), resolver: zodResolver(formSchema),
@ -50,13 +58,13 @@ export const ContactsForm: FC<Props> = ({ className }) => {
<div className={clsx("bg-PRIMARY rounded-[8px] py-8 px-6", className)}> <div className={clsx("bg-PRIMARY rounded-[8px] py-8 px-6", className)}>
<form onSubmit={handleSubmit(onSubmit)}> <form onSubmit={handleSubmit(onSubmit)}>
<h2 className="h2 !text-white text-3xl font-medium lg:mb-8 mb-6"> <h2 className="h2 !text-white text-3xl font-medium lg:mb-8 mb-6">
Связаться с нами {t("contacts.contactUs")}
</h2> </h2>
<div className="flex flex-col gap-8"> <div className="flex flex-col gap-8">
<div className="flex flex-col relative"> <div className="flex flex-col relative">
<label htmlFor="name" className="label"> <label htmlFor="name" className="label">
Имя {t("contacts.name")}
</label> </label>
<input <input
type="text" type="text"
@ -70,7 +78,7 @@ export const ContactsForm: FC<Props> = ({ className }) => {
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 items-center"> <div className="grid grid-cols-1 lg:grid-cols-2 gap-6 items-center">
<div className="flex flex-col relative"> <div className="flex flex-col relative">
<label htmlFor="email" className="label"> <label htmlFor="email" className="label">
E-mail {t("contacts.email")}
</label> </label>
<input <input
type="text" type="text"
@ -83,7 +91,7 @@ export const ContactsForm: FC<Props> = ({ className }) => {
<div className="flex flex-col relative"> <div className="flex flex-col relative">
<label htmlFor="phone" className="label"> <label htmlFor="phone" className="label">
Номер {t("contacts.phone")}
</label> </label>
<input <input
type="text" type="text"
@ -97,7 +105,7 @@ export const ContactsForm: FC<Props> = ({ className }) => {
<div className="flex flex-col relative"> <div className="flex flex-col relative">
<label htmlFor="company" className="label"> <label htmlFor="company" className="label">
Название компании {t("contacts.companyName")}
</label> </label>
<input <input
type="text" type="text"
@ -110,7 +118,7 @@ export const ContactsForm: FC<Props> = ({ className }) => {
<div className="flex flex-col relative"> <div className="flex flex-col relative">
<label htmlFor="msg" className="label"> <label htmlFor="msg" className="label">
Сообщение {t("contacts.message")}
</label> </label>
<textarea <textarea
rows={3} rows={3}
@ -124,7 +132,7 @@ export const ContactsForm: FC<Props> = ({ className }) => {
disabled={formState.isSubmitting || status} disabled={formState.isSubmitting || status}
className="bg-[#A4FFF3] text-sm text-ON_PRIMARY_CONTAINER h-10 rounded-[2px]" className="bg-[#A4FFF3] text-sm text-ON_PRIMARY_CONTAINER h-10 rounded-[2px]"
> >
{!status ? "Отправить" : "Форма отправлена"} {!status ? t("common.send") : t("common.formSubmitted")}
</button> </button>
</div> </div>
</form> </form>

View File

@ -10,15 +10,14 @@ import {
Organizer, Organizer,
Timing, Timing,
} from "@/lib/types/Calendar.type"; } from "@/lib/types/Calendar.type";
import { useAppSelector } from "@/redux/hooks"; import { useTranslations } from "next-intl";
import { useLang } from "@/utils/useLang"; import { Link } from "@/i18n/navigation";
import Link from "next/link";
interface Props { interface Props {
id: number; id: number;
description: string; description: string;
starts_at: string; starts_at: string | null;
ends_at: string; ends_at: string | null;
date: string; date: string;
title: string; title: string;
web_site: string | null; web_site: string | null;
@ -45,18 +44,18 @@ export const EventCard = ({
images, images,
dark = false, dark = false,
}: Props) => { }: Props) => {
const formatDate = (dateString: string) => { const formatDate = (dateString: string | null) => {
const dateParts = dateString?.split(" "); if (!dateString) return null;
const date = dateParts?.[0]; const dateParts = dateString.split(" ");
const parts = date?.split("-"); const date = dateParts[0];
const formattedDate = `${parts?.[2]}.${parts?.[1]}.${parts?.[0]}`; const parts = date.split("-");
if (parts.length === 3 && parts[0].length === 4) {
return formattedDate; return `${parts[2]}.${parts[1]}.${parts[0]}`;
}
return dateString;
}; };
const lang = useAppSelector( const t = useTranslations("events");
(state) => state.headerSlice.activeLang.localization
);
return ( return (
<Link className="w-full cursor-default" href={`/calendar/${id}`}> <Link className="w-full cursor-default" href={`/calendar/${id}`}>
@ -83,8 +82,8 @@ export const EventCard = ({
{} {}
)} )}
> >
<p className="mr-5">{formatDate(starts_at)}</p>{" "} {formatDate(starts_at) && <p className="mr-5">{formatDate(starts_at)}</p>}
<p>{formatDate(ends_at)}</p> {formatDate(ends_at) && <p>{formatDate(ends_at)}</p>}
</div> </div>
</div> </div>
@ -97,7 +96,6 @@ export const EventCard = ({
className="lg:size-[228px] size-[100px] object-cover rounded-l-[4px]" className="lg:size-[228px] size-[100px] object-cover rounded-l-[4px]"
/> />
{/* CENTER */}
<div className="flex flex-col gap-[10px] md:gap-4 max-w-[683px] py-6 w-full"> <div className="flex flex-col gap-[10px] md:gap-4 max-w-[683px] py-6 w-full">
<p className="text-[12px] text-[#6B7674] font-normal leading-none"> <p className="text-[12px] text-[#6B7674] font-normal leading-none">
{category} {category}
@ -105,27 +103,26 @@ export const EventCard = ({
<div className="flex flex-col gap-[10px] md:gap-[15px]"> <div className="flex flex-col gap-[10px] md:gap-[15px]">
<h3 <h3
className={clsx( className={clsx(
"text-5 font-medium line leading-[115%] lg:leading-8 md:leading-[100%]" "text-[18px] font-medium line leading-[115%] lg:leading-8 md:leading-[100%]"
)} )}
> >
{title} {title}
</h3> </h3>
{/* <p className={clsx('text-base line-clamp-2 leading-[130%] md:leading-[150%]', {})}>
{description}
</p> */}
</div> </div>
{organizers && organizers?.length > 0 &&
<div className="flex flex-col gap-[10px]"> <div className="flex flex-col gap-[10px]">
<p className="text-[#6B7674] uppercase font-normal leading-none text-[10px]"> <p className="text-[#6B7674] uppercase font-normal leading-none text-[10px]">
{useLang("Organiser:", "Организатор:", lang)} {t("organiserLabel")}
</p> </p>
<p className="text-[#6B7674] font-normal text-[13px] leading-[125%]"> <p className="text-[#6B7674] font-normal text-[13px] leading-[125%]">
{organizers ? organizers[0]?.name : null} {organizers ? organizers[0]?.name : null}
</p> </p>
</div> </div>
}
{coorganizers && coorganizers?.length > 0 && ( {coorganizers && coorganizers?.length > 0 && (
<div className="flex flex-col gap-[10px]"> <div className="flex flex-col gap-[10px]">
<p className="text-[#6B7674] uppercase font-normal leading-none text-[10px]"> <p className="text-[#6B7674] uppercase font-normal leading-none text-[10px]">
{useLang("Co-organiser:", "Со-организатор:", lang)} {t("coOrganiserLabel")}
</p> </p>
<p className="text-[#6B7674] font-normal text-[13px] leading-[125%]"> <p className="text-[#6B7674] font-normal text-[13px] leading-[125%]">
{coorganizers ? coorganizers[0]?.name : null} {coorganizers ? coorganizers[0]?.name : null}
@ -133,11 +130,10 @@ export const EventCard = ({
</div> </div>
)} )}
</div> </div>
{/* CENTER */}
<div className="hidden md:flex text-2xl flex-col text-white leading- none h-[228px] min-w-[245px] items-center justify-center bg-[#31A898] px-12 text-center"> <div className="hidden md:flex text-2xl flex-col text-white leading- none h-[228px] min-w-[245px] items-center justify-center bg-[#31A898] px-12 text-center">
<p className="">{formatDate(starts_at)}</p>{" "} {formatDate(starts_at) && <p>{formatDate(starts_at)}</p>}
<p>{formatDate(ends_at)}</p> {formatDate(ends_at) && <p>{formatDate(ends_at)}</p>}
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,7 +1,6 @@
"use client"; "use client";
import { useAppSelector } from "@/redux/hooks"; import { useTranslations } from "next-intl";
import Link from "next/link";
import { FC } from "react"; import { FC } from "react";
interface Props { interface Props {
@ -12,37 +11,40 @@ interface Props {
details?: string; details?: string;
} }
function toExternalUrl(url: string) {
if (!/^https?:\/\//i.test(url)) return `https://${url}`;
return url;
}
export const EventPageButtons: FC<Props> = ({ export const EventPageButtons: FC<Props> = ({
once = false, once = false,
register, register,
visit, visit,
details, details,
}) => { }) => {
const lang = useAppSelector( const t = useTranslations("events");
(state) => state.headerSlice.activeLang.localization
);
return ( return (
<div className="flex items-center gap-6"> <div className="flex items-center gap-6">
{once ? ( {once ? (
<> <>
<Link href={register || ""} className="w-full" target="_blank"> <a href={toExternalUrl(register || "")} className="w-full" target="_blank" rel="noopener noreferrer">
<button className="full-btn bg-PRIMARY py-2.5 text-white"> <button className="full-btn bg-PRIMARY py-2.5 text-white">
{lang === "en" ? "Registration" : "Зарегистрироваться"} {t("registration")}
</button> </button>
</Link> </a>
<Link href={visit || ""} className="w-full" target="_blank"> <a href={toExternalUrl(visit || "")} className="w-full" target="_blank" rel="noopener noreferrer">
<button className="full-btn bg-SECONDARY_CONTAINER py-2.5 text-ON_SECONDARY_CONTAINER"> <button className="full-btn bg-SECONDARY_CONTAINER py-2.5 text-ON_SECONDARY_CONTAINER">
{lang === "en" ? "Visit site" : "Посетить сайт"} {t("visitSite")}
</button> </button>
</Link> </a>
</> </>
) : ( ) : (
<Link href={details || ""} className="w-full" target="_blank"> <a href={toExternalUrl(details || "")} className="w-full" target="_blank" rel="noopener noreferrer">
<button className="full-btn w-full bg-PRIMARY py-2.5 text-white"> <button className="full-btn w-full bg-PRIMARY py-2.5 text-white">
{lang === "en" ? "More" : "Подробнее"} {t("more")}
</button> </button>
</Link> </a>
)} )}
</div> </div>
); );

View File

@ -2,14 +2,12 @@
import "swiper/css"; import "swiper/css";
import "swiper/css/pagination"; import "swiper/css/pagination";
// import "./styles/events.css";
import { useLang } from "@/utils/useLang"; import { useTranslations } from "next-intl";
import { FC } from "react"; import { FC } from "react";
import { Swiper, SwiperSlide } from "swiper/react"; import { Swiper, SwiperSlide } from "swiper/react";
import { EventCard } from "./event-card"; import { EventCard } from "./event-card";
import { CalendarType } from "@/lib/types/Calendar.type"; import { CalendarType } from "@/lib/types/Calendar.type";
import { useAppSelector } from "@/redux/hooks";
interface Props { interface Props {
data: CalendarType["data"]; data: CalendarType["data"];
@ -17,17 +15,12 @@ interface Props {
} }
export const EventsMobile: FC<Props> = ({ data }) => { export const EventsMobile: FC<Props> = ({ data }) => {
const lang = useAppSelector( const t = useTranslations("home");
(state) => state.headerSlice.activeLang.localization
);
return ( return (
<div className="md:hidden container"> <div className="md:hidden container">
<h2 className="text-[26px] mb-5 sm:mb-10 font-semibold leading-[115%]"> <h2 className="text-[26px] mb-5 sm:mb-10 font-semibold leading-[115%]">
{useLang( {t("upcomingExhibitions")}
"Upcoming exhibitions and events",
"Ближайшие выставки и мероприятия",
lang
)}
</h2> </h2>
<div className="flex flex-col"> <div className="flex flex-col">
<div className="flex items-center gap-y-[10px]"> <div className="flex items-center gap-y-[10px]">

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import Image from 'next/image'; import Image from 'next/image';
import Link from 'next/link'; import { Link } from '@/i18n/navigation';
interface Props { interface Props {
img: string; img: string;

View File

@ -1,10 +1,8 @@
"use client"; "use client";
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import Image from "next/image";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { useAppDispatch, useAppSelector } from "@/redux/hooks"; import { useAppDispatch, useAppSelector } from "@/redux/hooks";
import close from "@/public/assets/icons/home/close-input.svg";
import { selectInput, setInputStatus } from "@/redux/slices/inputSlice"; import { selectInput, setInputStatus } from "@/redux/slices/inputSlice";
import { v4 } from "uuid"; import { v4 } from "uuid";
@ -12,20 +10,14 @@ import { selectHeader, setShowInput } from "@/redux/slices/headerSlice";
import clsx from "clsx"; import clsx from "clsx";
import { selectBurger } from "@/redux/slices/burgerSlice"; import { selectBurger } from "@/redux/slices/burgerSlice";
import { baseAPI } from "@/lib/API"; import { baseAPI } from "@/lib/API";
import Link from "next/link";
import { SearchTypes } from "@/lib/types/Search.type"; import { SearchTypes } from "@/lib/types/Search.type";
import { useMediaQuery } from "usehooks-ts"; import { useMediaQuery } from "usehooks-ts";
import { useTranslations, useLocale } from "next-intl";
export const inputRadio = [ import { Link } from "@/i18n/navigation";
{ name: "Везде", id: "all" },
{ name: "В событиях", id: "events" },
{ name: "В новостях", id: "news" },
];
export const SearchInput = ({ mob = false }: { mob?: boolean }) => { export const SearchInput = ({ mob = false }: { mob?: boolean }) => {
const localization = useAppSelector( const locale = useLocale();
(state) => state.headerSlice.activeLang.localization const t = useTranslations("search");
);
const wrapper = document.querySelector(".wrapper"); const wrapper = document.querySelector(".wrapper");
const tab = useMediaQuery("(min-width: 980px)"); const tab = useMediaQuery("(min-width: 980px)");
@ -38,12 +30,17 @@ export const SearchInput = ({ mob = false }: { mob?: boolean }) => {
const { showInput } = useAppSelector(selectHeader); const { showInput } = useAppSelector(selectHeader);
const inputRadio = [
{ name: t("all"), id: "all" },
{ name: t("inEvents"), id: "events" },
{ name: t("inNews"), id: "news" },
];
useEffect(() => { useEffect(() => {
wrapper?.classList.remove("overflow-hidden"); wrapper?.classList.remove("overflow-hidden");
wrapper?.classList.add("overflow-hidden"); wrapper?.classList.add("overflow-hidden");
setStatus(inputRadio[0].id); setStatus(inputRadio[0].id);
inputRadio;
return () => { return () => {
wrapper?.classList.remove("overflow-hidden"); wrapper?.classList.remove("overflow-hidden");
@ -56,7 +53,7 @@ export const SearchInput = ({ mob = false }: { mob?: boolean }) => {
try { try {
const res = await fetch(`${baseAPI}search?search=${value}`, { const res = await fetch(`${baseAPI}search?search=${value}`, {
headers: { headers: {
"Accept-Language": localization, "Accept-Language": locale,
"Content-Type": "application/json", "Content-Type": "application/json",
}, },
}); });
@ -135,7 +132,7 @@ export const SearchInput = ({ mob = false }: { mob?: boolean }) => {
} }
value={value} value={value}
type="text" type="text"
placeholder="Что найти?" placeholder={t("placeholder")}
className="p-3 w-full leading-[150%] placeholder:leading-[150%] placeholder:text-gray focus:outline-none rounded-sm bg-transparent border-[1px] border-[#BCC4CC]" className="p-3 w-full leading-[150%] placeholder:leading-[150%] placeholder:text-gray focus:outline-none rounded-sm bg-transparent border-[1px] border-[#BCC4CC]"
/> />
</div> </div>
@ -167,7 +164,7 @@ export const SearchInput = ({ mob = false }: { mob?: boolean }) => {
</div> </div>
) : ( ) : (
<div className="bg-green py-[17px] px-[70px] rounded-sm"> <div className="bg-green py-[17px] px-[70px] rounded-sm">
Найти {t("findButton")}
</div> </div>
)} )}
</button> </button>
@ -177,11 +174,12 @@ export const SearchInput = ({ mob = false }: { mob?: boolean }) => {
searchData.data.posts.length ? ( searchData.data.posts.length ? (
<> <>
<div className="mb-12 font-light"> <div className="mb-12 font-light">
По запросу « <span className="font-bold">{searchValue}</span>{" "} {t("byRequest")}
» нашлось <span className="font-bold">{searchValue}</span>
{t("found")}{" "}
{searchData.data.expo_events.length + {searchData.data.expo_events.length +
searchData.data.posts.length}{" "} searchData.data.posts.length}{" "}
результатов {t("results")}
</div> </div>
<div className="flex flex-col gap-9 w-full tab:mb-0 mb-20"> <div className="flex flex-col gap-9 w-full tab:mb-0 mb-20">
{inputStatus === "all" || inputStatus === "events" {inputStatus === "all" || inputStatus === "events"
@ -191,7 +189,7 @@ export const SearchInput = ({ mob = false }: { mob?: boolean }) => {
{item.title} {item.title}
</h3> </h3>
<Link href={`/calendar/${item.id}`}> <Link href={`/calendar/${item.id}`}>
Перейти на страницу {t("goToPage")}
</Link> </Link>
<hr className="mt-9 border-OUTLINE_VAR" /> <hr className="mt-9 border-OUTLINE_VAR" />
</div> </div>
@ -204,7 +202,7 @@ export const SearchInput = ({ mob = false }: { mob?: boolean }) => {
{item.title} {item.title}
</h3> </h3>
<Link href={`/news/${item.id}`}> <Link href={`/news/${item.id}`}>
Перейти на страницу {t("goToPage")}
</Link> </Link>
<hr className="mt-9 border-OUTLINE_VAR" /> <hr className="mt-9 border-OUTLINE_VAR" />
</div> </div>
@ -213,7 +211,7 @@ export const SearchInput = ({ mob = false }: { mob?: boolean }) => {
</div> </div>
</> </>
) : ( ) : (
<h3>По вашему запросу ничего не найдено</h3> <h3>{t("noResults")}</h3>
) )
) : null} ) : null}
</div> </div>

View File

@ -4,13 +4,10 @@ import React from "react";
import Image from "next/image"; import Image from "next/image";
import { contactCardData, roadCardData } from "@/lib/database/homeInfoData"; import { contactCardData, roadCardData } from "@/lib/database/homeInfoData";
import { useLang } from "@/utils/useLang"; import { useTranslations } from "next-intl";
import { useAppSelector } from "@/redux/hooks";
export const Services = () => { export const Services = () => {
const localization = useAppSelector( const t = useTranslations();
(state) => state.headerSlice.activeLang.localization
);
return ( return (
<div <div
@ -18,7 +15,7 @@ export const Services = () => {
> >
<div className="flex flex-col items-start gap-x-5 w-full"> <div className="flex flex-col items-start gap-x-5 w-full">
<h3 className="text-[21px] leading-[100%] font-bold text-bgWhite md:text-[#B0E6A1] uppercase md:mb-10 mb-5"> <h3 className="text-[21px] leading-[100%] font-bold text-bgWhite md:text-[#B0E6A1] uppercase md:mb-10 mb-5">
{useLang("Routes", "как добраться", localization)} {t("services.routes")}
</h3> </h3>
<div className="flex flex-col gap-y-5 w-full"> <div className="flex flex-col gap-y-5 w-full">
{roadCardData.map((item, i) => ( {roadCardData.map((item, i) => (
@ -29,7 +26,7 @@ export const Services = () => {
<div className="flex items-center gap-10 md:gap-5"> <div className="flex items-center gap-10 md:gap-5">
<Image className="img-auto" src={item.icon} alt="icon" /> <Image className="img-auto" src={item.icon} alt="icon" />
<p className="text-[16px] leading-[120%] md:leading-[100%]"> <p className="text-[16px] leading-[120%] md:leading-[100%]">
{localization === "ru" ? item.text : item.enText} {t(item.textKey)}
</p> </p>
</div> </div>
</div> </div>
@ -38,7 +35,7 @@ export const Services = () => {
</div> </div>
<div className="flex flex-col items-start md:mt-0 mt-10 gap-x-5 w-full"> <div className="flex flex-col items-start md:mt-0 mt-10 gap-x-5 w-full">
<h3 className="text-[21px] leading-[100%] text-bgWhite md:text-[#FFD288] uppercase font-bold md:mb-10 mb-5"> <h3 className="text-[21px] leading-[100%] text-bgWhite md:text-[#FFD288] uppercase font-bold md:mb-10 mb-5">
{useLang("Contacts", "контакты", localization)} {t("contacts.title")}
</h3> </h3>
<div className="flex flex-col gap-y-5 w-full"> <div className="flex flex-col gap-y-5 w-full">
{contactCardData.map((item, i) => ( {contactCardData.map((item, i) => (
@ -49,7 +46,7 @@ export const Services = () => {
<div className="flex items-center md:gap-5 gap-10"> <div className="flex items-center md:gap-5 gap-10">
<Image src={item.icon} alt="icon" /> <Image src={item.icon} alt="icon" />
<p className="text-[16px] leading-[120%] md:leading-[100%]"> <p className="text-[16px] leading-[120%] md:leading-[100%]">
{localization === "ru" ? item.text : item.enText} {t(item.textKey)}
</p> </p>
</div> </div>
</div> </div>

View File

@ -3,9 +3,9 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import Image from "next/image"; import Image from "next/image";
import { useMediaQuery } from "usehooks-ts"; import { useMediaQuery } from "usehooks-ts";
import { useAppSelector } from "@/redux/hooks";
import { useSliderBanner } from "@/hooks/use-slider"; import { useSliderBanner } from "@/hooks/use-slider";
import Loader from "../ui/Loader"; import Loader from "../ui/Loader";
import { useLocale } from "next-intl";
export const SliderClient = () => { export const SliderClient = () => {
const isTab = useMediaQuery("(min-width: 1024px)"); const isTab = useMediaQuery("(min-width: 1024px)");
@ -14,16 +14,14 @@ export const SliderClient = () => {
const [data, setData] = useState<any>(null); const [data, setData] = useState<any>(null);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const bannerType = useSliderBanner(isTab, isMd); const bannerType = useSliderBanner(isTab, isMd);
const lang = useAppSelector( const locale = useLocale();
(state) => state.headerSlice.activeLang.localization
);
const fetchData = async () => { const fetchData = async () => {
try { try {
setLoading(true); setLoading(true);
const res = await fetch(`/api/banners?bannerType=${bannerType}`, { const res = await fetch(`/api/banners?bannerType=${bannerType}`, {
headers: { headers: {
"Accept-Language": lang, "Accept-Language": locale,
}, },
}); });
const json = await res.json(); const json = await res.json();
@ -36,7 +34,7 @@ export const SliderClient = () => {
useEffect(() => { useEffect(() => {
fetchData(); fetchData();
}, [bannerType, lang]); }, [bannerType, locale]);
if (loading) return <Loader className="h-[600px] min-h-[320px]" />; if (loading) return <Loader className="h-[600px] min-h-[320px]" />;

View File

@ -6,50 +6,27 @@ import clsx from "clsx";
import { motion, AnimatePresence } from "framer-motion"; import { motion, AnimatePresence } from "framer-motion";
import triangle from "@/public/assets/icons/drop-icon.svg"; import triangle from "@/public/assets/icons/drop-icon.svg";
import { useAppSelector, useAppDispatch } from "@/redux/hooks"; import { useLocale } from "next-intl";
import { activeLangType, selectHeader } from "@/redux/slices/headerSlice"; import { useRouter, usePathname } from "@/i18n/navigation";
import { setActiveLang } from "@/redux/slices/headerSlice"; import { locales } from "@/i18n/config";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
export const lang = [ const langNames: Record<string, string> = {
{ ru: "Русский",
title: "Русский", en: "English",
localization: "ru", tm: "Türkmen",
},
// {
// title: 'Tm',
// localization: 'tm',
// },
{
title: "English",
localization: "en",
},
];
export const LangMenu = () => {
const { activeLang } = useAppSelector(selectHeader);
const { refresh } = useRouter();
const [active, setActive] = useState(false);
const dispatch = useAppDispatch();
const menuRef = useRef<HTMLDivElement>(null);
const setLang = (lang: activeLangType) => {
// Устанавливаем cookie через document.cookie
document.cookie = `lang=${lang.localization}; path=/; max-age=31536000`;
dispatch(setActiveLang(lang));
refresh();
}; };
useEffect(() => { export const LangMenu = () => {
const cookieLang = document.cookie const locale = useLocale();
.split("; ") const router = useRouter();
.find((row) => row.startsWith("lang=")) const pathname = usePathname();
?.split("=")[1]; const [active, setActive] = useState(false);
const menuRef = useRef<HTMLDivElement>(null);
if (cookieLang) { const switchLocale = (newLocale: string) => {
const foundLang = lang.find((l) => l.localization === cookieLang); router.replace(pathname, { locale: newLocale });
if (foundLang) dispatch(setActiveLang(foundLang)); setActive(false);
} };
}, [dispatch]);
useEffect(() => { useEffect(() => {
const handleClick = (e: MouseEvent) => { const handleClick = (e: MouseEvent) => {
@ -72,7 +49,7 @@ export const LangMenu = () => {
}} }}
> >
<div className="flex items-center px-[12px]"> <div className="flex items-center px-[12px]">
<p>{activeLang.title}</p> <p>{langNames[locale]}</p>
<Image <Image
src={triangle} src={triangle}
alt="arrow" alt="arrow"
@ -98,21 +75,15 @@ export const LangMenu = () => {
}} }}
className="absolute rounded-[4px] w-[112px] overflow-hidden custom-shadow z-10 flex flex-col top-[27px] bg-[#EEF1F0] transition-all duration-300" className="absolute rounded-[4px] w-[112px] overflow-hidden custom-shadow z-10 flex flex-col top-[27px] bg-[#EEF1F0] transition-all duration-300"
> >
{lang {locales
.filter((item) => item.title !== activeLang.title) .filter((l) => l !== locale)
.map((item, i) => ( .map((l, i) => (
<div <div
key={i} key={i}
onClick={() => setLang(item)} onClick={() => switchLocale(l)}
className={clsx( className="p-3 pr-[22px] py-4 text-extraSm transition-all hover:bg-ON_SECONDARY_CONTAINER/[8%]"
"p-3 pr-[22px] py-4 text-extraSm transition-all",
{
"hover:bg-ON_SECONDARY_CONTAINER/[8%]":
item.title === item.title,
}
)}
> >
{item.title} {langNames[l]}
</div> </div>
))} ))}
</motion.div> </motion.div>

View File

@ -1,6 +1,7 @@
"use client"; "use client";
import React, { Dispatch, SetStateAction } from "react"; import React, { Dispatch, SetStateAction } from "react";
import { useTranslations } from "next-intl";
interface IProps { interface IProps {
lastPage?: number; lastPage?: number;
@ -11,6 +12,8 @@ interface IProps {
} }
export const Pagination = ({ current, setCurrent, lastPage = 3 }: IProps) => { export const Pagination = ({ current, setCurrent, lastPage = 3 }: IProps) => {
const t = useTranslations("common");
const onNext = () => { const onNext = () => {
setCurrent(current + 1); setCurrent(current + 1);
}; };
@ -39,7 +42,9 @@ export const Pagination = ({ current, setCurrent, lastPage = 3 }: IProps) => {
<div className="border-[1px] border-OUTLINE_VAR rounded-sm px-3 py-[9px]"> <div className="border-[1px] border-OUTLINE_VAR rounded-sm px-3 py-[9px]">
{current} {current}
</div> </div>
<p>из {lastPage}</p> <p>
{t("of")} {lastPage}
</p>
<button onClick={onNext} disabled={current >= lastPage} type="button"> <button onClick={onNext} disabled={current >= lastPage} type="button">
<svg <svg
width="32" width="32"

View File

@ -1,19 +1,15 @@
"use client"; "use client";
import React from "react"; import React from "react";
import Link from "next/link";
import clsx from "clsx"; import clsx from "clsx";
import { usePathname } from "next/navigation"; import { useTranslations } from "next-intl";
import { sidebarData } from "@/lib/database/pathnames"; import { sidebarData } from "@/lib/database/pathnames";
import { useAppSelector } from "@/redux/hooks"; import { Link, usePathname } from "@/i18n/navigation";
export const Sidebar = () => { export const Sidebar = () => {
const pathname = usePathname(); const pathname = usePathname();
const t = useTranslations();
const lang = useAppSelector(
(state) => state.headerSlice.activeLang.localization
);
return ( return (
<div className="flex flex-col bg-white rounded-lg px-6 py-4 items-start gap-y-[12px] pb-5 mt-12 sticky top-0 left-0 overflow-hidden"> <div className="flex flex-col bg-white rounded-lg px-6 py-4 items-start gap-y-[12px] pb-5 mt-12 sticky top-0 left-0 overflow-hidden">
@ -31,7 +27,7 @@ export const Sidebar = () => {
<p <p
className={clsx("mb-[16px] text-[16px] font-bold leading-[1.5]")} className={clsx("mb-[16px] text-[16px] font-bold leading-[1.5]")}
> >
{lang === "ru" ? item.pathname : item.pathnameEn} {t(item.pathnameKey)}
</p> </p>
<div className="flex flex-col items-start gap-y-[8px]"> <div className="flex flex-col items-start gap-y-[8px]">
<div className="flex flex-col gap-[10px] pl-4 pr-10"> <div className="flex flex-col gap-[10px] pl-4 pr-10">
@ -47,7 +43,7 @@ export const Sidebar = () => {
)} )}
key={i} key={i}
> >
{lang === "ru" ? obj.title : obj.titleEn} {t(obj.titleKey)}
</Link> </Link>
))} ))}
</div> </div>

View File

@ -1,9 +1,7 @@
"use client"; "use client";
import { useAppSelector } from "@/redux/hooks"; import { useTranslations } from "next-intl";
import { selectHeader } from "@/redux/slices/headerSlice"; import { Link } from "@/i18n/navigation";
import { useLang } from "@/utils/useLang";
import Link from "next/link";
export const BreadCrumbs = ({ export const BreadCrumbs = ({
second, second,
@ -18,12 +16,12 @@ export const BreadCrumbs = ({
path2?: string; path2?: string;
cursor?: boolean; cursor?: boolean;
}) => { }) => {
const { activeLang } = useAppSelector(selectHeader); const t = useTranslations("common");
return ( return (
<div className="text-[12px] text-[#6B7674] flex items-center mob:mb-6 mb-5"> <div className="text-[12px] text-[#6B7674] flex items-center mob:mb-6 mb-5">
<Link href={"/"}> <Link href={"/"}>
{useLang("Home", "Главная", activeLang.localization)} {t("home")}
</Link> </Link>
<p className="px-1">/</p> <p className="px-1">/</p>

View File

@ -1,11 +1,12 @@
"use client"; "use client";
import { burgerMenuData } from "@/lib/database/pathnames"; import { burgerMenuData } from "@/lib/database/pathnames";
import { useAppDispatch, useAppSelector } from "@/redux/hooks"; import { useAppDispatch } from "@/redux/hooks";
import Link from "next/link"; import { Link } from "@/i18n/navigation";
import React from "react"; import React from "react";
import Image from "next/image"; import Image from "next/image";
import { v4 } from "uuid"; import { v4 } from "uuid";
import { useTranslations } from "next-intl";
import arrow from "@/public/assets/icons/header/burger-arrow.svg"; import arrow from "@/public/assets/icons/header/burger-arrow.svg";
import { import {
@ -22,6 +23,7 @@ export const BurgerDrop = ({
setDrop: (name: boolean) => void; setDrop: (name: boolean) => void;
}) => { }) => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const t = useTranslations();
return burgerMenuData return burgerMenuData
.filter((obj) => !obj.only) .filter((obj) => !obj.only)
@ -38,7 +40,7 @@ export const BurgerDrop = ({
className="cursor-pointer flex items-center gap-[10px] mb-[10px]" className="cursor-pointer flex items-center gap-[10px] mb-[10px]"
> >
<Image src={arrow} alt="стрелка" className="rotate-180" /> <Image src={arrow} alt="стрелка" className="rotate-180" />
<h3 className="leading-[135%] text-[18px]">{item.title}</h3> <h3 className="leading-[135%] text-[18px]">{t(item.titleKey)}</h3>
</div> </div>
<hr className="border-bgWhite mb-5" /> <hr className="border-bgWhite mb-5" />
@ -53,7 +55,7 @@ export const BurgerDrop = ({
setDrop(false); setDrop(false);
}} }}
> >
{subj.title} {t(subj.titleKey)}
</Link> </Link>
))} ))}
</div> </div>

View File

@ -1,88 +1,44 @@
"use client"; "use client";
import Link from "next/link";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { v4 } from "uuid"; import { v4 } from "uuid";
import { motion } from "framer-motion"; import { motion } from "framer-motion";
import { useLocale, useTranslations } from "next-intl";
import { useAppDispatch, useAppSelector } from "@/redux/hooks"; import { useAppDispatch } from "@/redux/hooks";
import { setBurgerOpen } from "@/redux/slices/burgerSlice"; import { setBurgerOpen } from "@/redux/slices/burgerSlice";
import { activeLangType, setActiveLang } from "@/redux/slices/headerSlice";
import clsx from "clsx"; import clsx from "clsx";
import { burgerMenu, burgerMenu2 } from "@/lib/database/header"; import { burgerMenu, burgerMenu2 } from "@/lib/database/header";
import { useRouter } from "next/navigation"; import { useRouter, usePathname } from "@/i18n/navigation";
import { lang } from "./lang-menu"; import { Link } from "@/i18n/navigation";
import { locales } from "@/i18n/config";
interface flagTypes { const burgerLangs = [
// title: 'Ру' | 'En' | 'Tm'; { title: "Ру", localization: "ru" as const },
title: "Ру" | "En"; { title: "En", localization: "en" as const },
localization: "ru" | "en"; { title: "Tm", localization: "tm" as const },
// localization: 'ru' | 'en' | 'tm';
}
const burgerLangs: flagTypes[] = [
// {
// title: 'Tm',
// localization: 'tm',
// },
{
title: "Ру",
localization: "ru",
},
{
title: "En",
localization: "en",
},
]; ];
export const BurgerMenu = () => { export const BurgerMenu = () => {
const dispatch = useAppDispatch(); const dispatch = useAppDispatch();
const wrapper = document.querySelector(".wrapper"); const locale = useLocale();
const { refresh } = useRouter(); const t = useTranslations();
const router = useRouter();
const localization = useAppSelector( const pathname = usePathname();
(state) => state.headerSlice.activeLang.localization
);
const [activeMenu, setActiveMenu] = useState<string>(""); const [activeMenu, setActiveMenu] = useState<string>("");
const [activeMenu2, setActiveMenu2] = useState<string>(""); const [activeMenu2, setActiveMenu2] = useState<string>("");
const setActiveTitle = () => { const setActiveTitle = () => {
if (activeMenu.includes("/ser")) if (activeMenu.includes("/ser")) return t("nav.services");
return (
(localization === "ru" && "Услуги") ||
(localization === "en" && "Services")
);
}; };
const setActiveTitle2 = () => { const setActiveTitle2 = () => {
if (activeMenu2.includes("/company")) if (activeMenu2.includes("/company")) return t("nav.about");
return (
(localization === "ru" && "О компании") ||
(localization === "en" && "About company")
);
};
const setLang = (lang: activeLangType) => {
// Устанавливаем cookie через document.cookie
document.cookie = `lang=${lang.localization}; path=/; max-age=31536000`;
dispatch(setActiveLang(lang));
refresh();
}; };
useEffect(() => { useEffect(() => {
const cookieLang = document.cookie const wrapper = document.querySelector(".wrapper");
.split("; ")
.find((row) => row.startsWith("lang="))
?.split("=")[1];
if (cookieLang) {
const foundLang = lang.find((l) => l.localization === cookieLang);
if (foundLang) dispatch(setActiveLang(foundLang));
}
}, [dispatch]);
useEffect(() => {
wrapper?.classList.remove("overflow-hidden"); wrapper?.classList.remove("overflow-hidden");
wrapper?.classList.add("overflow-hidden"); wrapper?.classList.add("overflow-hidden");
@ -103,7 +59,7 @@ export const BurgerMenu = () => {
x: "100%", x: "100%",
opacity: 0, opacity: 0,
}} }}
className="bg-green overflow-auto fixed w-full z-[900] top-[74px] bottom-0 left-0 min-h-[100vh] h-full px-4 py-10 flex flex-col overflow-y-auto" className="bg-green overflow-auto fixed w-full z-50 top-[66px] bottom-0 left-0 min-h-[100vh] h-full px-4 py-10 flex flex-col overflow-y-auto"
> >
{activeMenu && ( {activeMenu && (
<div> <div>
@ -145,7 +101,7 @@ export const BurgerMenu = () => {
onClick={() => dispatch(setBurgerOpen(false))} onClick={() => dispatch(setBurgerOpen(false))}
href={obj.link} href={obj.link}
> >
{localization === "en" ? obj.titleEn : obj.title} {t(obj.titleKey)}
</Link> </Link>
)) ))
)} )}
@ -163,8 +119,7 @@ export const BurgerMenu = () => {
}} }}
href={item.link} href={item.link}
> >
{(localization === "en" && item.titleEn) || {t(item.titleKey)}
(localization === "ru" && item.title)}
</Link> </Link>
) : ( ) : (
<div <div
@ -174,8 +129,7 @@ export const BurgerMenu = () => {
setActiveMenu(item.link); setActiveMenu(item.link);
}} }}
> >
{(localization === "en" && item.titleEn) || {t(item.titleKey)}
(localization === "ru" && item.title)}
{item.drop && ( {item.drop && (
<svg <svg
width="24" width="24"
@ -234,8 +188,7 @@ export const BurgerMenu = () => {
dispatch(setBurgerOpen(false)); dispatch(setBurgerOpen(false));
}} }}
> >
{(localization === "en" && item.titleEn) || {t(item.titleKey)}
(localization === "ru" && item.title)}
</Link> </Link>
)) ))
)} )}
@ -246,9 +199,8 @@ export const BurgerMenu = () => {
<div <div
key={i} key={i}
onClick={() => { onClick={() => {
dispatch(setActiveLang(item)); router.replace(pathname, { locale: item.localization });
dispatch(setBurgerOpen(false)); dispatch(setBurgerOpen(false));
setLang(item);
}} }}
className="flex cursor-pointer items-center gap-[10px]" className="flex cursor-pointer items-center gap-[10px]"
> >

View File

@ -1,8 +1,20 @@
import clsx from "clsx";
import React from "react"; import React from "react";
export const Title = ({ text }: { text: string | boolean }) => { export const Title = ({
text,
className,
}: {
text: string | boolean;
className?: string;
}) => {
return ( return (
<h2 className={`text-[26px] sm:text-[34px] leading-[115%] font-normal`}> <h2
className={clsx(
`text-[26px] sm:text-[34px] leading-[115%] font-normal`,
className
)}
>
{text} {text}
</h2> </h2>
); );

60
hooks/useFetch.ts Normal file
View File

@ -0,0 +1,60 @@
"use client";
import { baseAPI } from "@/lib/API";
import { useLocale } from "next-intl";
import { useState, useEffect } from "react";
interface FetchState<T> {
data: T | null;
loading: boolean;
error: string | null;
}
export const useFetch = <T>(
url: string,
options?: RequestInit
): FetchState<T> => {
const [state, setState] = useState<FetchState<T>>({
data: null,
loading: true,
error: null,
});
const locale = useLocale();
useEffect(() => {
const fetchData = async () => {
try {
setState((prev) => ({ ...prev, loading: true, error: null }));
const response = await fetch(baseAPI + url, {
headers: {
"Accept-Language": locale,
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const result = (await response.json()) as T;
setState({
data: result,
loading: false,
error: null,
});
} catch (error) {
setState({
data: null,
loading: false,
error: error instanceof Error ? error.message : "Unknown error",
});
}
};
fetchData();
}, [url, locale]);
return state;
};

3
i18n/config.ts Normal file
View File

@ -0,0 +1,3 @@
export const locales = ["ru", "en", "tm"] as const;
export type Locale = (typeof locales)[number];
export const defaultLocale: Locale = "ru";

7
i18n/navigation.ts Normal file
View File

@ -0,0 +1,7 @@
import { createNavigation } from "next-intl/navigation";
import { locales, defaultLocale } from "./config";
export const { Link, redirect, usePathname, useRouter } = createNavigation({
locales,
defaultLocale,
});

15
i18n/request.ts Normal file
View File

@ -0,0 +1,15 @@
import { getRequestConfig } from "next-intl/server";
import { locales, type Locale } from "./config";
export default getRequestConfig(async ({ requestLocale }) => {
let locale = await requestLocale;
if (!locale || !locales.includes(locale as Locale)) {
locale = "ru";
}
return {
locale,
messages: (await import(`../messages/${locale}.json`)).default,
};
});

View File

@ -1,123 +1,82 @@
export const burgerMenu = [ interface BurgerMenuItem {
titleKey: string;
link: string;
services?: boolean;
drop?: boolean;
dropDown?: {
titleKey: string;
link: string;
}[];
}
export const burgerMenu: BurgerMenuItem[] = [
{ {
title: "Календарь мероприятий", titleKey: "nav.calendar",
titleEn: "Calendar of events",
link: "/calendar", link: "/calendar",
}, },
{ {
services: true, services: true,
title: "Услуги", titleKey: "nav.services",
drop: true, drop: true,
titleEn: "Services",
link: "/services/organization", link: "/services/organization",
dropDown: [ dropDown: [
{ { titleKey: "sidebar.organizeExhibitions", link: "/services/organization" },
title: "Организация выставок", { titleKey: "sidebar.b2bMeetings", link: "/services/meetings" },
titleEn: "Organization of exhibitions", { titleKey: "sidebar.businessMissions", link: "/services/missions" },
link: "/services/organization", { titleKey: "burger.advertisingActivity", link: "/services/advertising" },
}, { titleKey: "sidebar.hybridEvents", link: "/services/hybrid-organizations" },
{ { titleKey: "sidebar.certification", link: "/services/certification" },
title: "B2B Встречи и Матчмейкинг", { titleKey: "burger.freightForwarding", link: "/services/forwarding" },
titleEn: "B2B Meetings & Business Matchmaking", { titleKey: "burger.accountingOutsourcing", link: "/services/outsourcing" },
link: "/services/meetings", { titleKey: "burger.personnelTraining", link: "/services/personnel-training" },
}, { titleKey: "sidebar.businessTours", link: "/services/business-tours" },
{
title: "Бизнес-Миссии",
titleEn: "Business Missions",
link: "/services/missions",
},
{
title: "Рекламная деятельность",
titleEn: "Advertising activity",
link: "/services/advertising",
},
{
title: "Организация гибридных мероприятий",
titleEn: "Organization of hybrid events",
link: "/services/hybrid-organizations",
},
{
title: "Сертификация",
titleEn: "Certification",
link: "/services/certification",
},
{
title: "Экспедирование грузов и таможенное оформление",
titleEn: "Freight forwarding and customs clearance",
link: "/services/forwarding",
},
{
title: "Аутсорсинг бух.учета и аудита",
titleEn: "Outsourcing of accounting and auditing",
link: "/services/outsourcing",
},
{
title: "Обучения персонала",
titleEn: "Personnel-training",
link: "/services/personnel-training",
},
{
title: "Бизнес - туры",
titleEn: "Business - tours",
link: "/services/business-tours",
},
], ],
}, },
{ {
title: "О компании", titleKey: "nav.about",
titleEn: "Calendar of events",
link: "/company/aboutus", link: "/company/aboutus",
}, },
{ {
title: "Новости", titleKey: "nav.news",
titleEn: "News",
link: "/news", link: "/news",
}, },
{ {
title: "Контакты", titleKey: "nav.contacts",
titleEn: "Contacts",
link: "/contacts", link: "/contacts",
}, },
// { en: true, title: "Exhibition", link: "/exhibition-about" },
// { en: true, title: "Participants", link: "/participants-info" },
// { en: true, title: "For visitors", link: "/visitors-info" },
]; ];
export const burgerMenu2 = [ interface BurgerMenu2Item {
titleKey: string;
link: string;
company?: boolean;
drop?: boolean;
dropDown?: {
titleKey: string;
link: string;
}[];
}
export const burgerMenu2: BurgerMenu2Item[] = [
{ {
company: true, company: true,
title: "О компании", titleKey: "nav.about",
titleEn: "About company",
link: "/company/aboutus", link: "/company/aboutus",
drop: true, drop: true,
dropDown: [ dropDown: [
{ { titleKey: "burger.aboutUs", link: "/company/aboutus" },
title: "О нас",
titleEn: "About us",
link: "/company/aboutus",
},
], ],
}, },
{ {
title: "Новости", titleKey: "nav.news",
titleEn: "News",
link: "/news", link: "/news",
}, },
{ {
title: "FAQ", titleKey: "nav.faq",
titleEn: "FAQ",
link: "/faq", link: "/faq",
}, },
{ {
title: "Контакты", titleKey: "nav.contacts",
titleEn: "Контакты",
link: "/contacts", link: "/contacts",
}, },
]; ];

View File

@ -1,56 +1,36 @@
import car from '@/public/assets/icons/service/car.svg'; import car from "@/public/assets/icons/service/car.svg";
import bus from '@/public/assets/icons/service/bus.svg'; import bus from "@/public/assets/icons/service/bus.svg";
import track from '@/public/assets/icons/service/track.svg'; import track from "@/public/assets/icons/service/track.svg";
import { RoadCardProps } from '../types'; import { StaticImageData } from "next/image";
export interface RoadCardProps {
icon: StaticImageData;
textKey: string;
}
export const roadCardData: RoadCardProps[] = [ export const roadCardData: RoadCardProps[] = [
{ { icon: car, textKey: "services.byCar" },
icon: car, { icon: bus, textKey: "services.byBus" },
text: 'На машине', { icon: track, textKey: "services.freight" },
enText: 'Car',
},
{
icon: bus,
text: 'На автобусе',
enText: 'Public transport',
},
{
icon: track,
text: 'Freight transport',
enText: 'Car',
},
]; ];
import call from '@/public/assets/icons/service/call.svg'; import call from "@/public/assets/icons/service/call.svg";
import megaphone from '@/public/assets/icons/service/megaphone.svg'; import megaphone from "@/public/assets/icons/service/megaphone.svg";
import bag from '@/public/assets/icons/service/bag.svg'; import bag from "@/public/assets/icons/service/bag.svg";
export const contactCardData: RoadCardProps[] = [ export const contactCardData: RoadCardProps[] = [
{ { icon: call, textKey: "services.callCentre" },
icon: call, { icon: bag, textKey: "services.serviceBureau" },
text: 'Справочный центр', { icon: megaphone, textKey: "services.advertising" },
enText: 'Call centre',
},
{
icon: bag,
text: 'Услуги',
enText: 'Servise bureau',
},
{
icon: megaphone,
text: 'Реклама',
enText: 'Advertising',
},
]; ];
import partner from '@/public/assets/icons/home/partner.svg'; import partner from "@/public/assets/icons/home/partner.svg";
import { StaticImageData } from 'next/image';
export const partnersData: StaticImageData[] = [partner, partner, partner, partner, partner]; export const partnersData: StaticImageData[] = [
partner,
partner,
partner,
partner,
partner,
];

View File

@ -1,148 +1,110 @@
interface MenuItemType {
titleKey: string;
link: string;
}
interface MenuType { interface MenuType {
pathname: string; pathnameKey: string;
pathnameEn: string;
company?: boolean; company?: boolean;
members?: boolean; members?: boolean;
visitors?: boolean; visitors?: boolean;
news?: boolean; news?: boolean;
services?: boolean; services?: boolean;
info: { info: MenuItemType[];
titleEn: string;
title: string;
link: string;
}[];
} }
export const sidebarData: MenuType[] = [ export const sidebarData: MenuType[] = [
{ {
company: true, company: true,
pathname: 'О компании', pathnameKey: "sidebar.company",
pathnameEn: 'About company',
info: [ info: [
{ title: 'Коротко о нас', titleEn: 'About us', link: '/company/aboutus' }, { titleKey: "sidebar.aboutUs", link: "/company/aboutus" },
// { title: 'Выставочная деятельность', link: '' },
// { title: 'История и награды', link: '' },
// { title: 'Партнеры', link: '' },
// { title: 'Работы в компании', link: '' },
// { title: 'Наши издания', link: '' },
], ],
}, },
{ {
members: true, members: true,
pathname: 'Участникам', pathnameKey: "sidebar.participants",
pathnameEn: 'Participants',
info: [ info: [
{ { titleKey: "sidebar.participantsInfo", link: "/members" },
title: 'Информация для участников', { titleKey: "sidebar.participantsApplication", link: "/members/bid" },
titleEn: 'Information for participants', { titleKey: "sidebar.participantsRules", link: "/members/members-rules" },
link: '/members',
},
{
title: 'Онлайн заявка для участников',
titleEn: 'Online application',
link: '/members/bid',
},
{
title: 'Правила для участников',
titleEn: 'Rules for participants',
link: '/members/members-rules',
},
], ],
}, },
{ {
news: true, news: true,
pathname: 'Новости', pathnameKey: "sidebar.news",
pathnameEn: 'News', info: [{ titleKey: "sidebar.news", link: "/news" }],
info: [
{ title: 'Новости', titleEn: 'News', link: '/news' },
// { title: 'Пресс-релизы', link: '' },
],
}, },
{ {
visitors: true, visitors: true,
pathname: 'Посетителям', pathnameKey: "sidebar.visitors",
pathnameEn: 'Visitors',
info: [ info: [
{ { titleKey: "sidebar.visitorsInfo", link: "/visitors" },
title: 'Информация для посетителей', { titleKey: "sidebar.visitorsRules", link: "/visitors/rules-for-visitors" },
titleEn: 'Information for visitors',
link: '/visitors',
},
{
title: 'Порядок регистрации посетителей',
titleEn: 'Entrance rules',
link: '/visitors/rules-for-visitors',
},
], ],
}, },
{ {
services: true, services: true,
pathname: 'Услуги', pathnameKey: "sidebar.services",
pathnameEn: 'Services',
info: [ info: [
{ { titleKey: "sidebar.organizeExhibitions", link: "/services/organization" },
title: 'Организация выставок', { titleKey: "sidebar.b2bMeetings", link: "/services/meetings" },
titleEn: 'Organization of exhibitions', { titleKey: "sidebar.businessMissions", link: "/services/missions" },
link: '/services/organization', { titleKey: "sidebar.marketingServices", link: "/services/advertising" },
}, { titleKey: "sidebar.hybridEvents", link: "/services/hybrid-organizations" },
{ { titleKey: "sidebar.certification", link: "/services/certification" },
title: 'B2B Встречи и Матчмейкинг', { titleKey: "sidebar.forwarding", link: "/services/forwarding" },
titleEn: 'B2B Meetings & Business Matchmaking', { titleKey: "sidebar.outsourcing", link: "/services/outsourcing" },
link: '/services/meetings', { titleKey: "sidebar.personalTraining", link: "/services/personnel-training" },
}, { titleKey: "sidebar.businessTours", link: "/services/business-tours" },
{ { titleKey: "sidebar.additionalServices", link: "/services/additional" },
title: 'Бизнес-Миссии',
titleEn: 'Business Missions',
link: '/services/missions',
},
{
title: 'Маркетинговые услуги',
titleEn: 'Advertising activity',
link: '/services/advertising',
},
{
title: 'Организация гибридных мероприятий',
titleEn: 'Organization of hybrid events',
link: '/services/hybrid-organizations',
},
{
title: 'Сертификация',
titleEn: 'Certification',
link: '/services/certification',
},
{
title: 'Организация перевозки и таможенное оформление',
titleEn: 'Freight forwarding and customs clearance',
link: '/services/forwarding',
},
{
title: 'Аутсорсинг бухгалтерского учета и аудита',
titleEn: 'Outsourcing of accounting and auditing',
link: '/services/outsourcing',
},
{
title: 'Тренинг для персонала',
titleEn: 'Personnel-training',
link: '/services/personnel-training',
},
{
title: 'Бизнес - туры',
titleEn: 'Business - tours',
link: '/services/business-tours',
},
{
title: 'Дополнительные услуги',
titleEn: 'Additional servies',
link: '/services/additional',
},
], ],
}, },
]; ];
interface HeaderType {
titleKey: string;
link: string;
id: number;
}
export const headerMenu: HeaderType[] = [
{ titleKey: "nav.about", link: "/company/aboutus", id: 1 },
{ titleKey: "nav.news", link: "/news", id: 2 },
{ titleKey: "nav.faq", link: "/faq", id: 3 },
{ titleKey: "nav.contacts", link: "/contacts", id: 4 },
];
export const headerMenu2: HeaderType[] = [
{ titleKey: "nav.calendar", link: "/calendar", id: 1 },
{ titleKey: "nav.services", link: "/services/organization", id: 2 },
{ titleKey: "nav.about", link: "/company/aboutus", id: 3 },
{ titleKey: "nav.news", link: "/news", id: 4 },
{ titleKey: "nav.contacts", link: "/contacts", id: 5 },
];
interface FooterMenuType {
titleKey: string;
link: string;
one?: boolean;
}
export const footerMenu: FooterMenuType[] = [
{ titleKey: "nav.calendar", link: "/calendar", one: true },
{ titleKey: "nav.participants", link: "/members" },
{ titleKey: "nav.visitors", link: "" },
{ titleKey: "nav.services", link: "/services/organization" },
];
export const footerMenu2: FooterMenuType[] = [
{ titleKey: "footer.territory", link: "" },
{ titleKey: "nav.about", link: "/company/aboutus" },
{ titleKey: "footer.pressCenter", link: "" },
{ titleKey: "nav.faq", link: "/faq" },
{ titleKey: "nav.contacts", link: "/contacts" },
{ titleKey: "footer.callCentre", link: "" },
];
interface BurgerDataTypes { interface BurgerDataTypes {
pathname: string; pathname: string;
company?: boolean; company?: boolean;
@ -155,278 +117,71 @@ interface BurgerDataTypes {
visitors?: boolean; visitors?: boolean;
contacts?: boolean; contacts?: boolean;
first?: boolean; first?: boolean;
title: string; titleKey: string;
drop?: string; drop?: string;
info?: { info?: {
title: string; titleKey: string;
link: string; link: string;
}[]; }[];
} }
export const burgerMenuData: BurgerDataTypes[] = [ export const burgerMenuData: BurgerDataTypes[] = [
{ {
pathname: '/calendar', pathname: "/calendar",
calendar: true, calendar: true,
only: true, only: true,
title: 'Календарь мероприятий', titleKey: "nav.calendar",
first: true, first: true,
}, },
{ {
members: true, members: true,
title: 'Участникам', titleKey: "nav.participants",
pathname: '/members', pathname: "/members",
drop: 'members', drop: "members",
first: true, first: true,
info: [ info: [
{ title: 'Информация для участников', link: '/members' }, { titleKey: "sidebar.participantsInfo", link: "/members" },
{ title: 'Онлайн заявка для участников', link: '/members/bid' }, { titleKey: "sidebar.participantsApplication", link: "/members/bid" },
], ],
}, },
{ {
pathname: '/visitors', pathname: "/visitors",
visitors: true, visitors: true,
only: true, only: true,
title: 'Посетителям', titleKey: "nav.visitors",
first: true, first: true,
}, },
{ {
pathname: '/services', pathname: "/services",
services: true, services: true,
only: true, only: true,
title: 'Услуги', titleKey: "nav.services",
first: true, first: true,
}, },
{ {
pathname: '/faq', pathname: "/faq",
faq: true, faq: true,
only: true, only: true,
title: 'FAQ', titleKey: "nav.faq",
}, },
{ {
pathname: '/contacts', pathname: "/contacts",
contacts: true, contacts: true,
only: true, only: true,
title: 'Контакты', titleKey: "nav.contacts",
}, },
{ {
company: true, company: true,
title: 'О компании', titleKey: "nav.about",
pathname: '/company/aboutus', pathname: "/company/aboutus",
drop: 'company', drop: "company",
info: [ info: [{ titleKey: "sidebar.aboutUs", link: "/company/aboutus" }],
{ title: 'Коротко о нас', link: '/company/aboutus' },
// { title: "Выставочная деятельность", link: "" },
// { title: "История и награды", link: "" },
// { title: "Партнеры", link: "" },
// { title: "Работы в компании", link: "" },
// { title: "Наши издания", link: "" },
],
}, },
{ {
news: true, news: true,
title: 'Новости', titleKey: "nav.news",
pathname: '/news', pathname: "/news",
drop: 'news', drop: "news",
info: [ info: [{ titleKey: "sidebar.news", link: "/news" }],
{ title: 'Новости', link: '/news' },
// { title: "Пресс-релизы", link: "/news" },
],
},
];
interface HeaderType {
title: string;
link: string;
id: number;
one?: boolean;
en?: boolean;
}
export const headerMenu: HeaderType[] = [
{ title: 'О компании', link: '/company/aboutus', id: 1 },
{ title: 'Новости', link: '/news', id: 2 },
{ title: 'FAQ', link: '/faq', id: 3 },
{ title: 'Контакты', link: '/contacts', id: 4 },
{ en: true, title: 'About company', link: '/company/aboutus', id: 1 },
{ en: true, title: 'News', link: '/news', id: 2 },
{ en: true, title: 'FAQ', link: '/faq', id: 3 },
{ en: true, title: 'Contacts', link: '/contacts', id: 4 },
];
export const headerMenu2: HeaderType[] = [
{ title: 'Календарь мероприятий', link: '/calendar', id: 1 },
{ title: 'Услуги', link: '/services/organization', id: 2 },
{ title: 'О компании', link: '/company/aboutus', id: 3 },
{ title: 'Новости', link: '/news', id: 4 },
{ title: 'Контакты', link: '/contacts', id: 5 },
// { title: 'Участникам', link: '/members', id: 2 },
// { title: 'Посетителям', link: '/visitors', id: 3 },
{ en: true, title: 'Calendar of events', link: '/calendar', id: 1 },
{ en: true, title: 'Services', link: '/services/organization', id: 2 },
{ en: true, title: 'About company', link: '/company/aboutus', id: 3 },
{ en: true, title: 'News', link: '/news', id: 4 },
{ en: true, title: 'Contacts', link: '/contacts', id: 5 },
// { en: true, title: 'Participants', link: '/members', id: 2 },
// { en: true, title: 'Visitors', link: '/visitors', id: 3 },
];
interface FooterType {
title: string;
link: string;
}
export const footerMenu = [
{ title: 'Календарь мероприятий', link: '/calendar', one: true },
{ title: 'Участникам', link: '/members' },
{ title: 'Посетителям', link: '' },
{ title: 'Услуги', link: '/services/organization' },
];
export const footerMenu2: FooterType[] = [
{ title: 'Территория комплекса', link: '' },
{ title: 'О компании', link: '/company/aboutus' },
{ title: 'Пресс-центр', link: '' },
{ title: 'FAQ', link: '/faq' },
{ title: 'Контакты', link: '/contacts' },
{ title: 'Справочный центр', link: '' },
];
export const footerInfo: string[] = [
'Адрес: 744000, г. Ашхабад, просп. Битарап Туркменистан, 183',
'Тел.: +99362006200',
'+99312454111',
'E-mail: contact@turkmenexpo.com',
'Address: Ashgabat, 183 Bitarap Turkmenistan',
'ave.,744000',
'E-mail: contact@turkmenexpo.com',
];
export const topMenu = [
{
path: 'about',
links: [{ active: 'Главная', default: '/ О компании / Коротко нас' }],
},
{
path: 'members',
links: [
{
active: 'Главная',
active2: ' / Участникам',
default: ' / Информация для участников',
},
],
},
{
path: 'members/bid',
links: [
{
active: 'Главная',
default: ' / Участникам / Онлайн заявка для участников',
},
],
},
{
path: 'events',
links: [
{
active: 'Главная ',
default: '/ Календарь мероприятий',
},
],
},
{
path: 'faq',
links: [
{
active: 'Главная',
default: ' / FAQ',
},
],
},
{
path: 'contacts',
links: [
{
active: 'Главная',
default: ' / Контакты',
},
],
},
{
path: 'calendar',
links: [
{
active: 'Главная',
default: ' / Календарь мероприятий',
},
],
},
{
path: 'news',
links: [
{
active: 'Главная',
default: ' / Новости',
},
],
},
];
export const burgerLinks = [
{
title: 'О компании',
about: true,
links: [
{ name: 'Коротко о нас', link: '/about/company' },
{ name: 'Выставочная деятельность', link: '/about/company' },
{ name: 'История и награды', link: '/about/company' },
{ name: 'Партнеры', link: '/about/company' },
{ name: 'Работа в компании', link: '/about/company' },
{ name: 'Наши издания', link: '/about/company' },
],
},
{
title: 'Новости',
news: true,
links: [
{ name: 'Новости', link: '/news' },
{ name: 'Пресс центр', link: '/news' },
],
},
{
title: 'Участникам',
members: true,
links: [
{ name: 'Участникам', link: '/members' },
{ name: 'Онлайн заявка', link: '/members/bid' },
],
},
{
title: 'Контакты',
contacts: true,
links: [
{ name: 'Новости', link: '/news' },
{ name: 'Пресс центр', link: '/news' },
],
},
{
title: 'FAQ',
faq: true,
links: [
{ name: 'faq', link: '/news' },
{ name: 'Пресс центр', link: '/news' },
],
},
{
news: true,
links: [
{ name: 'Новости', link: '/news' },
{ name: 'Пресс центр', link: '/news' },
],
}, },
]; ];

View File

@ -1,12 +0,0 @@
import { cookies } from "next/headers";
export const getLang = () => {
const cookieStore = cookies();
const langCookie = cookieStore.get("lang")?.value || "ru";
// Возвращаем полный объект языка
return {
title: langCookie === "en" ? "English" : "Русский",
localization: langCookie,
};
};

View File

@ -22,6 +22,5 @@ export type NewsCardProps = {
export type RoadCardProps = { export type RoadCardProps = {
icon: any; icon: any;
text: string; textKey: string;
enText: string;
}; };

View File

@ -22,6 +22,8 @@ export interface EventDatum {
installation_date: string; installation_date: string;
dismantling_date: string; dismantling_date: string;
event_topic: string; event_topic: string;
starts_at_text: string | null
ends_at_text: string | null
} }
export interface Coorganizers { export interface Coorganizers {

32
lib/types/Reviews.type.ts Normal file
View File

@ -0,0 +1,32 @@
export interface Image {
id: number;
disk_name: string;
file_name: string;
file_size: number;
content_type: string;
title: string | null;
description: string | null;
field: string;
sort_order: number;
created_at: string;
updated_at: string;
path: string;
extension: string;
}
// Тип для элемента отзыва
export interface Review {
id: number;
name: string;
job_title: string;
text: string;
created_at: string;
updated_at: string;
image: Image | null;
}
// Основной тип ответа API
export interface ReviewsType {
status: "success" | "error";
data: Review[] | null;
}

144
messages/en.json Normal file
View File

@ -0,0 +1,144 @@
{
"common": {
"home": "Home",
"showMore": "Show more",
"send": "Send",
"formSubmitted": "Form submitted",
"of": "of"
},
"nav": {
"calendar": "Calendar of events",
"services": "Services",
"about": "About company",
"news": "News",
"contacts": "Contacts",
"faq": "FAQ",
"participants": "Participants",
"visitors": "Visitors"
},
"sidebar": {
"company": "About company",
"aboutUs": "About us",
"participants": "Participants",
"participantsInfo": "Information for participants",
"participantsApplication": "Online application",
"participantsRules": "Rules for participants",
"news": "News",
"visitors": "Visitors",
"visitorsInfo": "Information for visitors",
"visitorsRules": "Entrance rules",
"services": "Services",
"organizeExhibitions": "Organization of exhibitions",
"b2bMeetings": "B2B Meetings & Business Matchmaking",
"businessMissions": "Business Missions",
"marketingServices": "Advertising activity",
"hybridEvents": "Organization of hybrid events",
"certification": "Certification",
"forwarding": "Freight forwarding and customs clearance",
"outsourcing": "Outsourcing of accounting and auditing",
"personalTraining": "Personnel-training",
"businessTours": "Business - tours",
"additionalServices": "Additional services"
},
"burger": {
"services": "Services",
"about": "About company",
"aboutUs": "About us",
"advertisingActivity": "Advertising activity",
"freightForwarding": "Freight forwarding and customs clearance",
"accountingOutsourcing": "Outsourcing of accounting and auditing",
"personnelTraining": "Personnel-training",
"calendar": "Calendar of events",
"participantsInfo": "Information for participants",
"participantsApplication": "Online application"
},
"home": {
"exhibitions": "Exhibitions",
"goToWebsite": "Go to website",
"news": "News",
"allNews": "All news",
"upcomingExhibitions": "Upcoming exhibitions and events",
"partners": "Partners",
"feedback": "Feedback"
},
"events": {
"organiserLabel": "Organiser:",
"coOrganiserLabel": "Co-organiser:",
"registration": "Registration",
"visitSite": "Visit site",
"more": "More",
"showMore": "Show more",
"date": "Date",
"venue": "Venue",
"organiser": "Organiser",
"coOrganiser": "Co-organiser",
"description": "Description",
"theme": "Theme of event"
},
"contacts": {
"title": "Contacts",
"contactUs": "Contact us",
"name": "Name",
"email": "E-mail",
"phone": "Phone",
"companyName": "Company name",
"message": "Message",
"address": "Address:",
"addressValue": "744000, Ashgabat, 183 Bitarap Turkmenistan ave.",
"phoneNumbers": "+993 71 971813; +993 62 006200"
},
"footer": {
"address": "Address: Ashgabat, 183 Bitarap Turkmenistan ave., 744000",
"phone": "Phone: +993 71 971813",
"phone2": "+993 62 006200",
"email": "E-mail: contact@turkmenexpo.com",
"territory": "Complex territory",
"pressCenter": "Press center",
"callCentre": "Call centre"
},
"search": {
"placeholder": "What to find?",
"all": "Everywhere",
"inEvents": "In events",
"inNews": "In news",
"findButton": "Find",
"byRequest": "By request \"",
"found": "\" found",
"results": "results",
"goToPage": "Go to page",
"noResults": "Nothing found for your request"
},
"services": {
"byCar": "Car",
"byBus": "Public transport",
"freight": "Freight transport",
"callCentre": "Call centre",
"serviceBureau": "Service bureau",
"advertising": "Advertising",
"breadcrumb": "Services",
"routes": "Routes"
},
"validation": {
"nameRequired": "Name is required",
"emailRequired": "Email is required",
"phoneRequired": "Phone number is required",
"messageRequired": "Message is required"
},
"visitors": {
"title": "For visitors",
"information": "Information for visitors",
"rules": "Entrance rules"
},
"about": {
"title": "About us"
},
"news": {
"title": "News",
"mediaAboutUs": "Media about us",
"allNews": "All news",
"article": "Article"
},
"calendar": {
"title": "Calendar of events"
}
}

144
messages/ru.json Normal file
View File

@ -0,0 +1,144 @@
{
"common": {
"home": "Главная",
"showMore": "Показать ещё",
"send": "Отправить",
"formSubmitted": "Форма отправлена",
"of": "из"
},
"nav": {
"calendar": "Календарь мероприятий",
"services": "Услуги",
"about": "О компании",
"news": "Новости",
"contacts": "Контакты",
"faq": "FAQ",
"participants": "Участникам",
"visitors": "Посетителям"
},
"sidebar": {
"company": "О компании",
"aboutUs": "Коротко о нас",
"participants": "Участникам",
"participantsInfo": "Информация для участников",
"participantsApplication": "Онлайн заявка для участников",
"participantsRules": "Правила для участников",
"news": "Новости",
"visitors": "Посетителям",
"visitorsInfo": "Информация для посетителей",
"visitorsRules": "Порядок регистрации посетителей",
"services": "Услуги",
"organizeExhibitions": "Организация выставок",
"b2bMeetings": "B2B Встречи и Матчмейкинг",
"businessMissions": "Бизнес-Миссии",
"marketingServices": "Маркетинговые услуги",
"hybridEvents": "Организация гибридных мероприятий",
"certification": "Сертификация",
"forwarding": "Организация перевозки и таможенное оформление",
"outsourcing": "Аутсорсинг бухгалтерского учета и аудита",
"personalTraining": "Тренинг для персонала",
"businessTours": "Бизнес - туры",
"additionalServices": "Дополнительные услуги"
},
"burger": {
"services": "Услуги",
"about": "О компании",
"aboutUs": "О нас",
"advertisingActivity": "Рекламная деятельность",
"freightForwarding": "Экспедирование грузов и таможенное оформление",
"accountingOutsourcing": "Аутсорсинг бух.учета и аудита",
"personnelTraining": "Обучения персонала",
"calendar": "Календарь мероприятий",
"participantsInfo": "Информация для участников",
"participantsApplication": "Онлайн заявка для участников"
},
"home": {
"exhibitions": "Выставки",
"goToWebsite": "Перейти на сайт",
"news": "Новости",
"allNews": "Все новости",
"upcomingExhibitions": "Ближайшие выставки и мероприятия",
"partners": "Партнёры",
"feedback": "Обратная связь"
},
"events": {
"organiserLabel": "Организатор:",
"coOrganiserLabel": "Со-организатор:",
"registration": "Зарегистрироваться",
"visitSite": "Посетить сайт",
"more": "Подробнее",
"showMore": "Показать еще",
"date": "Дата",
"venue": "Место",
"organiser": "Организатор",
"coOrganiser": "Со-организатор",
"description": "Описание",
"theme": "Тематика мероприятия"
},
"contacts": {
"title": "Контакты",
"contactUs": "Связаться с нами",
"name": "Имя",
"email": "E-mail",
"phone": "Номер",
"companyName": "Название компании",
"message": "Сообщение",
"address": "Адрес:",
"addressValue": "744000, г. Ашхабад, просп. Битарап Туркменистан, 183",
"phoneNumbers": "+993 71 971813; +993 62 006200"
},
"footer": {
"address": "Адрес: 744000, г. Ашхабад, просп. Битарап Туркменистан, 183",
"phone": "Тел.: +993 71 971813",
"phone2": "+993 62 006200",
"email": "E-mail: contact@turkmenexpo.com",
"territory": "Территория комплекса",
"pressCenter": "Пресс-центр",
"callCentre": "Справочный центр"
},
"search": {
"placeholder": "Что найти?",
"all": "Везде",
"inEvents": "В событиях",
"inNews": "В новостях",
"findButton": "Найти",
"byRequest": "По запросу «",
"found": "» нашлось",
"results": "результатов",
"goToPage": "Перейти на страницу",
"noResults": "По вашему запросу ничего не найдено"
},
"services": {
"byCar": "На машине",
"byBus": "На автобусе",
"freight": "Грузовой транспорт",
"callCentre": "Справочный центр",
"serviceBureau": "Услуги",
"advertising": "Реклама",
"breadcrumb": "Сервисы",
"routes": "Как добраться"
},
"validation": {
"nameRequired": "Имя необходимо",
"emailRequired": "Email необходим",
"phoneRequired": "Номер телефона необходим",
"messageRequired": "Сообщение необходимо"
},
"visitors": {
"title": "Посетителям",
"information": "Информация для посетителей",
"rules": "Порядок регистрации посетителей"
},
"about": {
"title": "Коротко о нас"
},
"news": {
"title": "Новости",
"mediaAboutUs": "СМИ о нас",
"allNews": "Все новости",
"article": "Статья"
},
"calendar": {
"title": "Календарь мероприятий"
}
}

144
messages/tm.json Normal file
View File

@ -0,0 +1,144 @@
{
"common": {
"home": "Baş sahypa",
"showMore": "Ýene görkez",
"send": "Iber",
"formSubmitted": "Forma iberildi",
"of": "-dan"
},
"nav": {
"calendar": "Çäreleriň senenamasy",
"services": "Hyzmatlar",
"about": "Kompaniýa hakynda",
"news": "Täzelikler",
"contacts": "Aragatnaşyk",
"faq": "FAQ",
"participants": "Gatnaşyjylara",
"visitors": "Gelýänlere"
},
"sidebar": {
"company": "Kompaniýa hakynda",
"aboutUs": "Biz barada",
"participants": "Gatnaşyjylara",
"participantsInfo": "Gatnaşyjylar üçin maglumat",
"participantsApplication": "Onlaýn arza",
"participantsRules": "Gatnaşyjylar üçin düzgünler",
"news": "Täzelikler",
"visitors": "Gelýänlere",
"visitorsInfo": "Gelýänler üçin maglumat",
"visitorsRules": "Gelýänleri hasaba almagyň tertibi",
"services": "Hyzmatlar",
"organizeExhibitions": "Sergileri gurnamak",
"b2bMeetings": "B2B Duşuşyklar we işewür gabatlaşdyrmak",
"businessMissions": "Işewürlik missiýalary",
"marketingServices": "Mahabat işi",
"hybridEvents": "Gibrid çäreleri gurnamak",
"certification": "Sertifikasiýa",
"forwarding": "Ýük daşamak we gümrük resmileşdirmek",
"outsourcing": "Buhgalterçilik we audit autsorsingi",
"personalTraining": "Işgärleri taýýarlamak",
"businessTours": "Işewürlik syýahatlary",
"additionalServices": "Goşmaça hyzmatlar"
},
"burger": {
"services": "Hyzmatlar",
"about": "Kompaniýa hakynda",
"aboutUs": "Biz barada",
"advertisingActivity": "Mahabat işi",
"freightForwarding": "Ýük daşamak we gümrük resmileşdirmek",
"accountingOutsourcing": "Buhgalterçilik we audit autsorsingi",
"personnelTraining": "Işgärleri taýýarlamak",
"calendar": "Çäreleriň senenamasy",
"participantsInfo": "Gatnaşyjylar üçin maglumat",
"participantsApplication": "Onlaýn arza"
},
"home": {
"exhibitions": "Sergiler",
"goToWebsite": "Saýta geçiň",
"news": "Täzelikler",
"allNews": "Ähli täzelikler",
"upcomingExhibitions": "Ýakyn sergiler we çäreler",
"partners": "Hyzmatdaşlar",
"feedback": "Yzyna aragatnaşyk"
},
"events": {
"organiserLabel": "Guramaçy:",
"coOrganiserLabel": "Bilelikdäki guramaçy:",
"registration": "Hasaba durmak",
"visitSite": "Saýta girmek",
"more": "Giňişleýin",
"showMore": "Ýene görkez",
"date": "Sene",
"venue": "Ýeri",
"organiser": "Guramaçy",
"coOrganiser": "Bilelikdäki guramaçy",
"description": "Beýany",
"theme": "Çäräniň mowzugy"
},
"contacts": {
"title": "Aragatnaşyk",
"contactUs": "Biz bilen habarlaşyň",
"name": "Ady",
"email": "E-poçta",
"phone": "Telefon",
"companyName": "Kompaniýanyň ady",
"message": "Habar",
"address": "Salgysy:",
"addressValue": "744000, Aşgabat ş., Bitarap Türkmenistan şaýoly, 183",
"phoneNumbers": "+993 71 971813; +993 62 006200"
},
"footer": {
"address": "Salgysy: 744000, Aşgabat ş., Bitarap Türkmenistan şaýoly, 183",
"phone": "Tel.: +993 71 971813",
"phone2": "+993 62 006200",
"email": "E-poçta: contact@turkmenexpo.com",
"territory": "Toplumyň çägi",
"pressCenter": "Metbugat merkezi",
"callCentre": "Maglumat merkezi"
},
"search": {
"placeholder": "Näme gözlemeli?",
"all": "Hemme ýerde",
"inEvents": "Çärelerde",
"inNews": "Täzeliklerde",
"findButton": "Gözle",
"byRequest": "Isleg boýunça «",
"found": "» tapyldy",
"results": "netije",
"goToPage": "Sahypa geçiň",
"noResults": "Siziň islegiňiz boýunça hiç zat tapylmady"
},
"services": {
"byCar": "Awtoulag bilen",
"byBus": "Awtobus bilen",
"freight": "Ýük ulagy",
"callCentre": "Maglumat merkezi",
"serviceBureau": "Hyzmatlar",
"advertising": "Mahabat",
"breadcrumb": "Hyzmatlar",
"routes": "Nädip barmaly"
},
"validation": {
"nameRequired": "Ady gerekli",
"emailRequired": "E-poçta gerekli",
"phoneRequired": "Telefon belgisi gerekli",
"messageRequired": "Habar gerekli"
},
"visitors": {
"title": "Gelýänlere",
"information": "Gelýänler üçin maglumat",
"rules": "Gelýänleri hasaba almagyň tertibi"
},
"about": {
"title": "Biz barada"
},
"news": {
"title": "Täzelikler",
"mediaAboutUs": "Metbugat biz barada",
"allNews": "Ähli täzelikler",
"article": "Makala"
},
"calendar": {
"title": "Çäreleriň senenamasy"
}
}

13
middleware.ts Normal file
View File

@ -0,0 +1,13 @@
import createMiddleware from "next-intl/middleware";
import { locales, defaultLocale } from "./i18n/config";
export default createMiddleware({
locales,
defaultLocale,
localePrefix: "always",
localeDetection: true,
});
export const config = {
matcher: ["/((?!api|_next|_vercel|.*\\..*).*)"],
};

View File

@ -1,7 +1,11 @@
import createNextIntlPlugin from "next-intl/plugin";
const withNextIntl = createNextIntlPlugin("./i18n/request.ts");
/** @type {import('next').NextConfig} */ /** @type {import('next').NextConfig} */
const nextConfig = { const nextConfig = {
images: { unoptimized: true }, images: { unoptimized: true },
distDir: "build", distDir: "build",
}; };
export default nextConfig; export default withNextIntl(nextConfig);

717
package-lock.json generated
View File

@ -15,6 +15,7 @@
"clsx": "^2.1.0", "clsx": "^2.1.0",
"framer-motion": "^11.0.25", "framer-motion": "^11.0.25",
"next": "14.1.0", "next": "14.1.0",
"next-intl": "^4.8.2",
"pm2": "^5.3.1", "pm2": "^5.3.1",
"react": "^18", "react": "^18",
"react-dom": "^18", "react-dom": "^18",
@ -59,6 +60,67 @@
"tslib": "^2.4.0" "tslib": "^2.4.0"
} }
}, },
"node_modules/@formatjs/ecma402-abstract": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-3.1.1.tgz",
"integrity": "sha512-jhZbTwda+2tcNrs4kKvxrPLPjx8QsBCLCUgrrJ/S+G9YrGHWLhAyFMMBHJBnBoOwuLHd7L14FgYudviKaxkO2Q==",
"license": "MIT",
"dependencies": {
"@formatjs/fast-memoize": "3.1.0",
"@formatjs/intl-localematcher": "0.8.1",
"decimal.js": "^10.6.0",
"tslib": "^2.8.1"
}
},
"node_modules/@formatjs/ecma402-abstract/node_modules/@formatjs/intl-localematcher": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.8.1.tgz",
"integrity": "sha512-xwEuwQFdtSq1UKtQnyTZWC+eHdv7Uygoa+H2k/9uzBVQjDyp9r20LNDNKedWXll7FssT3GRHvqsdJGYSUWqYFA==",
"license": "MIT",
"dependencies": {
"@formatjs/fast-memoize": "3.1.0",
"tslib": "^2.8.1"
}
},
"node_modules/@formatjs/fast-memoize": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/@formatjs/fast-memoize/-/fast-memoize-3.1.0.tgz",
"integrity": "sha512-b5mvSWCI+XVKiz5WhnBCY3RJ4ZwfjAidU0yVlKa3d3MSgKmH1hC3tBGEAtYyN5mqL7N0G5x0BOUYyO8CEupWgg==",
"license": "MIT",
"dependencies": {
"tslib": "^2.8.1"
}
},
"node_modules/@formatjs/icu-messageformat-parser": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-3.5.1.tgz",
"integrity": "sha512-sSDmSvmmoVQ92XqWb499KrIhv/vLisJU8ITFrx7T7NZHUmMY7EL9xgRowAosaljhqnj/5iufG24QrdzB6X3ItA==",
"license": "MIT",
"dependencies": {
"@formatjs/ecma402-abstract": "3.1.1",
"@formatjs/icu-skeleton-parser": "2.1.1",
"tslib": "^2.8.1"
}
},
"node_modules/@formatjs/icu-skeleton-parser": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-2.1.1.tgz",
"integrity": "sha512-PSFABlcNefjI6yyk8f7nyX1DC7NHmq6WaCHZLySEXBrXuLOB2f935YsnzuPjlz+ibhb9yWTdPeVX1OVcj24w2Q==",
"license": "MIT",
"dependencies": {
"@formatjs/ecma402-abstract": "3.1.1",
"tslib": "^2.8.1"
}
},
"node_modules/@formatjs/intl-localematcher": {
"version": "0.5.10",
"resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.5.10.tgz",
"integrity": "sha512-af3qATX+m4Rnd9+wHcjJ4w2ijq+rAVP3CCinJQvFv1kgSu1W6jypUmvleJxcewdxmutM8dmIRZFxO/IQBZmP2Q==",
"license": "MIT",
"dependencies": {
"tslib": "2"
}
},
"node_modules/@googlemaps/js-api-loader": { "node_modules/@googlemaps/js-api-loader": {
"version": "1.16.2", "version": "1.16.2",
"resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz", "resolved": "https://registry.npmjs.org/@googlemaps/js-api-loader/-/js-api-loader-1.16.2.tgz",
@ -831,6 +893,313 @@
"uuid": "bin/uuid" "uuid": "bin/uuid"
} }
}, },
"node_modules/@parcel/watcher": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.6.tgz",
"integrity": "sha512-tmmZ3lQxAe/k/+rNnXQRawJ4NjxO2hqiOLTHvWchtGZULp4RyFeh6aU4XdOYBFe2KE1oShQTv4AblOs2iOrNnQ==",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
"detect-libc": "^2.0.3",
"is-glob": "^4.0.3",
"node-addon-api": "^7.0.0",
"picomatch": "^4.0.3"
},
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
},
"optionalDependencies": {
"@parcel/watcher-android-arm64": "2.5.6",
"@parcel/watcher-darwin-arm64": "2.5.6",
"@parcel/watcher-darwin-x64": "2.5.6",
"@parcel/watcher-freebsd-x64": "2.5.6",
"@parcel/watcher-linux-arm-glibc": "2.5.6",
"@parcel/watcher-linux-arm-musl": "2.5.6",
"@parcel/watcher-linux-arm64-glibc": "2.5.6",
"@parcel/watcher-linux-arm64-musl": "2.5.6",
"@parcel/watcher-linux-x64-glibc": "2.5.6",
"@parcel/watcher-linux-x64-musl": "2.5.6",
"@parcel/watcher-win32-arm64": "2.5.6",
"@parcel/watcher-win32-ia32": "2.5.6",
"@parcel/watcher-win32-x64": "2.5.6"
}
},
"node_modules/@parcel/watcher-android-arm64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.6.tgz",
"integrity": "sha512-YQxSS34tPF/6ZG7r/Ih9xy+kP/WwediEUsqmtf0cuCV5TPPKw/PQHRhueUo6JdeFJaqV3pyjm0GdYjZotbRt/A==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"android"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-darwin-arm64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.6.tgz",
"integrity": "sha512-Z2ZdrnwyXvvvdtRHLmM4knydIdU9adO3D4n/0cVipF3rRiwP+3/sfzpAwA/qKFL6i1ModaabkU7IbpeMBgiVEA==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-darwin-x64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.6.tgz",
"integrity": "sha512-HgvOf3W9dhithcwOWX9uDZyn1lW9R+7tPZ4sug+NGrGIo4Rk1hAXLEbcH1TQSqxts0NYXXlOWqVpvS1SFS4fRg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-freebsd-x64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.6.tgz",
"integrity": "sha512-vJVi8yd/qzJxEKHkeemh7w3YAn6RJCtYlE4HPMoVnCpIXEzSrxErBW5SJBgKLbXU3WdIpkjBTeUNtyBVn8TRng==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"freebsd"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm-glibc": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.6.tgz",
"integrity": "sha512-9JiYfB6h6BgV50CCfasfLf/uvOcJskMSwcdH1PHH9rvS1IrNy8zad6IUVPVUfmXr+u+Km9IxcfMLzgdOudz9EQ==",
"cpu": [
"arm"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm-musl": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.6.tgz",
"integrity": "sha512-Ve3gUCG57nuUUSyjBq/MAM0CzArtuIOxsBdQ+ftz6ho8n7s1i9E1Nmk/xmP323r2YL0SONs1EuwqBp2u1k5fxg==",
"cpu": [
"arm"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm64-glibc": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.6.tgz",
"integrity": "sha512-f2g/DT3NhGPdBmMWYoxixqYr3v/UXcmLOYy16Bx0TM20Tchduwr4EaCbmxh1321TABqPGDpS8D/ggOTaljijOA==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-arm64-musl": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.6.tgz",
"integrity": "sha512-qb6naMDGlbCwdhLj6hgoVKJl2odL34z2sqkC7Z6kzir8b5W65WYDpLB6R06KabvZdgoHI/zxke4b3zR0wAbDTA==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-x64-glibc": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.6.tgz",
"integrity": "sha512-kbT5wvNQlx7NaGjzPFu8nVIW1rWqV780O7ZtkjuWaPUgpv2NMFpjYERVi0UYj1msZNyCzGlaCWEtzc+exjMGbQ==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-linux-x64-musl": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.6.tgz",
"integrity": "sha512-1JRFeC+h7RdXwldHzTsmdtYR/Ku8SylLgTU/reMuqdVD7CtLwf0VR1FqeprZ0eHQkO0vqsbvFLXUmYm/uNKJBg==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-win32-arm64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.6.tgz",
"integrity": "sha512-3ukyebjc6eGlw9yRt678DxVF7rjXatWiHvTXqphZLvo7aC5NdEgFufVwjFfY51ijYEWpXbqF5jtrK275z52D4Q==",
"cpu": [
"arm64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-win32-ia32": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.6.tgz",
"integrity": "sha512-k35yLp1ZMwwee3Ez/pxBi5cf4AoBKYXj00CZ80jUz5h8prpiaQsiRPKQMxoLstNuqe2vR4RNPEAEcjEFzhEz/g==",
"cpu": [
"ia32"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher-win32-x64": {
"version": "2.5.6",
"resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.6.tgz",
"integrity": "sha512-hbQlYcCq5dlAX9Qx+kFb0FHue6vbjlf0FrNzSKdYK2APUf7tGfGxQCk2ihEREmbR6ZMc0MVAD5RIX/41gpUzTw==",
"cpu": [
"x64"
],
"license": "MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">= 10.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/parcel"
}
},
"node_modules/@parcel/watcher/node_modules/picomatch": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/@pkgjs/parseargs": { "node_modules/@pkgjs/parseargs": {
"version": "0.11.0", "version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
@ -1155,6 +1524,178 @@
} }
} }
}, },
"node_modules/@schummar/icu-type-parser": {
"version": "1.21.5",
"resolved": "https://registry.npmjs.org/@schummar/icu-type-parser/-/icu-type-parser-1.21.5.tgz",
"integrity": "sha512-bXHSaW5jRTmke9Vd0h5P7BtWZG9Znqb8gSDxZnxaGSJnGwPLDPfS+3g0BKzeWqzgZPsIVZkM7m2tbo18cm5HBw==",
"license": "MIT"
},
"node_modules/@swc/core-darwin-arm64": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.11.tgz",
"integrity": "sha512-QoIupRWVH8AF1TgxYyeA5nS18dtqMuxNwchjBIwJo3RdwLEFiJq6onOx9JAxHtuPwUkIVuU2Xbp+jCJ7Vzmgtg==",
"cpu": [
"arm64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-darwin-x64": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.15.11.tgz",
"integrity": "sha512-S52Gu1QtPSfBYDiejlcfp9GlN+NjTZBRRNsz8PNwBgSE626/FUf2PcllVUix7jqkoMC+t0rS8t+2/aSWlMuQtA==",
"cpu": [
"x64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-arm-gnueabihf": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.11.tgz",
"integrity": "sha512-lXJs8oXo6Z4yCpimpQ8vPeCjkgoHu5NoMvmJZ8qxDyU99KVdg6KwU9H79vzrmB+HfH+dCZ7JGMqMF//f8Cfvdg==",
"cpu": [
"arm"
],
"license": "Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-arm64-gnu": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.11.tgz",
"integrity": "sha512-chRsz1K52/vj8Mfq/QOugVphlKPWlMh10V99qfH41hbGvwAU6xSPd681upO4bKiOr9+mRIZZW+EfJqY42ZzRyA==",
"cpu": [
"arm64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-arm64-musl": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.11.tgz",
"integrity": "sha512-PYftgsTaGnfDK4m6/dty9ryK1FbLk+LosDJ/RJR2nkXGc8rd+WenXIlvHjWULiBVnS1RsjHHOXmTS4nDhe0v0w==",
"cpu": [
"arm64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-x64-gnu": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.11.tgz",
"integrity": "sha512-DKtnJKIHiZdARyTKiX7zdRjiDS1KihkQWatQiCHMv+zc2sfwb4Glrodx2VLOX4rsa92NLR0Sw8WLcPEMFY1szQ==",
"cpu": [
"x64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-linux-x64-musl": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.11.tgz",
"integrity": "sha512-mUjjntHj4+8WBaiDe5UwRNHuEzLjIWBTSGTw0JT9+C9/Yyuh4KQqlcEQ3ro6GkHmBGXBFpGIj/o5VMyRWfVfWw==",
"cpu": [
"x64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-win32-arm64-msvc": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.11.tgz",
"integrity": "sha512-ZkNNG5zL49YpaFzfl6fskNOSxtcZ5uOYmWBkY4wVAvgbSAQzLRVBp+xArGWh2oXlY/WgL99zQSGTv7RI5E6nzA==",
"cpu": [
"arm64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-win32-ia32-msvc": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.11.tgz",
"integrity": "sha512-6XnzORkZCQzvTQ6cPrU7iaT9+i145oLwnin8JrfsLG41wl26+5cNQ2XV3zcbrnFEV6esjOceom9YO1w9mGJByw==",
"cpu": [
"ia32"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/core-win32-x64-msvc": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.11.tgz",
"integrity": "sha512-IQ2n6af7XKLL6P1gIeZACskSxK8jWtoKpJWLZmdXTDj1MGzktUy4i+FvpdtxFmJWNavRWH1VmTr6kAubRDHeKw==",
"cpu": [
"x64"
],
"license": "Apache-2.0 AND MIT",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=10"
}
},
"node_modules/@swc/counter": {
"version": "0.1.3",
"resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz",
"integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==",
"license": "Apache-2.0"
},
"node_modules/@swc/helpers": { "node_modules/@swc/helpers": {
"version": "0.5.2", "version": "0.5.2",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz", "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.2.tgz",
@ -1163,6 +1704,15 @@
"tslib": "^2.4.0" "tslib": "^2.4.0"
} }
}, },
"node_modules/@swc/types": {
"version": "0.1.25",
"resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.25.tgz",
"integrity": "sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==",
"license": "Apache-2.0",
"dependencies": {
"@swc/counter": "^0.1.3"
}
},
"node_modules/@tootallnate/quickjs-emscripten": { "node_modules/@tootallnate/quickjs-emscripten": {
"version": "0.23.0", "version": "0.23.0",
"resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
@ -2005,6 +2555,12 @@
"ms": "2.0.0" "ms": "2.0.0"
} }
}, },
"node_modules/decimal.js": {
"version": "10.6.0",
"resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz",
"integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==",
"license": "MIT"
},
"node_modules/deep-extend": { "node_modules/deep-extend": {
"version": "0.6.0", "version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
@ -2027,9 +2583,10 @@
} }
}, },
"node_modules/detect-libc": { "node_modules/detect-libc": {
"version": "2.0.2", "version": "2.1.2",
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.2.tgz", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz",
"integrity": "sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==",
"license": "Apache-2.0",
"engines": { "engines": {
"node": ">=8" "node": ">=8"
} }
@ -2570,6 +3127,21 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/icu-minify": {
"version": "4.8.2",
"resolved": "https://registry.npmjs.org/icu-minify/-/icu-minify-4.8.2.tgz",
"integrity": "sha512-LHBQV+skKkjZSPd590pZ7ZAHftUgda3eFjeuNwA8/15L8T8loCNBktKQyTlkodAU86KovFXeg/9WntlAo5wA5A==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/amannn"
}
],
"license": "MIT",
"dependencies": {
"@formatjs/icu-messageformat-parser": "^3.4.0"
}
},
"node_modules/immer": { "node_modules/immer": {
"version": "10.0.3", "version": "10.0.3",
"resolved": "https://registry.npmjs.org/immer/-/immer-10.0.3.tgz", "resolved": "https://registry.npmjs.org/immer/-/immer-10.0.3.tgz",
@ -2598,6 +3170,18 @@
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
"integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
}, },
"node_modules/intl-messageformat": {
"version": "11.1.2",
"resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-11.1.2.tgz",
"integrity": "sha512-ucSrQmZGAxfiBHfBRXW/k7UC8MaGFlEj4Ry1tKiDcmgwQm1y3EDl40u+4VNHYomxJQMJi9NEI3riDRlth96jKg==",
"license": "BSD-3-Clause",
"dependencies": {
"@formatjs/ecma402-abstract": "3.1.1",
"@formatjs/fast-memoize": "3.1.0",
"@formatjs/icu-messageformat-parser": "3.5.1",
"tslib": "^2.8.1"
}
},
"node_modules/invariant": { "node_modules/invariant": {
"version": "2.2.4", "version": "2.2.4",
"resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
@ -3103,6 +3687,91 @@
} }
} }
}, },
"node_modules/next-intl": {
"version": "4.8.2",
"resolved": "https://registry.npmjs.org/next-intl/-/next-intl-4.8.2.tgz",
"integrity": "sha512-GuuwyvyEI49/oehQbBXEoY8KSIYCzmfMLhmIwhMXTb+yeBmly1PnJcpgph3KczQ+HTJMXwXCmkizgtT8jBMf3A==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/amannn"
}
],
"license": "MIT",
"dependencies": {
"@formatjs/intl-localematcher": "^0.5.4",
"@parcel/watcher": "^2.4.1",
"@swc/core": "^1.15.2",
"icu-minify": "^4.8.2",
"negotiator": "^1.0.0",
"next-intl-swc-plugin-extractor": "^4.8.2",
"po-parser": "^2.1.1",
"use-intl": "^4.8.2"
},
"peerDependencies": {
"next": "^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0",
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0",
"typescript": "^5.0.0"
},
"peerDependenciesMeta": {
"typescript": {
"optional": true
}
}
},
"node_modules/next-intl-swc-plugin-extractor": {
"version": "4.8.2",
"resolved": "https://registry.npmjs.org/next-intl-swc-plugin-extractor/-/next-intl-swc-plugin-extractor-4.8.2.tgz",
"integrity": "sha512-sHDs36L1VZmFHj3tPHsD+KZJtnsRudHlNvT0ieIe3iFVn5OpGLTxW3d/Zc/2LXSj5GpGuR6wQeikbhFjU9tMQQ==",
"license": "MIT"
},
"node_modules/next-intl/node_modules/@swc/core": {
"version": "1.15.11",
"resolved": "https://registry.npmjs.org/@swc/core/-/core-1.15.11.tgz",
"integrity": "sha512-iLmLTodbYxU39HhMPaMUooPwO/zqJWvsqkrXv1ZI38rMb048p6N7qtAtTp37sw9NzSrvH6oli8EdDygo09IZ/w==",
"hasInstallScript": true,
"license": "Apache-2.0",
"dependencies": {
"@swc/counter": "^0.1.3",
"@swc/types": "^0.1.25"
},
"engines": {
"node": ">=10"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/swc"
},
"optionalDependencies": {
"@swc/core-darwin-arm64": "1.15.11",
"@swc/core-darwin-x64": "1.15.11",
"@swc/core-linux-arm-gnueabihf": "1.15.11",
"@swc/core-linux-arm64-gnu": "1.15.11",
"@swc/core-linux-arm64-musl": "1.15.11",
"@swc/core-linux-x64-gnu": "1.15.11",
"@swc/core-linux-x64-musl": "1.15.11",
"@swc/core-win32-arm64-msvc": "1.15.11",
"@swc/core-win32-ia32-msvc": "1.15.11",
"@swc/core-win32-x64-msvc": "1.15.11"
},
"peerDependencies": {
"@swc/helpers": ">=0.5.17"
},
"peerDependenciesMeta": {
"@swc/helpers": {
"optional": true
}
}
},
"node_modules/next-intl/node_modules/negotiator": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
"integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/next/node_modules/postcss": { "node_modules/next/node_modules/postcss": {
"version": "8.4.31", "version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
@ -3130,6 +3799,12 @@
"node": "^10 || ^12 || >=14" "node": "^10 || ^12 || >=14"
} }
}, },
"node_modules/node-addon-api": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz",
"integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==",
"license": "MIT"
},
"node_modules/node-releases": { "node_modules/node-releases": {
"version": "2.0.14", "version": "2.0.14",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
@ -3651,6 +4326,12 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
}, },
"node_modules/po-parser": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/po-parser/-/po-parser-2.1.1.tgz",
"integrity": "sha512-ECF4zHLbUItpUgE3OTtLKlPjeBN+fKEczj2zYjDfCGOzicNs0GK3Vg2IoAYwx7LH/XYw43fZQP6xnZ4TkNxSLQ==",
"license": "MIT"
},
"node_modules/postcss": { "node_modules/postcss": {
"version": "8.4.35", "version": "8.4.35",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.35.tgz",
@ -4757,9 +5438,10 @@
"dev": true "dev": true
}, },
"node_modules/tslib": { "node_modules/tslib": {
"version": "2.6.2", "version": "2.8.1",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
"integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
"license": "0BSD"
}, },
"node_modules/tv4": { "node_modules/tv4": {
"version": "1.3.0", "version": "1.3.0",
@ -4793,7 +5475,7 @@
"version": "5.3.3", "version": "5.3.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz",
"integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==", "integrity": "sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==",
"dev": true, "devOptional": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
"tsserver": "bin/tsserver" "tsserver": "bin/tsserver"
@ -4882,6 +5564,27 @@
"react": ">=16.8.0" "react": ">=16.8.0"
} }
}, },
"node_modules/use-intl": {
"version": "4.8.2",
"resolved": "https://registry.npmjs.org/use-intl/-/use-intl-4.8.2.tgz",
"integrity": "sha512-3VNXZgDnPFqhIYosQ9W1Hc6K5q+ZelMfawNbexdwL/dY7BTHbceLUBX5Eeex9lgogxTp0pf1SjHuhYNAjr9H3g==",
"funding": [
{
"type": "individual",
"url": "https://github.com/sponsors/amannn"
}
],
"license": "MIT",
"dependencies": {
"@formatjs/fast-memoize": "^3.1.0",
"@schummar/icu-type-parser": "1.21.5",
"icu-minify": "^4.8.2",
"intl-messageformat": "^11.1.0"
},
"peerDependencies": {
"react": "^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0"
}
},
"node_modules/use-sync-external-store": { "node_modules/use-sync-external-store": {
"version": "1.2.0", "version": "1.2.0",
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz",

View File

@ -17,6 +17,7 @@
"clsx": "^2.1.0", "clsx": "^2.1.0",
"framer-motion": "^11.0.25", "framer-motion": "^11.0.25",
"next": "14.1.0", "next": "14.1.0",
"next-intl": "^4.8.2",
"pm2": "^5.3.1", "pm2": "^5.3.1",
"react": "^18", "react": "^18",
"react-dom": "^18", "react-dom": "^18",

View File

@ -0,0 +1,4 @@
<svg width="35" height="35" viewBox="0 0 35 35" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.6673 30.625C12.4409 30.625 13.1827 30.3177 13.7297 29.7707C14.2767 29.2237 14.584 28.4819 14.584 27.7083V18.9583C14.584 18.1848 14.2767 17.4429 13.7297 16.8959C13.1827 16.349 12.4409 16.0417 11.6673 16.0417C11.2805 16.0417 10.9096 15.888 10.6361 15.6145C10.3626 15.341 10.209 14.9701 10.209 14.5833V13.125C10.209 12.3515 10.5163 11.6096 11.0633 11.0626C11.6102 10.5156 12.3521 10.2083 13.1257 10.2083C13.5124 10.2083 13.8834 10.0547 14.1568 9.7812C14.4303 9.50771 14.584 9.13677 14.584 8.75V5.83333C14.584 5.44656 14.4303 5.07562 14.1568 4.80213C13.8834 4.52864 13.5124 4.375 13.1257 4.375C10.805 4.375 8.57941 5.29687 6.93847 6.93781C5.29752 8.57876 4.37565 10.8044 4.37565 13.125V27.7083C4.37565 28.4819 4.68294 29.2237 5.22992 29.7707C5.77691 30.3177 6.51877 30.625 7.29232 30.625H11.6673Z" fill="#059784"/>
<path d="M27.7083 30.625C28.4819 30.625 29.2237 30.3177 29.7707 29.7707C30.3177 29.2237 30.625 28.4819 30.625 27.7083V18.9583C30.625 18.1848 30.3177 17.4429 29.7707 16.8959C29.2237 16.349 28.4819 16.0417 27.7083 16.0417C27.3216 16.0417 26.9506 15.888 26.6771 15.6145C26.4036 15.341 26.25 14.9701 26.25 14.5833V13.125C26.25 12.3515 26.5573 11.6096 27.1043 11.0626C27.6513 10.5156 28.3931 10.2083 29.1667 10.2083C29.5534 10.2083 29.9244 10.0547 30.1979 9.7812C30.4714 9.50771 30.625 9.13677 30.625 8.75V5.83333C30.625 5.44656 30.4714 5.07562 30.1979 4.80213C29.9244 4.52864 29.5534 4.375 29.1667 4.375C26.846 4.375 24.6204 5.29687 22.9795 6.93781C21.3385 8.57876 20.4167 10.8044 20.4167 13.125V27.7083C20.4167 28.4819 20.724 29.2237 21.2709 29.7707C21.8179 30.3177 22.5598 30.625 23.3333 30.625H27.7083Z" fill="#059784"/>
</svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,13 +1,12 @@
import { baseAPI } from "@/lib/API"; import { baseAPI } from "@/lib/API";
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import { activeLangType } from "./headerSlice";
export const fetchAbout = createAsyncThunk( export const fetchAbout = createAsyncThunk(
"about/fetchAbout", "about/fetchAbout",
async ({ activeLang }: { activeLang: activeLangType }) => { async ({ locale }: { locale: string }) => {
const res = await fetch(`${baseAPI}settings/about_us`, { const res = await fetch(`${baseAPI}settings/about_us`, {
headers: { headers: {
"Accept-Language": activeLang.localization, "Accept-Language": locale,
}, },
}); });
@ -35,12 +34,9 @@ const aboutSlice = createSlice({
}, },
extraReducers: (builder) => { extraReducers: (builder) => {
builder.addCase(fetchAbout.pending, (state) => { builder.addCase(fetchAbout.pending, (state) => {});
// console.log('pending');
});
builder.addCase(fetchAbout.fulfilled, (state, action) => { builder.addCase(fetchAbout.fulfilled, (state, action) => {
// console.log('success', action.payload);
state.aboutData = action.payload; state.aboutData = action.payload;
}); });

View File

@ -1,21 +1,11 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { RootState } from '../store'; import { RootState } from '../store';
export type activeLangType = {
title: 'Ру' | 'En' | 'Tm' | string;
localization: 'ru' | 'en' | 'tm' | string;
};
interface HeaderState { interface HeaderState {
activeLang: activeLangType;
showInput: boolean; showInput: boolean;
} }
const initialState: HeaderState = { const initialState: HeaderState = {
activeLang: {
title: 'Русский',
localization: 'ru',
},
showInput: false, showInput: false,
}; };
@ -23,9 +13,6 @@ const headerSlice = createSlice({
name: 'header', name: 'header',
initialState, initialState,
reducers: { reducers: {
setActiveLang(state, action: PayloadAction<activeLangType>) {
state.activeLang = action.payload;
},
setShowInput(state, action: PayloadAction<boolean>) { setShowInput(state, action: PayloadAction<boolean>) {
state.showInput = action.payload; state.showInput = action.payload;
}, },
@ -34,6 +21,6 @@ const headerSlice = createSlice({
export const selectHeader = (state: RootState) => state.headerSlice; export const selectHeader = (state: RootState) => state.headerSlice;
export const { setActiveLang, setShowInput } = headerSlice.actions; export const { setShowInput } = headerSlice.actions;
export default headerSlice.reducer; export default headerSlice.reducer;

View File

@ -1,21 +1,18 @@
import { baseAPI } from "@/lib/API"; import { baseAPI } from "@/lib/API";
import { ServicesType } from "@/lib/types/Services.data"; import { ServicesType } from "@/lib/types/Services.data";
import { cookies } from "next/headers";
export const getServices = async () => {
const lang = cookies().get("lang")?.value || "en";
export const getServices = async (lang: string) => {
const res = await fetch(`${baseAPI}services`, { const res = await fetch(`${baseAPI}services`, {
headers: { headers: {
"Accept-Language": lang, // Передаём язык в заголовке "Accept-Language": lang,
}, },
next: { next: {
revalidate: 1000, revalidate: 1000,
tags: [`services-${lang}`], // Кешируем отдельно для каждого языка tags: [`services-${lang}`],
}, },
}); });
if (!res.ok) throw new Error("Ошибка при загрузке данных"); if (!res.ok) throw new Error("Failed to load services");
return (await res.json()) as ServicesType; return (await res.json()) as ServicesType;
}; };

View File

@ -1,9 +0,0 @@
"use client";
export const useLang = (en: string, ru: string, localization: string) => {
if (localization === "en") {
return en;
} else {
return ru;
}
};