Compare commits

..
33 Commits
Author SHA1 Message Date
Omar López 95be16c358 v3.2.9
release.yml / release (push) Canceled after 0s
2023-09-07 13:14:59 -07:00
Peer Richelsen 5621507f7e chore: fixed an i18n string (#11200) 2023-09-07 17:27:22 +00:00
Mehul bc6d58fd47 fix: bad setState call at datePicker component (#11175) 2023-09-07 17:11:59 +00:00
WesleyandCarinaWolli db29cc1251 feat: send new booking uid on reschedule webhook (#10654)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-09-07 16:27:46 +00:00
Patel Divyesh 69888c57b0 fix: Fixed SVG icons on light and dark mode (#11173) 2023-09-07 17:34:11 +02:00
5c0da23b97 feat: User Avatar and Org Logo (#10700)
* Pass organization name & logo

* Overflow hidden

* Show org icon on public page

* Add org logo to large user avatars

* Clean up

* Add org name and logo to context

* Get org logo from /avatar.png endpoint

* Do not query for logo

* Remove name and logo from session middleware

* Type fix

* Set user onboarding org logo

* feat: organization avatar component (#10788)

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>

* Type fixes

* Type fix

* Transition to org slug for organization avatar

* Address feedback

* Clean up

* Clean up

* Type fix

* fix: set avatar cache control (#11163)

* test: Integration tests for handleNewBooking (#11044)

Co-authored-by: Shivam Kalra <shivamkalra98@gmail.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>

* fix: booking_paid webhook and added new payment metadata (#11093)

* app store improvements, logos, dark mode, added screenshots, fixed author names (#11164)

* fix: mobile event types and avatars (#11184)

* New Crowdin translations by Github Action

* fix: updateProfile metadata overwrite (#11188)

Co-authored-by: alannnc <alannnc@gmail.com>

* New Crowdin translations by Github Action

---------

Co-authored-by: Sean Brydon <sean@cal.com>
Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
Co-authored-by: Omar López <zomars@me.com>
Co-authored-by: Hariom Balhara <hariombalhara@gmail.com>
Co-authored-by: Shivam Kalra <shivamkalra98@gmail.com>
Co-authored-by: alannnc <alannnc@gmail.com>
Co-authored-by: Peer Richelsen <peeroke@gmail.com>
Co-authored-by: Leo Giovanetti <hello@leog.me>
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
2023-09-07 17:26:40 +02:00
Hariom BalharaandCarina Wollendorfer 5324ec8051 fix: Routing Form - Show responses in the order of fields (#11143)
Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
2023-09-07 15:22:39 +00:00
Crowdin Bot b946f89ffb New Crowdin translations by Github Action 2023-09-07 12:33:00 +00:00
Crowdin Bot 3e3581fabc New Crowdin translations by Github Action 2023-09-07 12:29:44 +00:00
Crowdin Bot 05ac339233 New Crowdin translations by Github Action 2023-09-07 12:26:19 +00:00
Crowdin Bot ef4675ff44 New Crowdin translations by Github Action 2023-09-07 12:22:42 +00:00
sean-brydon 47dc85ee1b chore: fixing darkmode data table (#11195) 2023-09-07 14:18:52 +02:00
Crowdin Bot 50342e33ed New Crowdin translations by Github Action 2023-09-06 23:43:28 +00:00
Omar Lópezandalannnc eebcb636f1 fix: updateProfile metadata overwrite (#11188)
Co-authored-by: alannnc <alannnc@gmail.com>
2023-09-06 16:40:50 -07:00
Crowdin Bot ed2ced899a New Crowdin translations by Github Action 2023-09-06 21:43:37 +00:00
Leo Giovanetti b7ae8c9594 fix: mobile event types and avatars (#11184) 2023-09-06 23:41:03 +02:00
Peer Richelsen fce98ebb13 app store improvements, logos, dark mode, added screenshots, fixed author names (#11164) 2023-09-07 01:17:04 +05:30
alannnc b81b221bf5 fix: booking_paid webhook and added new payment metadata (#11093) 2023-09-06 12:40:27 -07:00
f9eb335d0b test: Integration tests for handleNewBooking (#11044)
Co-authored-by: Shivam Kalra <shivamkalra98@gmail.com>
Co-authored-by: Joe Au-Yeung <65426560+joeauyeung@users.noreply.github.com>
2023-09-06 12:23:53 -07:00
Omar López d7d7bcd651 fix: set avatar cache control (#11163) 2023-09-06 12:22:13 -07:00
Crowdin Bot 4c861b9e67 New Crowdin translations by Github Action 2023-09-06 18:32:09 +00:00
Carina WollendorferandCarinaWolli 2fa704c39b fix: add make invite link to setup page (#11177)
Co-authored-by: CarinaWolli <wollencarina@gmail.com>
2023-09-06 14:29:13 -04:00
Crowdin Bot 9ccdf21d75 New Crowdin translations by Github Action 2023-09-06 15:25:19 +00:00
GitStart-Cal.comandgitstart-calcom 9d6148da42 chore: add Wizard in storybook (CALCOM-10760) (#11166)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-09-06 17:22:02 +02:00
MehulandUdit Takkar bf437b7d6b fix: event duration can be 0 (#11145)
Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2023-09-06 17:21:24 +02:00
Udit Takkar 3701fcd68b fix: teams page error (#11171) 2023-09-06 11:38:21 +02:00
GitStart-Cal.comandgitstart-calcom 2f90dc7cb6 fix: DataTable storybook file is not rendering (#10984)
Co-authored-by: gitstart-calcom <gitstart@users.noreply.github.com>
2023-09-06 09:18:06 +01:00
alannnc 829f90b82f chore: remove unused queries on user event types (#11159)
* remove unused queries on user event types

* Fix types
2023-09-06 05:00:06 -03:00
Crowdin Bot 3539693729 New Crowdin translations by Github Action 2023-09-06 05:11:51 +00:00
Joe Au-Yeung 868ba4396d fix: Installing Zoho CRM (#11161)
* Fix installing Zoho CRM

* Clean up
2023-09-06 05:08:59 +00:00
zomars d06e36a5cd Update yarn.lock 2023-09-05 14:46:14 -07:00
Crowdin Bot f61c9d9bbf New Crowdin translations by Github Action 2023-09-05 21:39:15 +00:00
Leo Giovanetti a2d521e001 fix: i18n issues reported by crowdin (#11160) 2023-09-05 18:36:17 -03:00
97 changed files with 2380 additions and 1793 deletions

No files matched your search

@@ -13,7 +13,6 @@ import type { EventLocationType } from "@calcom/app-store/locations";
import { getEventLocationType, MeetLocationType, LocationType } from "@calcom/app-store/locations"; import { getEventLocationType, MeetLocationType, LocationType } from "@calcom/app-store/locations";
import useLockedFieldsManager from "@calcom/features/ee/managed-event-types/hooks/useLockedFieldsManager"; import useLockedFieldsManager from "@calcom/features/ee/managed-event-types/hooks/useLockedFieldsManager";
import { useOrgBranding } from "@calcom/features/ee/organizations/context/provider"; import { useOrgBranding } from "@calcom/features/ee/organizations/context/provider";
import cx from "@calcom/lib/classNames";
import { CAL_URL } from "@calcom/lib/constants"; import { CAL_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import { md } from "@calcom/lib/markdownIt"; import { md } from "@calcom/lib/markdownIt";
@@ -302,13 +301,7 @@ export const EventSetupTab = (
<div className="flex items-center"> <div className="flex items-center">
<img <img
src={eventLocationType.iconUrl} src={eventLocationType.iconUrl}
className={cx( className="h-4 w-4 dark:invert-[.65]"
"h-4 w-4",
// invert all the icons except app icons
eventLocationType.iconUrl &&
eventLocationType.iconUrl.includes("-dark") &&
"dark:invert"
)}
alt={`${eventLocationType.label} logo`} alt={`${eventLocationType.label} logo`}
/> />
<span className="ms-1 line-clamp-1 text-sm">{`${eventLabel} ${ <span className="ms-1 line-clamp-1 text-sm">{`${eventLabel} ${
@@ -3,12 +3,13 @@ import type { FormEvent } from "react";
import { useRef, useState } from "react"; import { useRef, useState } from "react";
import { useForm } from "react-hook-form"; import { useForm } from "react-hook-form";
import OrganizationAvatar from "@calcom/features/ee/organizations/components/OrganizationAvatar";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import { md } from "@calcom/lib/markdownIt"; import { md } from "@calcom/lib/markdownIt";
import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry"; import { telemetryEventTypes, useTelemetry } from "@calcom/lib/telemetry";
import turndown from "@calcom/lib/turndownService"; import turndown from "@calcom/lib/turndownService";
import { trpc } from "@calcom/trpc/react"; import { trpc } from "@calcom/trpc/react";
import { Avatar, Button, Editor, ImageUploader, Label, showToast } from "@calcom/ui"; import { Button, Editor, ImageUploader, Label, showToast } from "@calcom/ui";
import { ArrowRight } from "@calcom/ui/components/icon"; import { ArrowRight } from "@calcom/ui/components/icon";
type FormData = { type FormData = {
@@ -98,7 +99,14 @@ const UserProfile = () => {
return ( return (
<form onSubmit={onSubmit}> <form onSubmit={onSubmit}>
<div className="flex flex-row items-center justify-start rtl:justify-end"> <div className="flex flex-row items-center justify-start rtl:justify-end">
{user && <Avatar alt={user.username || "user avatar"} size="lg" imageSrc={imageSrc} />} {user && (
<OrganizationAvatar
alt={user.username || "user avatar"}
size="lg"
imageSrc={imageSrc}
organizationSlug={user.organization?.slug}
/>
)}
<input <input
ref={avatarRef} ref={avatarRef}
type="hidden" type="hidden"
@@ -22,14 +22,7 @@ export type GroupOptionType = GroupBase<LocationOption>;
const OptionWithIcon = ({ icon, label }: { icon?: string; label: string }) => { const OptionWithIcon = ({ icon, label }: { icon?: string; label: string }) => {
return ( return (
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
{icon && ( {icon && <img src={icon} alt="cover" className="h-3.5 w-3.5 dark:invert-[.65]" />}
<img
src={icon}
alt="cover"
// invert all the icons except app icons
className={classNames(icon.includes("-dark") && "dark:invert", "h-3.5 w-3.5")}
/>
)}
<span className={classNames("text-sm font-medium")}>{label}</span> <span className={classNames("text-sm font-medium")}>{label}</span>
</div> </div>
); );
+4
View File
@@ -254,6 +254,10 @@ const nextConfig = {
source: "/org/:slug", source: "/org/:slug",
destination: "/team/:slug", destination: "/team/:slug",
}, },
{
source: "/org/:orgSlug/avatar.png",
destination: "/api/user/avatar?orgSlug=:orgSlug",
},
{ {
source: "/team/:teamname/avatar.png", source: "/team/:teamname/avatar.png",
destination: "/api/user/avatar?teamname=:teamname", destination: "/api/user/avatar?teamname=:teamname",
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "@calcom/web", "name": "@calcom/web",
"version": "3.2.8", "version": "3.2.9",
"private": true, "private": true,
"scripts": { "scripts": {
"analyze": "ANALYZE=true next build", "analyze": "ANALYZE=true next build",
+10 -2
View File
@@ -11,6 +11,7 @@ import {
useEmbedStyles, useEmbedStyles,
useIsEmbed, useIsEmbed,
} from "@calcom/embed-core/embed-iframe"; } from "@calcom/embed-core/embed-iframe";
import OrganizationAvatar from "@calcom/features/ee/organizations/components/OrganizationAvatar";
import { getSlugOrRequestedSlug } from "@calcom/features/ee/organizations/lib/orgDomains"; import { getSlugOrRequestedSlug } from "@calcom/features/ee/organizations/lib/orgDomains";
import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains"; import { orgDomainConfig } from "@calcom/features/ee/organizations/lib/orgDomains";
import { EventTypeDescriptionLazy as EventTypeDescription } from "@calcom/features/eventtypes/components"; import { EventTypeDescriptionLazy as EventTypeDescription } from "@calcom/features/eventtypes/components";
@@ -25,7 +26,7 @@ import prisma from "@calcom/prisma";
import type { EventType, User } from "@calcom/prisma/client"; import type { EventType, User } from "@calcom/prisma/client";
import { baseEventTypeSelect } from "@calcom/prisma/selects"; import { baseEventTypeSelect } from "@calcom/prisma/selects";
import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils"; import { EventTypeMetaDataSchema } from "@calcom/prisma/zod-utils";
import { Avatar, HeadSeo, UnpublishedEntity } from "@calcom/ui"; import { HeadSeo, UnpublishedEntity } from "@calcom/ui";
import { Verified, ArrowRight } from "@calcom/ui/components/icon"; import { Verified, ArrowRight } from "@calcom/ui/components/icon";
import type { EmbedProps } from "@lib/withEmbedSsr"; import type { EmbedProps } from "@lib/withEmbedSsr";
@@ -96,7 +97,12 @@ export function UserPage(props: InferGetServerSidePropsType<typeof getServerSide
"max-w-3xl px-4 py-24" "max-w-3xl px-4 py-24"
)}> )}>
<div className="mb-8 text-center"> <div className="mb-8 text-center">
<Avatar imageSrc={profile.image} size="xl" alt={profile.name} /> <OrganizationAvatar
imageSrc={profile.image}
size="xl"
alt={profile.name}
organizationSlug={profile.organizationSlug}
/>
<h1 className="font-cal text-emphasis mb-1 text-3xl" data-testid="name-title"> <h1 className="font-cal text-emphasis mb-1 text-3xl" data-testid="name-title">
{profile.name} {profile.name}
{user.verified && ( {user.verified && (
@@ -218,6 +224,7 @@ export type UserPageProps = {
theme: string | null; theme: string | null;
brandColor: string; brandColor: string;
darkBrandColor: string; darkBrandColor: string;
organizationSlug: string | null;
allowSEOIndexing: boolean; allowSEOIndexing: boolean;
}; };
users: Pick<User, "away" | "name" | "username" | "bio" | "verified">[]; users: Pick<User, "away" | "name" | "username" | "bio" | "verified">[];
@@ -321,6 +328,7 @@ export const getServerSideProps: GetServerSideProps<UserPageProps> = async (cont
theme: user.theme, theme: user.theme,
brandColor: user.brandColor, brandColor: user.brandColor,
darkBrandColor: user.darkBrandColor, darkBrandColor: user.darkBrandColor,
organizationSlug: user.organization?.slug ?? null,
allowSEOIndexing: user.allowSEOIndexing ?? true, allowSEOIndexing: user.allowSEOIndexing ?? true,
}; };
+1 -1
View File
@@ -187,7 +187,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
} }
res.setHeader("Content-Type", response.headers.get("content-type") as string); res.setHeader("Content-Type", response.headers.get("content-type") as string);
res.setHeader("Cache-Control", "s-maxage=86400"); res.setHeader("Cache-Control", "s-maxage=86400, stale-while-revalidate=60");
res.send(buffer); res.send(buffer);
} catch (error) { } catch (error) {
res.statusCode = 404; res.statusCode = 404;
+21 -2
View File
@@ -10,6 +10,7 @@ const querySchema = z
.object({ .object({
username: z.string(), username: z.string(),
teamname: z.string(), teamname: z.string(),
orgSlug: z.string(),
/** /**
* Allow fetching avatar of a particular organization * Allow fetching avatar of a particular organization
* Avatars being public, we need not worry about others accessing it. * Avatars being public, we need not worry about others accessing it.
@@ -19,7 +20,7 @@ const querySchema = z
.partial(); .partial();
async function getIdentityData(req: NextApiRequest) { async function getIdentityData(req: NextApiRequest) {
const { username, teamname, orgId } = querySchema.parse(req.query); const { username, teamname, orgId, orgSlug } = querySchema.parse(req.query);
const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(req.headers.host ?? ""); const { currentOrgDomain, isValidOrgDomain } = orgDomainConfig(req.headers.host ?? "");
const org = isValidOrgDomain ? currentOrgDomain : null; const org = isValidOrgDomain ? currentOrgDomain : null;
@@ -59,7 +60,23 @@ async function getIdentityData(req: NextApiRequest) {
org, org,
name: teamname, name: teamname,
email: null, email: null,
avatar: team?.logo || getPlaceholderAvatar(null, teamname), avatar: getPlaceholderAvatar(team?.logo, teamname),
};
}
if (orgSlug) {
const org = await prisma.team.findFirst({
where: getSlugOrRequestedSlug(orgSlug),
select: {
slug: true,
logo: true,
name: true,
},
});
return {
org: org?.slug,
name: org?.name,
email: null,
avatar: getPlaceholderAvatar(org?.logo, org?.name),
}; };
} }
} }
@@ -67,6 +84,8 @@ async function getIdentityData(req: NextApiRequest) {
export default async function handler(req: NextApiRequest, res: NextApiResponse) { export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const identity = await getIdentityData(req); const identity = await getIdentityData(req);
const img = identity?.avatar; const img = identity?.avatar;
// We cache for one day
res.setHeader("Cache-Control", "s-maxage=86400, stale-while-revalidate=60");
// If image isn't set or links to this route itself, use default avatar // If image isn't set or links to this route itself, use default avatar
if (!img) { if (!img) {
if (identity?.org) { if (identity?.org) {
+10 -2
View File
@@ -376,9 +376,12 @@ const EventTypePage = (props: EventTypeSetupProps) => {
bookerLayouts, bookerLayouts,
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
multipleDurationEnabled, multipleDurationEnabled,
length,
...input ...input
} = values; } = values;
if (!Number(length)) throw new Error(t("event_setup_length_error"));
if (bookingLimits) { if (bookingLimits) {
const isValid = validateIntervalLimitOrder(bookingLimits); const isValid = validateIntervalLimitOrder(bookingLimits);
if (!isValid) throw new Error(t("event_setup_booking_limits_error")); if (!isValid) throw new Error(t("event_setup_booking_limits_error"));
@@ -396,7 +399,7 @@ const EventTypePage = (props: EventTypeSetupProps) => {
if (metadata?.multipleDuration.length < 1) { if (metadata?.multipleDuration.length < 1) {
throw new Error(t("event_setup_multiple_duration_error")); throw new Error(t("event_setup_multiple_duration_error"));
} else { } else {
if (!input.length && !metadata?.multipleDuration?.includes(input.length)) { if (!length && !metadata?.multipleDuration?.includes(length)) {
throw new Error(t("event_setup_multiple_duration_default_error")); throw new Error(t("event_setup_multiple_duration_default_error"));
} }
} }
@@ -410,6 +413,7 @@ const EventTypePage = (props: EventTypeSetupProps) => {
const { availability, ...rest } = input; const { availability, ...rest } = input;
updateMutation.mutate({ updateMutation.mutate({
...rest, ...rest,
length,
locations, locations,
recurringEvent, recurringEvent,
periodStartDate: periodDates.startDate, periodStartDate: periodDates.startDate,
@@ -467,9 +471,12 @@ const EventTypePage = (props: EventTypeSetupProps) => {
seatsPerTimeSlotEnabled, seatsPerTimeSlotEnabled,
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
multipleDurationEnabled, multipleDurationEnabled,
length,
...input ...input
} = values; } = values;
if (!Number(length)) throw new Error(t("event_setup_length_error"));
if (bookingLimits) { if (bookingLimits) {
const isValid = validateIntervalLimitOrder(bookingLimits); const isValid = validateIntervalLimitOrder(bookingLimits);
if (!isValid) throw new Error(t("event_setup_booking_limits_error")); if (!isValid) throw new Error(t("event_setup_booking_limits_error"));
@@ -487,7 +494,7 @@ const EventTypePage = (props: EventTypeSetupProps) => {
if (metadata?.multipleDuration.length < 1) { if (metadata?.multipleDuration.length < 1) {
throw new Error(t("event_setup_multiple_duration_error")); throw new Error(t("event_setup_multiple_duration_error"));
} else { } else {
if (!input.length && !metadata?.multipleDuration?.includes(input.length)) { if (!length && !metadata?.multipleDuration?.includes(length)) {
throw new Error(t("event_setup_multiple_duration_default_error")); throw new Error(t("event_setup_multiple_duration_default_error"));
} }
} }
@@ -496,6 +503,7 @@ const EventTypePage = (props: EventTypeSetupProps) => {
const { availability, ...rest } = input; const { availability, ...rest } = input;
updateMutation.mutate({ updateMutation.mutate({
...rest, ...rest,
length,
locations, locations,
recurringEvent, recurringEvent,
periodStartDate: periodDates.startDate, periodStartDate: periodDates.startDate,
+32 -9
View File
@@ -108,8 +108,10 @@ const MobileTeamsTab: FC<MobileTeamsTabProps> = (props) => {
const orgBranding = useOrgBranding(); const orgBranding = useOrgBranding();
const tabs = eventTypeGroups.map((item) => ({ const tabs = eventTypeGroups.map((item) => ({
name: item.profile.name ?? "", name: item.profile.name ?? "",
href: item.teamId ? `/event-types?teamId=${item.teamId}` : "/event-types", href: item.teamId ? `/event-types?teamId=${item.teamId}` : "/event-types?noTeam",
avatar: item.profile.image ?? `${orgBranding?.fullDomain ?? WEBAPP_URL}/${item.profile.slug}/avatar.png`, avatar: orgBranding
? `${orgBranding.fullDomain}${item.teamId ? "/team" : ""}/${item.profile.slug}/avatar.png`
: item.profile.image ?? `${WEBAPP_URL + (item.teamId && "/team")}/${item.profile.slug}/avatar.png`,
})); }));
const { data } = useTypedQuery(querySchema); const { data } = useTypedQuery(querySchema);
const events = eventTypeGroups.filter((item) => item.teamId === data.teamId); const events = eventTypeGroups.filter((item) => item.teamId === data.teamId);
@@ -117,13 +119,15 @@ const MobileTeamsTab: FC<MobileTeamsTabProps> = (props) => {
return ( return (
<div> <div>
<HorizontalTabs tabs={tabs} /> <HorizontalTabs tabs={tabs} />
{events.length && ( {events.length > 0 ? (
<EventTypeList <EventTypeList
types={events[0].eventTypes} types={events[0].eventTypes}
group={events[0]} group={events[0]}
groupIndex={0} groupIndex={0}
readOnly={events[0].metadata.readOnly} readOnly={events[0].metadata.readOnly}
/> />
) : (
<CreateFirstEventTypeView />
)} )}
</div> </div>
); );
@@ -358,6 +362,10 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
} }
}, []); }, []);
if (!types.length) {
return group.teamId ? <EmptyEventTypeList group={group} /> : <CreateFirstEventTypeView />;
}
const firstItem = types[0]; const firstItem = types[0];
const lastItem = types[types.length - 1]; const lastItem = types[types.length - 1];
const isManagedEventPrefix = () => { const isManagedEventPrefix = () => {
@@ -391,7 +399,9 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
className="relative right-3 top-1" className="relative right-3 top-1"
size="sm" size="sm"
truncateAfter={4} truncateAfter={4}
items={type.users.map( items={
type?.users
? type.users.map(
(organizer: { name: string | null; username: string | null }) => ({ (organizer: { name: string | null; username: string | null }) => ({
alt: organizer.name || "", alt: organizer.name || "",
image: `${orgBranding?.fullDomain ?? WEBAPP_URL}/${ image: `${orgBranding?.fullDomain ?? WEBAPP_URL}/${
@@ -399,15 +409,17 @@ export const EventTypeList = ({ group, groupIndex, readOnly, types }: EventTypeL
}/avatar.png`, }/avatar.png`,
title: organizer.name || "", title: organizer.name || "",
}) })
)} )
: []
}
/> />
)} )}
{isManagedEventType && type.children && ( {isManagedEventType && type?.children && type.children?.length > 0 && (
<AvatarGroup <AvatarGroup
className="relative right-3 top-1" className="relative right-3 top-1"
size="sm" size="sm"
truncateAfter={4} truncateAfter={4}
items={type.children items={type?.children
.flatMap((ch) => ch.users) .flatMap((ch) => ch.users)
.map((user: Pick<User, "name" | "username">) => ({ .map((user: Pick<User, "name" | "username">) => ({
alt: user.name || "", alt: user.name || "",
@@ -708,7 +720,10 @@ const EventTypeListHeading = ({
<Avatar <Avatar
alt={profile?.name || ""} alt={profile?.name || ""}
href={teamId ? `/settings/teams/${teamId}/profile` : "/settings/my-account/profile"} href={teamId ? `/settings/teams/${teamId}/profile` : "/settings/my-account/profile"}
imageSrc={`${orgBranding?.fullDomain ?? WEBAPP_URL}/${profile.slug}/avatar.png` || undefined} imageSrc={
`${orgBranding?.fullDomain ?? WEBAPP_URL}${teamId ? "/team" : ""}/${profile.slug}/avatar.png` ||
undefined
}
size="md" size="md"
className="mt-1 inline-flex justify-center" className="mt-1 inline-flex justify-center"
/> />
@@ -755,6 +770,12 @@ const CreateFirstEventTypeView = () => {
Icon={LinkIcon} Icon={LinkIcon}
headline={t("new_event_type_heading")} headline={t("new_event_type_heading")}
description={t("new_event_type_description")} description={t("new_event_type_description")}
className="mb-16"
buttonRaw={
<Button href="?dialog=new" variant="button">
{t("create")}
</Button>
}
/> />
); );
}; };
@@ -889,8 +910,10 @@ const Main = ({
groupIndex={index} groupIndex={index}
readOnly={group.metadata.readOnly} readOnly={group.metadata.readOnly}
/> />
) : ( ) : group.teamId ? (
<EmptyEventTypeList group={group} /> <EmptyEventTypeList group={group} />
) : (
<CreateFirstEventTypeView />
)} )}
</div> </div>
)) ))
+11 -2
View File
@@ -6,6 +6,7 @@ import { Controller, useForm } from "react-hook-form";
import { z } from "zod"; import { z } from "zod";
import { ErrorCode } from "@calcom/features/auth/lib/ErrorCode"; import { ErrorCode } from "@calcom/features/auth/lib/ErrorCode";
import OrganizationAvatar from "@calcom/features/ee/organizations/components/OrganizationAvatar";
import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout"; import { getLayout } from "@calcom/features/settings/layouts/SettingsLayout";
import { APP_NAME, FULL_NAME_LENGTH_MAX_LIMIT } from "@calcom/lib/constants"; import { APP_NAME, FULL_NAME_LENGTH_MAX_LIMIT } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
@@ -14,10 +15,10 @@ import turndown from "@calcom/lib/turndownService";
import { IdentityProvider } from "@calcom/prisma/enums"; import { IdentityProvider } from "@calcom/prisma/enums";
import type { TRPCClientErrorLike } from "@calcom/trpc/client"; import type { TRPCClientErrorLike } from "@calcom/trpc/client";
import { trpc } from "@calcom/trpc/react"; import { trpc } from "@calcom/trpc/react";
import type { RouterOutputs } from "@calcom/trpc/react";
import type { AppRouter } from "@calcom/trpc/server/routers/_app"; import type { AppRouter } from "@calcom/trpc/server/routers/_app";
import { import {
Alert, Alert,
Avatar,
Button, Button,
Dialog, Dialog,
DialogClose, DialogClose,
@@ -223,6 +224,7 @@ const ProfileView = () => {
key={JSON.stringify(defaultValues)} key={JSON.stringify(defaultValues)}
defaultValues={defaultValues} defaultValues={defaultValues}
isLoading={updateProfileMutation.isLoading} isLoading={updateProfileMutation.isLoading}
userOrganization={user.organization}
onSubmit={(values) => { onSubmit={(values) => {
if (values.email !== user.email && isCALIdentityProvider) { if (values.email !== user.email && isCALIdentityProvider) {
setTempFormValues(values); setTempFormValues(values);
@@ -364,11 +366,13 @@ const ProfileForm = ({
onSubmit, onSubmit,
extraField, extraField,
isLoading = false, isLoading = false,
userOrganization,
}: { }: {
defaultValues: FormValues; defaultValues: FormValues;
onSubmit: (values: FormValues) => void; onSubmit: (values: FormValues) => void;
extraField?: React.ReactNode; extraField?: React.ReactNode;
isLoading: boolean; isLoading: boolean;
userOrganization: RouterOutputs["viewer"]["me"]["organization"];
}) => { }) => {
const { t } = useLocale(); const { t } = useLocale();
const [firstRender, setFirstRender] = useState(true); const [firstRender, setFirstRender] = useState(true);
@@ -406,7 +410,12 @@ const ProfileForm = ({
name="avatar" name="avatar"
render={({ field: { value } }) => ( render={({ field: { value } }) => (
<> <>
<Avatar alt="" imageSrc={value} size="lg" /> <OrganizationAvatar
alt={formMethods.getValues("username")}
imageSrc={value}
size="lg"
organizationSlug={userOrganization.slug}
/>
<div className="ms-4"> <div className="ms-4">
<ImageUploader <ImageUploader
target="avatar" target="avatar"
+1 -1
View File
@@ -142,7 +142,7 @@ export default function Signup({ prepopulateFormValues, token, orgSlug }: Signup
<TextField <TextField
addOnLeading={ addOnLeading={
orgSlug orgSlug
? getOrgFullDomain(orgSlug, { protocol: true }) ? `${getOrgFullDomain(orgSlug, { protocol: true })}/`
: `${process.env.NEXT_PUBLIC_WEBSITE_URL}/` : `${process.env.NEXT_PUBLIC_WEBSITE_URL}/`
} }
{...register("username")} {...register("username")}
+1 -40
View File
@@ -1,60 +1,21 @@
import { expect } from "@playwright/test"; import { expect } from "@playwright/test";
import type { Prisma } from "@prisma/client";
import { uuid } from "short-uuid"; import { uuid } from "short-uuid";
import { v4 as uuidv4 } from "uuid"; import { v4 as uuidv4 } from "uuid";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import { BookingStatus } from "@calcom/prisma/enums"; import { BookingStatus } from "@calcom/prisma/enums";
import type { Fixtures } from "./lib/fixtures";
import { test } from "./lib/fixtures"; import { test } from "./lib/fixtures";
import { import {
bookTimeSlot, bookTimeSlot,
createNewSeatedEventType, createNewSeatedEventType,
selectFirstAvailableTimeSlotNextMonth, selectFirstAvailableTimeSlotNextMonth,
createUserWithSeatedEventAndAttendees,
} from "./lib/testUtils"; } from "./lib/testUtils";
test.describe.configure({ mode: "parallel" }); test.describe.configure({ mode: "parallel" });
test.afterEach(({ users }) => users.deleteAll()); test.afterEach(({ users }) => users.deleteAll());
async function createUserWithSeatedEvent(users: Fixtures["users"]) {
const slug = "seats";
const user = await users.create({
eventTypes: [
{
title: "Seated event",
slug,
seatsPerTimeSlot: 10,
requiresConfirmation: true,
length: 30,
disableGuests: true, // should always be true for seated events
},
],
});
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const eventType = user.eventTypes.find((e) => e.slug === slug)!;
return { user, eventType };
}
async function createUserWithSeatedEventAndAttendees(
fixtures: Pick<Fixtures, "users" | "bookings">,
attendees: Prisma.AttendeeCreateManyBookingInput[]
) {
const { user, eventType } = await createUserWithSeatedEvent(fixtures.users);
const booking = await fixtures.bookings.create(user.id, user.username, eventType.id, {
status: BookingStatus.ACCEPTED,
// startTime with 1 day from now and endTime half hour after
startTime: new Date(Date.now() + 24 * 60 * 60 * 1000),
endTime: new Date(Date.now() + 24 * 60 * 60 * 1000 + 30 * 60 * 1000),
attendees: {
createMany: {
data: attendees,
},
},
});
return { user, eventType, booking };
}
test.describe("Booking with Seats", () => { test.describe("Booking with Seats", () => {
test("User can create a seated event (2 seats as example)", async ({ users, page }) => { test("User can create a seated event (2 seats as example)", async ({ users, page }) => {
const user = await users.create({ name: "Seated event" }); const user = await users.create({ name: "Seated event" });
+46
View File
@@ -6,6 +6,10 @@ import { createServer } from "http";
import { noop } from "lodash"; import { noop } from "lodash";
import type { API, Messages } from "mailhog"; import type { API, Messages } from "mailhog";
import type { Prisma } from "@calcom/prisma/client";
import { BookingStatus } from "@calcom/prisma/enums";
import type { Fixtures } from "./fixtures";
import { test } from "./fixtures"; import { test } from "./fixtures";
export function todo(title: string) { export function todo(title: string) {
@@ -192,6 +196,7 @@ export async function installAppleCalendar(page: Page) {
await page.waitForURL("/apps/apple-calendar"); await page.waitForURL("/apps/apple-calendar");
await page.click('[data-testid="install-app-button"]'); await page.click('[data-testid="install-app-button"]');
} }
export async function getEmailsReceivedByUser({ export async function getEmailsReceivedByUser({
emails, emails,
userEmail, userEmail,
@@ -228,3 +233,44 @@ export async function expectEmailsToHaveSubject({
expect(organizerFirstEmail.subject).toBe(emailSubject); expect(organizerFirstEmail.subject).toBe(emailSubject);
expect(bookerFirstEmail.subject).toBe(emailSubject); expect(bookerFirstEmail.subject).toBe(emailSubject);
} }
// this method is not used anywhere else
// but I'm keeping it here in case we need in the future
async function createUserWithSeatedEvent(users: Fixtures["users"]) {
const slug = "seats";
const user = await users.create({
eventTypes: [
{
title: "Seated event",
slug,
seatsPerTimeSlot: 10,
requiresConfirmation: true,
length: 30,
disableGuests: true, // should always be true for seated events
},
],
});
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const eventType = user.eventTypes.find((e) => e.slug === slug)!;
return { user, eventType };
}
export async function createUserWithSeatedEventAndAttendees(
fixtures: Pick<Fixtures, "users" | "bookings">,
attendees: Prisma.AttendeeCreateManyBookingInput[]
) {
const { user, eventType } = await createUserWithSeatedEvent(fixtures.users);
const booking = await fixtures.bookings.create(user.id, user.username, eventType.id, {
status: BookingStatus.ACCEPTED,
// startTime with 1 day from now and endTime half hour after
startTime: new Date(Date.now() + 24 * 60 * 60 * 1000),
endTime: new Date(Date.now() + 24 * 60 * 60 * 1000 + 30 * 60 * 1000),
attendees: {
createMany: {
data: attendees,
},
},
});
return { user, eventType, booking };
}
+169
View File
@@ -1,5 +1,9 @@
import type { Page } from "@playwright/test"; import type { Page } from "@playwright/test";
import { expect } from "@playwright/test"; import { expect } from "@playwright/test";
import { v4 as uuidv4 } from "uuid";
import prisma from "@calcom/prisma";
import { BookingStatus } from "@calcom/prisma/client";
import { test } from "./lib/fixtures"; import { test } from "./lib/fixtures";
import { import {
@@ -8,6 +12,7 @@ import {
selectFirstAvailableTimeSlotNextMonth, selectFirstAvailableTimeSlotNextMonth,
waitFor, waitFor,
gotoRoutingLink, gotoRoutingLink,
createUserWithSeatedEventAndAttendees,
} from "./lib/testUtils"; } from "./lib/testUtils";
// remove dynamic properties that differs depending on where you run the tests // remove dynamic properties that differs depending on where you run the tests
@@ -15,6 +20,29 @@ const dynamic = "[redacted/dynamic]";
test.afterEach(({ users }) => users.deleteAll()); test.afterEach(({ users }) => users.deleteAll());
async function createWebhookReceiver(page: Page) {
const webhookReceiver = createHttpServer();
await page.goto(`/settings/developer/webhooks`);
// --- add webhook
await page.click('[data-testid="new_webhook"]');
await page.fill('[name="subscriberUrl"]', webhookReceiver.url);
await page.fill('[name="secret"]', "secret");
await Promise.all([
page.click("[type=submit]"),
page.waitForURL((url) => url.pathname.endsWith("/settings/developer/webhooks")),
]);
// page contains the url
expect(page.locator(`text='${webhookReceiver.url}'`)).toBeDefined();
return webhookReceiver;
}
test.describe("BOOKING_CREATED", async () => { test.describe("BOOKING_CREATED", async () => {
test("add webhook & test that creating an event triggers a webhook call", async ({ test("add webhook & test that creating an event triggers a webhook call", async ({
page, page,
@@ -388,6 +416,147 @@ test.describe("BOOKING_REQUESTED", async () => {
}); });
}); });
test.describe("BOOKING_RESCHEDULED", async () => {
test("can reschedule a booking and get a booking rescheduled event", async ({ page, users, bookings }) => {
const user = await users.create();
const [eventType] = user.eventTypes;
await user.apiLogin();
const webhookReceiver = await createWebhookReceiver(page);
const booking = await bookings.create(user.id, user.username, eventType.id, {
status: BookingStatus.ACCEPTED,
});
await page.goto(`/${user.username}/${eventType.slug}?rescheduleUid=${booking.uid}`);
await selectFirstAvailableTimeSlotNextMonth(page);
await page.locator('[data-testid="confirm-reschedule-button"]').click();
await expect(page).toHaveURL(/.*booking/);
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const newBooking = await prisma.booking.findFirst({ where: { fromReschedule: booking?.uid } })!;
expect(newBooking).not.toBeNull();
// --- check that webhook was called
await waitFor(() => {
expect(webhookReceiver.requestList.length).toBe(1);
});
const [request] = webhookReceiver.requestList;
expect(request.body).toMatchObject({
triggerEvent: "BOOKING_RESCHEDULED",
payload: {
uid: newBooking?.uid,
},
});
});
test("when rescheduling to a booking that already exists, should send a booking rescheduled event with the existant booking uid", async ({
page,
users,
bookings,
}) => {
const { user, eventType, booking } = await createUserWithSeatedEventAndAttendees({ users, bookings }, [
{ name: "John First", email: "first+seats@cal.com", timeZone: "Europe/Berlin" },
{ name: "Jane Second", email: "second+seats@cal.com", timeZone: "Europe/Berlin" },
]);
await prisma.eventType.update({
where: { id: eventType.id },
data: { requiresConfirmation: false },
});
await user.apiLogin();
const webhookReceiver = await createWebhookReceiver(page);
const bookingAttendees = await prisma.attendee.findMany({
where: { bookingId: booking.id },
select: {
id: true,
email: true,
},
});
const bookingSeats = bookingAttendees.map((attendee) => ({
bookingId: booking.id,
attendeeId: attendee.id,
referenceUid: uuidv4(),
}));
await prisma.bookingSeat.createMany({
data: bookingSeats,
});
const references = await prisma.bookingSeat.findMany({
where: { bookingId: booking.id },
include: { attendee: true },
});
await page.goto(`/reschedule/${references[0].referenceUid}`);
await selectFirstAvailableTimeSlotNextMonth(page);
await page.locator('[data-testid="confirm-reschedule-button"]').click();
await expect(page).toHaveURL(/.*booking/);
const newBooking = await prisma.booking.findFirst({
where: {
attendees: {
some: {
email: bookingAttendees[0].email,
},
},
},
});
// --- ensuring that new booking was created
expect(newBooking).not.toBeNull();
// --- check that webhook was called
await waitFor(() => {
expect(webhookReceiver.requestList.length).toBe(1);
});
const [firstRequest] = webhookReceiver.requestList;
expect(firstRequest?.body).toMatchObject({
triggerEvent: "BOOKING_RESCHEDULED",
payload: {
uid: newBooking?.uid,
},
});
await page.goto(`/reschedule/${references[1].referenceUid}`);
await selectFirstAvailableTimeSlotNextMonth(page);
await page.locator('[data-testid="confirm-reschedule-button"]').click();
await expect(page).toHaveURL(/.*booking/);
await waitFor(() => {
expect(webhookReceiver.requestList.length).toBe(2);
});
const [_, secondRequest] = webhookReceiver.requestList;
expect(secondRequest?.body).toMatchObject({
triggerEvent: "BOOKING_RESCHEDULED",
payload: {
// in the current implementation, it is the same as the first booking
uid: newBooking?.uid,
},
});
});
});
test.describe("FORM_SUBMITTED", async () => { test.describe("FORM_SUBMITTED", async () => {
test("on submitting user form, triggers user webhook", async ({ page, users, routingForms }) => { test("on submitting user form, triggers user webhook", async ({ page, users, routingForms }) => {
const webhookReceiver = createHttpServer(); const webhookReceiver = createHttpServer();
+8 -10
View File
@@ -13,7 +13,7 @@
"reset_password_subject": "{{appName}}: إرشادات إعادة تعيين كلمة المرور", "reset_password_subject": "{{appName}}: إرشادات إعادة تعيين كلمة المرور",
"verify_email_subject": "{{appName}}: تأكيد حسابك", "verify_email_subject": "{{appName}}: تأكيد حسابك",
"check_your_email": "تحقق من بريدك الإلكتروني", "check_your_email": "تحقق من بريدك الإلكتروني",
"verify_email_page_body": "أرسلنا رسالة إلكترونية إلى {{email}}. من المهم تأكيد عنوان بريدك الإلكتروني لضمان أفضل تسليم للبريد الإلكتروني والتقويم من {{appName}}.", "verify_email_page_body": "أرسلنا رسالة إلكترونية إلى {{email}}. من المهم تأكيد عنوان بريدك الإلكتروني لضمان تسليم البريد الإلكتروني والتقويم من {{appName}}.",
"verify_email_banner_body": "قم بتأكيد عنوان بريدك الإلكتروني لضمان أفضل تسليم للبريد الإلكتروني والتقويم", "verify_email_banner_body": "قم بتأكيد عنوان بريدك الإلكتروني لضمان أفضل تسليم للبريد الإلكتروني والتقويم",
"verify_email_email_header": "تأكيد عنوان بريدك الإلكتروني", "verify_email_email_header": "تأكيد عنوان بريدك الإلكتروني",
"verify_email_email_button": "تأكيد البريد الإلكتروني", "verify_email_email_button": "تأكيد البريد الإلكتروني",
@@ -130,7 +130,7 @@
"upgrade_banner_action": "قم بالترقية هنا", "upgrade_banner_action": "قم بالترقية هنا",
"team_upgraded_successfully": "تمت ترقية فريقك بنجاح!", "team_upgraded_successfully": "تمت ترقية فريقك بنجاح!",
"org_upgrade_banner_description": "شكرًا لك على تجربة خطة Organization الجديدة التي نقدمها. لقد لاحظنا أن منظمتك \"{{teamName}}\" بحاجة إلى الترقية.", "org_upgrade_banner_description": "شكرًا لك على تجربة خطة Organization الجديدة التي نقدمها. لقد لاحظنا أن منظمتك \"{{teamName}}\" بحاجة إلى الترقية.",
"org_upgraded_successfully": "تمت ترقية منظمتك بنجاح!", "org_upgraded_successfully": "تمت ترقية خطة Organization بنجاح!",
"use_link_to_reset_password": "استخدم الرابط أدناه لإعادة تعيين كلمة المرور", "use_link_to_reset_password": "استخدم الرابط أدناه لإعادة تعيين كلمة المرور",
"hey_there": "مرحبًا،", "hey_there": "مرحبًا،",
"forgot_your_password_calcom": "نسيت كلمة المرور الخاصة بك؟ - {{appName}}", "forgot_your_password_calcom": "نسيت كلمة المرور الخاصة بك؟ - {{appName}}",
@@ -550,7 +550,7 @@
"team_description": "بضع جمل عن فريقك. ستظهر على صفحة رابط فريقك.", "team_description": "بضع جمل عن فريقك. ستظهر على صفحة رابط فريقك.",
"org_description": "بضع جمل عن منظمتك. ستظهر على صفحة رابط منظمتك.", "org_description": "بضع جمل عن منظمتك. ستظهر على صفحة رابط منظمتك.",
"members": "الأعضاء", "members": "الأعضاء",
"organization_members": "أعضاء المنظمة", "organization_members": "أعضاء Organization",
"member": "العضو", "member": "العضو",
"number_member_one": "{{count}} عضو", "number_member_one": "{{count}} عضو",
"number_member_other": "{{count}} من الأعضاء", "number_member_other": "{{count}} من الأعضاء",
@@ -1078,7 +1078,7 @@
"url_start_with_https": "يجب أن يبدأ العنوان بـ http:// أو https://", "url_start_with_https": "يجب أن يبدأ العنوان بـ http:// أو https://",
"number_provided": "سيتم توفير رقم الهاتف", "number_provided": "سيتم توفير رقم الهاتف",
"before_event_trigger": "قبل بدء الحدث", "before_event_trigger": "قبل بدء الحدث",
"event_cancelled_trigger": "متى تم إلغاء هذا الحدث", "event_cancelled_trigger": "عند إلغاء هذا الحدث",
"new_event_trigger": "متى تم حجز الحدث الجديد", "new_event_trigger": "متى تم حجز الحدث الجديد",
"email_host_action": "إرسال رسالة إلكترونية إلى المضيف", "email_host_action": "إرسال رسالة إلكترونية إلى المضيف",
"email_attendee_action": "إرسال رسالة إلكترونية إلى الحضور", "email_attendee_action": "إرسال رسالة إلكترونية إلى الحضور",
@@ -1652,9 +1652,8 @@
"delete_sso_configuration_confirmation_description": "هل تريد بالتأكيد حذف تكوين {{connectionType}}؟ لن يتمكن أعضاء فريقك الذين يستخدمون معلومات تسجيل الدخول إلى {{connectionType}} من الوصول إلى Cal.com بعد الآن.", "delete_sso_configuration_confirmation_description": "هل تريد بالتأكيد حذف تكوين {{connectionType}}؟ لن يتمكن أعضاء فريقك الذين يستخدمون معلومات تسجيل الدخول إلى {{connectionType}} من الوصول إلى Cal.com بعد الآن.",
"organizer_timezone": "منظم المناطق الزمنية", "organizer_timezone": "منظم المناطق الزمنية",
"email_user_cta": "عرض الدعوة", "email_user_cta": "عرض الدعوة",
"email_no_user_invite_heading": "تمت دعوتك للانضمام إلى {{appName}} {{entity}}",
"email_no_user_invite_subheading": "دعاك {{invitedBy}} للانضمام إلى فريقه على {{appName}}. إن {{appName}} هو برنامج جدولة الأحداث الذي يمكّنك أنت وفريقك من جدولة الاجتماعات دون الحاجة إلى المراسلة عبر البريد الإلكتروني.", "email_no_user_invite_subheading": "دعاك {{invitedBy}} للانضمام إلى فريقه على {{appName}}. إن {{appName}} هو برنامج جدولة الأحداث الذي يمكّنك أنت وفريقك من جدولة الاجتماعات دون الحاجة إلى المراسلة عبر البريد الإلكتروني.",
"email_user_invite_subheading": "لقد دعاك {{invitedBy}} للانضمام إلى {{entity}} `{{teamName}}` على {{appName}}. إن {{appName}} هو برنامج جدولة الأحداث الذي يمكّنك أنت و{{entity}} من جدولة الاجتماعات دون الحاجة إلى المراسلة عبر البريد الإلكتروني.", "email_user_invite_subheading_team": "دعاك {{invitedBy}} للانضمام إلى فريقه {{teamName}} على {{appName}}. إن {{appName}} هو برنامج جدولة الأحداث الذي يمكّنك أنت وفريقك من جدولة الاجتماعات دون الحاجة إلى المراسلة عبر البريد الإلكتروني.",
"email_no_user_invite_steps_intro": "سنرشدك خلال بضع خطوات قصيرة وستستمتع بجدول زمني خالٍ من التوتر مع {{entity}} في لمح البصر.", "email_no_user_invite_steps_intro": "سنرشدك خلال بضع خطوات قصيرة وستستمتع بجدول زمني خالٍ من التوتر مع {{entity}} في لمح البصر.",
"email_no_user_step_one": "اختر اسم المستخدم الخاص بك", "email_no_user_step_one": "اختر اسم المستخدم الخاص بك",
"email_no_user_step_two": "ربط حساب التقويم الخاص بك", "email_no_user_step_two": "ربط حساب التقويم الخاص بك",
@@ -1834,7 +1833,7 @@
"invite_link_copied": "تم نسخ رابط الدعوة", "invite_link_copied": "تم نسخ رابط الدعوة",
"invite_link_deleted": "تم حذف رابط الدعوة", "invite_link_deleted": "تم حذف رابط الدعوة",
"invite_link_updated": "تم حفظ إعدادات رابط الدعوة", "invite_link_updated": "تم حفظ إعدادات رابط الدعوة",
"link_expires_after": "تم تعيين الروابط للانتهاء بعد...", "link_expires_after": "تم تعيين انتهاء صلاحية الروابط بعد...",
"one_day": "1 يوم", "one_day": "1 يوم",
"seven_days": "7 أيام", "seven_days": "7 أيام",
"thirty_days": "30 يومًا", "thirty_days": "30 يومًا",
@@ -1871,7 +1870,6 @@
"first_event_type_webhook_description": "قم بإنشاء أول شبكة ويب هوك لهذا النوع من الأحداث", "first_event_type_webhook_description": "قم بإنشاء أول شبكة ويب هوك لهذا النوع من الأحداث",
"install_app_on": "تثبيت التطبيق على", "install_app_on": "تثبيت التطبيق على",
"create_for": "إنشاء من أجل", "create_for": "إنشاء من أجل",
"setup_organization": "إعداد منظمة",
"organization_banner_description": "إنشاء بيئات حيث يمكن لفرقك إنشاء تطبيقات مشتركة ومهام سير العمل وأنواع الأحداث باستخدام الجدولة الدوارة والجماعية.", "organization_banner_description": "إنشاء بيئات حيث يمكن لفرقك إنشاء تطبيقات مشتركة ومهام سير العمل وأنواع الأحداث باستخدام الجدولة الدوارة والجماعية.",
"organization_banner_title": "إدارة المنظمات ذات الفرق المتعددة", "organization_banner_title": "إدارة المنظمات ذات الفرق المتعددة",
"set_up_your_organization": "إعداد منظمتك", "set_up_your_organization": "إعداد منظمتك",
@@ -1886,7 +1884,7 @@
"organization_verify_email_body": "الرجاء استخدام الرمز أدناه لتأكيد عنوان بريدك الإلكتروني لمواصلة إعداد منظمتك.", "organization_verify_email_body": "الرجاء استخدام الرمز أدناه لتأكيد عنوان بريدك الإلكتروني لمواصلة إعداد منظمتك.",
"additional_url_parameters": "معلمات الرابط الإضافية", "additional_url_parameters": "معلمات الرابط الإضافية",
"about_your_organization": "حول منظمتك", "about_your_organization": "حول منظمتك",
"about_your_organization_description": "المنظمات هي بيئات مشتركة حيث يمكنك إنشاء فرق متعددة مع أعضاء مشتركين وأنواع الأحداث والتطبيقات ومهام سير العمل والمزيد.", "about_your_organization_description": "المنظمات هي بيئات مشتركة حيث يمكنك إنشاء فرق متعددة مع أعضاء مشتركين وأنواع الأحداث والتطبيقات ومهام سير العمل المشتركة والمزيد.",
"create_your_teams": "إنشاء فرقك", "create_your_teams": "إنشاء فرقك",
"create_your_teams_description": "ابدأوا الجدولة معًا عن طريق إضافة أعضاء فريقك إلى منظمتك", "create_your_teams_description": "ابدأوا الجدولة معًا عن طريق إضافة أعضاء فريقك إلى منظمتك",
"invite_organization_admins": "دعوة مشرفي منظمتك", "invite_organization_admins": "دعوة مشرفي منظمتك",
@@ -1927,7 +1925,7 @@
"404_the_org": "المنظمة", "404_the_org": "المنظمة",
"404_the_team": "الفريق", "404_the_team": "الفريق",
"404_claim_entity_org": "المطالبة بنطاقك الفرعي لمنظمتك", "404_claim_entity_org": "المطالبة بنطاقك الفرعي لمنظمتك",
"404_claim_entity_team": "المطالبة بهذا الفريق والبدء في إدارة الجداول الزمنية بشكل جماعي", "404_claim_entity_team": "انضم لهذا الفريق وابدأ في إدارة الجداول الزمنية بشكل جماعي",
"insights_all_org_filter": "الكل", "insights_all_org_filter": "الكل",
"insights_team_filter": "الفريق: {{teamName}}", "insights_team_filter": "الفريق: {{teamName}}",
"insights_user_filter": "المستخدم: {{userName}}", "insights_user_filter": "المستخدم: {{userName}}",
+9 -11
View File
@@ -118,7 +118,7 @@
"team_info": "Informace o týmu", "team_info": "Informace o týmu",
"request_another_invitation_email": "Pokud si nepřejete použít e-mail {{toEmail}} pro {{appName}} nebo už účet na {{appName}} máte, požádejte prosím o další pozvánku na jiný e-mail.", "request_another_invitation_email": "Pokud si nepřejete použít e-mail {{toEmail}} pro {{appName}} nebo už účet na {{appName}} máte, požádejte prosím o další pozvánku na jiný e-mail.",
"you_have_been_invited": "Byli jste pozváni do týmu {{teamName}}", "you_have_been_invited": "Byli jste pozváni do týmu {{teamName}}",
"user_invited_you": "Uživatel {{user}} vás pozval, abyste se připojili k subjektu {{entity}} {{team}} v aplikaci {{appName}}", "user_invited_you": "Uživatel {{user}} vás pozval, abyste se připojili k {{entity}} {{team}} v aplikaci {{appName}}",
"hidden_team_member_title": "V tomto týmu nejste viditelní", "hidden_team_member_title": "V tomto týmu nejste viditelní",
"hidden_team_member_message": "Vaše místo není zaplacené. Buď přejděte na tarif Pro, nebo informujte vlastníka týmu, že za vaše místo může zaplatit.", "hidden_team_member_message": "Vaše místo není zaplacené. Buď přejděte na tarif Pro, nebo informujte vlastníka týmu, že za vaše místo může zaplatit.",
"hidden_team_owner_message": "Pro využívání týmů potřebujete tarif Pro, budete skrytí, než přejdete na vyšší verzi.", "hidden_team_owner_message": "Pro využívání týmů potřebujete tarif Pro, budete skrytí, než přejdete na vyšší verzi.",
@@ -130,7 +130,7 @@
"upgrade_banner_action": "Upgradovat zde", "upgrade_banner_action": "Upgradovat zde",
"team_upgraded_successfully": "Váš tým byl úspěšně přešel na vyšší verzi!", "team_upgraded_successfully": "Váš tým byl úspěšně přešel na vyšší verzi!",
"org_upgrade_banner_description": "Děkujeme, že jste vyzkoušeli náš tarif Organizace. Všimli jsme si, že vaše organizace „{{teamName}}“ vyžaduje upgrade.", "org_upgrade_banner_description": "Děkujeme, že jste vyzkoušeli náš tarif Organizace. Všimli jsme si, že vaše organizace „{{teamName}}“ vyžaduje upgrade.",
"org_upgraded_successfully": "Vaše organizace byla upgradována!", "org_upgraded_successfully": "Váš upgrade na tarif Organization byl úspěšně dokončen!",
"use_link_to_reset_password": "Pro obnovení hesla použijte odkaz níž", "use_link_to_reset_password": "Pro obnovení hesla použijte odkaz níž",
"hey_there": "Zdravíme,", "hey_there": "Zdravíme,",
"forgot_your_password_calcom": "Zapomněli jste heslo? - {{appName}}", "forgot_your_password_calcom": "Zapomněli jste heslo? - {{appName}}",
@@ -307,7 +307,7 @@
"layout": "Rozvržení", "layout": "Rozvržení",
"bookerlayout_default_title": "Výchozí zobrazení", "bookerlayout_default_title": "Výchozí zobrazení",
"bookerlayout_description": "Můžete si jich vybrat více a vaši rezervující si mohou zobrazení přepínat.", "bookerlayout_description": "Můžete si jich vybrat více a vaši rezervující si mohou zobrazení přepínat.",
"bookerlayout_user_settings_title": "Rozvržení rezervace", "bookerlayout_user_settings_title": "Rozvržení rezervací",
"bookerlayout_user_settings_description": "Můžete si jich vybrat více a vaši rezervující si mohou zobrazení přepínat. Lze nadefinovat pro každou událost zvlášť.", "bookerlayout_user_settings_description": "Můžete si jich vybrat více a vaši rezervující si mohou zobrazení přepínat. Lze nadefinovat pro každou událost zvlášť.",
"bookerlayout_month_view": "Měsíční", "bookerlayout_month_view": "Měsíční",
"bookerlayout_week_view": "Týdenní", "bookerlayout_week_view": "Týdenní",
@@ -403,7 +403,7 @@
"recording_ready": "Odkaz ke stažení záznamu je připraven", "recording_ready": "Odkaz ke stažení záznamu je připraven",
"booking_created": "Rezervace vytvořena", "booking_created": "Rezervace vytvořena",
"booking_rejected": "Rezervace byla zamítnuta", "booking_rejected": "Rezervace byla zamítnuta",
"booking_requested": "Byla vyžádána rezervace", "booking_requested": "Váš požadavek na rezervaci byl úspěšně odeslán",
"meeting_ended": "Schůzka skončila", "meeting_ended": "Schůzka skončila",
"form_submitted": "Formulář byl odeslán", "form_submitted": "Formulář byl odeslán",
"event_triggers": "Eventy na základě akce", "event_triggers": "Eventy na základě akce",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "Opravdu chcete odstranit konfiguraci {{connectionType}}? Členové vašeho týmu, kteří používají přihlášení {{connectionType}}, ztratí přístup k webu Cal.com.", "delete_sso_configuration_confirmation_description": "Opravdu chcete odstranit konfiguraci {{connectionType}}? Členové vašeho týmu, kteří používají přihlášení {{connectionType}}, ztratí přístup k webu Cal.com.",
"organizer_timezone": "Časové pásmo organizátora", "organizer_timezone": "Časové pásmo organizátora",
"email_user_cta": "Zobrazit pozvánku", "email_user_cta": "Zobrazit pozvánku",
"email_no_user_invite_heading": "Byli jste pozváni, abyste se připojili k subjektu {{entity}} v aplikaci {{appName}}",
"email_no_user_invite_subheading": "Uživatel {{invitedBy}} vás pozval, abyste se připojili k jeho týmu v aplikaci {{appName}}. {{appName}} je plánovač událostí, který vám a vašemu týmu umožňuje plánovat schůzky bez e-mailového ping-pongu.", "email_no_user_invite_subheading": "Uživatel {{invitedBy}} vás pozval, abyste se připojili k jeho týmu v aplikaci {{appName}}. {{appName}} je plánovač událostí, který vám a vašemu týmu umožňuje plánovat schůzky bez e-mailového ping-pongu.",
"email_user_invite_subheading": "Uživatel {{invitedBy}} vás pozval, abyste se připojili k týmu {{teamName}} subjektu {{entity}} v aplikaci {{appName}}. {{appName}} je plánovač událostí, který vám a vašemu subjektu {{entity}} umožňuje plánovat schůzky bez e-mailového pingpongu.", "email_user_invite_subheading_team": "Uživatel {{invitedBy}} vás pozval, abyste se připojili k jeho týmu „{{teamName}}“ v aplikaci {{appName}}. {{appName}} je plánovač událostí, který vám a vašemu týmu umožňuje plánovat schůzky bez e-mailového pingpongu.",
"email_no_user_invite_steps_intro": "Provedeme vás několika krátkými kroky a za malou chvíli si budete se svým subjektem {{entity}} užívat plánování bez stresu.", "email_no_user_invite_steps_intro": "Provedeme vás několika krátkými kroky a za malou chvíli si budete se svým subjektem {{entity}} užívat plánování bez stresu.",
"email_no_user_step_one": "Vyberte si uživatelské jméno", "email_no_user_step_one": "Vyberte si uživatelské jméno",
"email_no_user_step_two": "Připojte svůj účet kalendáře", "email_no_user_step_two": "Připojte svůj účet kalendáře",
@@ -1878,7 +1877,6 @@
"first_event_type_webhook_description": "Vytvořte svůj první webhook pro tento typ události", "first_event_type_webhook_description": "Vytvořte svůj první webhook pro tento typ události",
"install_app_on": "Nainstalovat aplikaci v", "install_app_on": "Nainstalovat aplikaci v",
"create_for": "Vytvořit pro", "create_for": "Vytvořit pro",
"setup_organization": "Nastavení organizace",
"organization_banner_description": "Vytvořte prostředí, ve kterém budou moct vaše týmy vytvářet sdílené aplikace, pracovní postupy a typy událostí s kolektivním plánováním nebo plánováním typu round-robin.", "organization_banner_description": "Vytvořte prostředí, ve kterém budou moct vaše týmy vytvářet sdílené aplikace, pracovní postupy a typy událostí s kolektivním plánováním nebo plánováním typu round-robin.",
"organization_banner_title": "Správa organizace s více týmy", "organization_banner_title": "Správa organizace s více týmy",
"set_up_your_organization": "Nastavení organizace", "set_up_your_organization": "Nastavení organizace",
@@ -1889,12 +1887,12 @@
"admin_username": "Uživatelské jméno správce", "admin_username": "Uživatelské jméno správce",
"organization_name": "Název organizace", "organization_name": "Název organizace",
"organization_url": "Adresa URL organizace", "organization_url": "Adresa URL organizace",
"organization_verify_header": "Ověřte e-mailovou adresu organizace", "organization_verify_header": "Ověřte svou e-mailovou adresu organizace",
"organization_verify_email_body": "Pomocí uvedeného kódu ověřte vaši e-mailovou adresu, abyste mohli pokračovat v nastavení vaší organizace.", "organization_verify_email_body": "Pomocí uvedeného kódu ověřte vaši e-mailovou adresu, abyste mohli pokračovat v nastavení vaší organizace.",
"additional_url_parameters": "Další parametry adresy URL", "additional_url_parameters": "Další parametry adresy URL",
"about_your_organization": "Informace o vaší organizaci", "about_your_organization": "Informace o vaší organizaci",
"about_your_organization_description": "Organizace jsou sdílená prostředí, ve kterých můžete vytvořit několik týmů se sdílenými členy, typy událostí, aplikacemi, pracovními postupy a mnoha dalšími věcmi.", "about_your_organization_description": "Organizace jsou sdílená prostředí, ve kterých můžete vytvořit několik týmů se sdílenými členy, typy událostí, aplikacemi, pracovními postupy a mnoha dalšími věcmi.",
"create_your_teams": "Vytvoření týmů", "create_your_teams": "Vytvořit tým",
"create_your_teams_description": "Přidejte do své organizace členy a pusťte se do společného plánování", "create_your_teams_description": "Přidejte do své organizace členy a pusťte se do společného plánování",
"invite_organization_admins": "Pozvěte správce své organizace", "invite_organization_admins": "Pozvěte správce své organizace",
"invite_organization_admins_description": "Tito správci budou mít přístup ke všem týmům ve vaší organizaci. Správce a členy týmů můžete přidat později.", "invite_organization_admins_description": "Tito správci budou mít přístup ke všem týmům ve vaší organizaci. Správce a členy týmů můžete přidat později.",
@@ -1934,11 +1932,11 @@
"404_the_org": "Organizace", "404_the_org": "Organizace",
"404_the_team": "Tým", "404_the_team": "Tým",
"404_claim_entity_org": "Vyžádejte si subdoménu pro svou organizaci", "404_claim_entity_org": "Vyžádejte si subdoménu pro svou organizaci",
"404_claim_entity_team": "Vyžádejte si tento tým a začněte kolektivně spravovat rozvrhy", "404_claim_entity_team": "Vyžádejte si přístup k tomuto týmu a začněte kolektivně spravovat rozvrhy",
"insights_all_org_filter": "Všechny aplikace", "insights_all_org_filter": "Všechny aplikace",
"insights_team_filter": "Tým: {{teamName}}", "insights_team_filter": "Tým: {{teamName}}",
"insights_user_filter": "Uživatel: {{userName}}", "insights_user_filter": "Uživatel: {{userName}}",
"insights_subtitle": "Zobrazte si přehled o rezervacích napříč vašimi událostmi", "insights_subtitle": "Zobrazte si Insight rezervací napříč vašimi událostmi",
"custom_plan": "Vlastní plán", "custom_plan": "Vlastní plán",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Přidejte své nové řetězce nahoru ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Přidejte své nové řetězce nahoru ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -1679,9 +1679,8 @@
"delete_sso_configuration_confirmation_description": "Sind Sie sicher, dass Sie die {{connectionType}}-Konfiguration löschen möchten? Ihre Teammitglieder, die sich über {{connectionType}} anmelden, werden keinen Zugriff mehr auf Cal.com haben.", "delete_sso_configuration_confirmation_description": "Sind Sie sicher, dass Sie die {{connectionType}}-Konfiguration löschen möchten? Ihre Teammitglieder, die sich über {{connectionType}} anmelden, werden keinen Zugriff mehr auf Cal.com haben.",
"organizer_timezone": "Zeitzone des Veranstalters", "organizer_timezone": "Zeitzone des Veranstalters",
"email_user_cta": "Einladung anzeigen", "email_user_cta": "Einladung anzeigen",
"email_no_user_invite_heading": "Sie wurden eingeladen, einem {{entity}} in {{appName}} beizutreten",
"email_no_user_invite_subheading": "{{invitedBy}} hat Sie eingeladen, dem Team in {{appName}} beizutreten. {{appName}} ist der Event-Planer, der es Ihnen und Ihrem Team ermöglicht, Meetings ohne ständiges hin und her zu planen.", "email_no_user_invite_subheading": "{{invitedBy}} hat Sie eingeladen, dem Team in {{appName}} beizutreten. {{appName}} ist der Event-Planer, der es Ihnen und Ihrem Team ermöglicht, Meetings ohne ständiges hin und her zu planen.",
"email_user_invite_subheading": "{{invitedBy}} hat Sie eingeladen, dem {{entity}} „{{teamName}}“ in {{appName}} beizutreten. {{appName}} ist der Terminplaner, der es Ihnen und Ihrem {{entity}} ermöglicht, Meetings ohne ständiges hin und her zu planen.", "email_user_invite_subheading_team": "{{invitedBy}} hat Sie eingeladen, dem Team „{{teamName}}“ beizutreten. {{appName}} ist der Event-Planer, der es Ihnen und Ihrem Team ermöglicht, Meetings ohne Hin und Her zu planen.",
"email_no_user_invite_steps_intro": "Wir begleiten Sie durch ein paar Schritte, danach können Sie in kürzester Zeit stressfreie Planung mit Ihrem {{entity}} genießen.", "email_no_user_invite_steps_intro": "Wir begleiten Sie durch ein paar Schritte, danach können Sie in kürzester Zeit stressfreie Planung mit Ihrem {{entity}} genießen.",
"email_no_user_step_one": "Wählen Sie Ihren Benutzernamen", "email_no_user_step_one": "Wählen Sie Ihren Benutzernamen",
"email_no_user_step_two": "Verbinden Sie Ihr Kalenderkonto", "email_no_user_step_two": "Verbinden Sie Ihr Kalenderkonto",
@@ -1902,7 +1901,6 @@
"install_app_on": "App installieren auf", "install_app_on": "App installieren auf",
"create_for": "Erstellen für", "create_for": "Erstellen für",
"currency": "Währung", "currency": "Währung",
"setup_organization": "Eine Organization einrichten",
"organization_banner_description": "Schaffen Sie Umgebungen, in der Teams gemeinsame Apps, Workflows und Termintypen mit Round Robin und kollektiver Terminplanung erstellen können.", "organization_banner_description": "Schaffen Sie Umgebungen, in der Teams gemeinsame Apps, Workflows und Termintypen mit Round Robin und kollektiver Terminplanung erstellen können.",
"organization_banner_title": "Verwalten Sie Organizations mit mehreren Teams", "organization_banner_title": "Verwalten Sie Organizations mit mehreren Teams",
"set_up_your_organization": "Ihre Organization einrichten", "set_up_your_organization": "Ihre Organization einrichten",
@@ -1060,7 +1060,7 @@
"your_unique_api_key": "Your unique API key", "your_unique_api_key": "Your unique API key",
"copy_safe_api_key": "Copy this API key and save it somewhere safe. If you lose this key you have to generate a new one.", "copy_safe_api_key": "Copy this API key and save it somewhere safe. If you lose this key you have to generate a new one.",
"zapier_setup_instructions": "<0>Log into your Zapier account and create a new Zap.</0><1>Select Cal.com as your Trigger app. Also choose a Trigger event.</1><2>Choose your account and then enter your Unique API Key.</2><3>Test your Trigger.</3><4>You're set!</4>", "zapier_setup_instructions": "<0>Log into your Zapier account and create a new Zap.</0><1>Select Cal.com as your Trigger app. Also choose a Trigger event.</1><2>Choose your account and then enter your Unique API Key.</2><3>Test your Trigger.</3><4>You're set!</4>",
"make_setup_instructions": "<0>Log into your Make account and create a new Scenario.</0><1>Select Cal.com as your Trigger app. Also choose a Trigger event.</1><2>Choose your account and then enter your Unique API Key.</2><3>Test your Trigger.</3><4>You're set!</4>", "make_setup_instructions": "<0>Go to <1><0>Make Invite Link</0></1> and install the Cal.com app.</0><1>Log into your Make account and create a new Scenario.</1><2>Select Cal.com as your Trigger app. Also choose a Trigger event.</2><3>Choose your account and then enter your Unique API Key.</3><4>Test your Trigger.</4><5>You're set!</5>",
"install_zapier_app": "Please first install the Zapier App in the app store.", "install_zapier_app": "Please first install the Zapier App in the app store.",
"install_make_app": "Please first install the Make App in the app store.", "install_make_app": "Please first install the Make App in the app store.",
"connect_apple_server": "Connect to Apple Server", "connect_apple_server": "Connect to Apple Server",
@@ -1093,7 +1093,6 @@
"or_lowercase": "or", "or_lowercase": "or",
"nevermind": "Nevermind", "nevermind": "Nevermind",
"go_to": "Go to: ", "go_to": "Go to: ",
"invite_link_make": "<li>Go to<a>Make Invite Link</a> and install Cal.com app</li>",
"zapier_invite_link": "Zapier Invite Link", "zapier_invite_link": "Zapier Invite Link",
"meeting_url_provided_after_confirmed": "A Meeting URL will be created once the event is confirmed.", "meeting_url_provided_after_confirmed": "A Meeting URL will be created once the event is confirmed.",
"dynamically_display_attendee_or_organizer": "Dynamically display the name of your attendee for you, or your name if it's viewed by your attendee", "dynamically_display_attendee_or_organizer": "Dynamically display the name of your attendee for you, or your name if it's viewed by your attendee",
@@ -1689,9 +1688,11 @@
"delete_sso_configuration_confirmation_description": "Are you sure you want to delete the {{connectionType}} configuration? Your team members who use {{connectionType}} login will no longer be able to access Cal.com.", "delete_sso_configuration_confirmation_description": "Are you sure you want to delete the {{connectionType}} configuration? Your team members who use {{connectionType}} login will no longer be able to access Cal.com.",
"organizer_timezone": "Organizer timezone", "organizer_timezone": "Organizer timezone",
"email_user_cta": "View Invitation", "email_user_cta": "View Invitation",
"email_no_user_invite_heading": "You’ve been invited to join a {{appName}} {{entity}}", "email_no_user_invite_heading_team": "You’ve been invited to join a {{appName}} team",
"email_no_user_invite_heading_org": "You’ve been invited to join a {{appName}} organization",
"email_no_user_invite_subheading": "{{invitedBy}} has invited you to join their team on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your team to schedule meetings without the email tennis.", "email_no_user_invite_subheading": "{{invitedBy}} has invited you to join their team on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your team to schedule meetings without the email tennis.",
"email_user_invite_subheading": "{{invitedBy}} has invited you to join their {{entity}} `{{teamName}}` on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your {{entity}} to schedule meetings without the email tennis.", "email_user_invite_subheading_team": "{{invitedBy}} has invited you to join their team `{{teamName}}` on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your team to schedule meetings without the email tennis.",
"email_user_invite_subheading_org": "{{invitedBy}} has invited you to join their organization `{{teamName}}` on {{appName}}. {{appName}} is the event-juggling scheduler that enables you and your organization to schedule meetings without the email tennis.",
"email_no_user_invite_steps_intro": "We’ll walk you through a few short steps and you’ll be enjoying stress free scheduling with your {{entity}} in no time.", "email_no_user_invite_steps_intro": "We’ll walk you through a few short steps and you’ll be enjoying stress free scheduling with your {{entity}} in no time.",
"email_no_user_step_one": "Choose your username", "email_no_user_step_one": "Choose your username",
"email_no_user_step_two": "Connect your calendar account", "email_no_user_step_two": "Connect your calendar account",
@@ -1914,7 +1915,6 @@
"install_app_on": "Install app on", "install_app_on": "Install app on",
"create_for": "Create for", "create_for": "Create for",
"currency": "Currency", "currency": "Currency",
"setup_organization": "Setup an Organization",
"organization_banner_description": "Create an environments where your teams can create shared apps, workflows and event types with round-robin and collective scheduling.", "organization_banner_description": "Create an environments where your teams can create shared apps, workflows and event types with round-robin and collective scheduling.",
"organization_banner_title": "Manage organizations with multiple teams", "organization_banner_title": "Manage organizations with multiple teams",
"set_up_your_organization": "Set up your organization", "set_up_your_organization": "Set up your organization",
@@ -2044,5 +2044,7 @@
"include_calendar_event": "Include calendar event", "include_calendar_event": "Include calendar event",
"recently_added":"Recently added", "recently_added":"Recently added",
"no_members_found": "No members found", "no_members_found": "No members found",
"event_setup_length_error":"Event Setup: The duration must be at least 1 minute.",
"availability_schedules":"Availability Schedules",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -129,7 +129,7 @@
"team_upgrade_banner_description": "Gracias por probar nuestro nuevo plan de equipo. Notamos que su equipo \"{{teamName}}\" necesita actualizarse.", "team_upgrade_banner_description": "Gracias por probar nuestro nuevo plan de equipo. Notamos que su equipo \"{{teamName}}\" necesita actualizarse.",
"upgrade_banner_action": "Actualizar aquí", "upgrade_banner_action": "Actualizar aquí",
"team_upgraded_successfully": "¡Tu equipo se actualizó con éxito!", "team_upgraded_successfully": "¡Tu equipo se actualizó con éxito!",
"org_upgrade_banner_description": "Gracias por probar nuestro nuevo plan de equipo. Notamos que su equipo \"{{teamName}}\" necesita actualizarse.", "org_upgrade_banner_description": "Gracias por probar nuestro nuevo plan Organization. Notamos que su Organization \"{{teamName}}\" necesita actualizarse.",
"org_upgraded_successfully": "Su Organization se actualizó con éxito.", "org_upgraded_successfully": "Su Organization se actualizó con éxito.",
"use_link_to_reset_password": "Utilice el enlace de abajo para restablecer su contraseña", "use_link_to_reset_password": "Utilice el enlace de abajo para restablecer su contraseña",
"hey_there": "Hola,", "hey_there": "Hola,",
@@ -306,7 +306,7 @@
"password_has_been_reset_login": "Su contraseña ha sido restablecida. Ahora puede iniciar sesión con su nueva contraseña.", "password_has_been_reset_login": "Su contraseña ha sido restablecida. Ahora puede iniciar sesión con su nueva contraseña.",
"layout": "Diseño", "layout": "Diseño",
"bookerlayout_default_title": "Vista predeterminada", "bookerlayout_default_title": "Vista predeterminada",
"bookerlayout_description": "Puede seleccionar varios y quienes le reserven pueden cambiar de vista.", "bookerlayout_description": "Puede seleccionar varias y quienes le reserven pueden cambiar de vista.",
"bookerlayout_user_settings_title": "Diseño de reserva", "bookerlayout_user_settings_title": "Diseño de reserva",
"bookerlayout_user_settings_description": "Puede seleccionar varios y quienes le reservan pueden cambiar de vista. Esto se puede anular por evento.", "bookerlayout_user_settings_description": "Puede seleccionar varios y quienes le reservan pueden cambiar de vista. Esto se puede anular por evento.",
"bookerlayout_month_view": "Mes", "bookerlayout_month_view": "Mes",
@@ -315,7 +315,7 @@
"bookerlayout_error_min_one_enabled": "Al menos un diseño tiene que estar habilitado.", "bookerlayout_error_min_one_enabled": "Al menos un diseño tiene que estar habilitado.",
"bookerlayout_error_default_not_enabled": "El diseño que seleccionó como vista predeterminada no es parte de los diseños habilitados.", "bookerlayout_error_default_not_enabled": "El diseño que seleccionó como vista predeterminada no es parte de los diseños habilitados.",
"bookerlayout_error_unknown_layout": "El diseño seleccionado no es un diseño válido.", "bookerlayout_error_unknown_layout": "El diseño seleccionado no es un diseño válido.",
"bookerlayout_override_global_settings": "Puede gestionar esto para todos sus tipos de eventos en <2>configuración / apariencia</2> o <6>sobrescribir solo para este evento</6>.", "bookerlayout_override_global_settings": "Puede gestionar esto para todos sus tipos de eventos en <2>configuración / apariencia</2> o <6>anular solo para este evento</6>.",
"unexpected_error_try_again": "Ocurrió un error inesperado. Inténtelo de nuevo.", "unexpected_error_try_again": "Ocurrió un error inesperado. Inténtelo de nuevo.",
"sunday_time_error": "Hora inválida del domingo", "sunday_time_error": "Hora inválida del domingo",
"monday_time_error": "Hora inválida del lunes", "monday_time_error": "Hora inválida del lunes",
@@ -551,7 +551,7 @@
"team_description": "Comentarios sobre tu equipo. Esta información aparecerá en la página de la URL de tu equipo.", "team_description": "Comentarios sobre tu equipo. Esta información aparecerá en la página de la URL de tu equipo.",
"org_description": "Algunas frases sobre su organización. Esto aparecerá en la página de la URL de su organización.", "org_description": "Algunas frases sobre su organización. Esto aparecerá en la página de la URL de su organización.",
"members": "Miembros", "members": "Miembros",
"organization_members": "Miembros de la organización", "organization_members": "Miembros de Organization",
"member": "Miembro", "member": "Miembro",
"number_member_one": "{{count}} miembro", "number_member_one": "{{count}} miembro",
"number_member_other": "{{count}} miembros", "number_member_other": "{{count}} miembros",
@@ -699,7 +699,7 @@
"create_team_to_get_started": "Crea un equipo para empezar", "create_team_to_get_started": "Crea un equipo para empezar",
"teams": "Equipos", "teams": "Equipos",
"team": "Equipo", "team": "Equipo",
"organization": "Organización", "organization": "Organization",
"team_billing": "Facturación del equipo", "team_billing": "Facturación del equipo",
"team_billing_description": "Gestione la facturación para su equipo", "team_billing_description": "Gestione la facturación para su equipo",
"upgrade_to_flexible_pro_title": "Hemos cambiado la facturación de los equipos", "upgrade_to_flexible_pro_title": "Hemos cambiado la facturación de los equipos",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "¿Está seguro de que desea eliminar la configuración de {{connectionType}}? Los miembros de su equipo que utilicen el inicio de sesión {{connectionType}} ya no podrán acceder a Cal.com.", "delete_sso_configuration_confirmation_description": "¿Está seguro de que desea eliminar la configuración de {{connectionType}}? Los miembros de su equipo que utilicen el inicio de sesión {{connectionType}} ya no podrán acceder a Cal.com.",
"organizer_timezone": "Zona horaria del organizador", "organizer_timezone": "Zona horaria del organizador",
"email_user_cta": "Ver la invitación", "email_user_cta": "Ver la invitación",
"email_no_user_invite_heading": "Lo invitaron a unirse a {{appName}} {{entity}}",
"email_no_user_invite_subheading": "{{invitedBy}} lo invitó a unirse a su equipo en {{appName}}. {{appName}} es el programador de eventos que les permite a usted y a su equipo programar reuniones sin necesidad de enviar correos electrónicos.", "email_no_user_invite_subheading": "{{invitedBy}} lo invitó a unirse a su equipo en {{appName}}. {{appName}} es el programador de eventos que les permite a usted y a su equipo programar reuniones sin necesidad de enviar correos electrónicos.",
"email_user_invite_subheading": "{{invitedBy}} lo ha invitado a unirse a su {{entity}} \"{{teamName}}\" en {{appName}}. {{appName}} es el planificador de eventos que le permite a usted y a su {{entity}} programar reuniones sin necesidad de correos electrónicos.", "email_user_invite_subheading_team": "{{invitedBy}} lo ha invitado a unirse a su equipo \"{{teamName}}\" en {{appName}}. {{appName}} es el planificador de eventos que le permite a usted y a su equipo programar reuniones sin correos electrónicos de ida y vuelta.",
"email_no_user_invite_steps_intro": "Lo guiaremos a través de unos pocos pasos y disfrutará de una programación sin estrés con su {{entity}} en muy poco tiempo.", "email_no_user_invite_steps_intro": "Lo guiaremos a través de unos pocos pasos y disfrutará de una programación sin estrés con su {{entity}} en muy poco tiempo.",
"email_no_user_step_one": "Elija su nombre de usuario", "email_no_user_step_one": "Elija su nombre de usuario",
"email_no_user_step_two": "Conecte su cuenta de calendario", "email_no_user_step_two": "Conecte su cuenta de calendario",
@@ -1878,7 +1877,6 @@
"first_event_type_webhook_description": "Cree su primer webhook para este tipo de evento", "first_event_type_webhook_description": "Cree su primer webhook para este tipo de evento",
"install_app_on": "Instalar aplicación en", "install_app_on": "Instalar aplicación en",
"create_for": "Crear para", "create_for": "Crear para",
"setup_organization": "Configurar una organización",
"organization_banner_description": "Cree entornos en los que sus equipos puedan crear aplicaciones, flujos de trabajo y tipos de eventos compartidos con programación por turnos y colectiva.", "organization_banner_description": "Cree entornos en los que sus equipos puedan crear aplicaciones, flujos de trabajo y tipos de eventos compartidos con programación por turnos y colectiva.",
"organization_banner_title": "Gestione organizaciones con varios equipos", "organization_banner_title": "Gestione organizaciones con varios equipos",
"set_up_your_organization": "Configure su organización", "set_up_your_organization": "Configure su organización",
@@ -1918,7 +1916,7 @@
"org_no_teams_yet_description": "Si usted es un administrador, asegúrese de crear equipos para que se muestren aquí.", "org_no_teams_yet_description": "Si usted es un administrador, asegúrese de crear equipos para que se muestren aquí.",
"set_up": "Configurar", "set_up": "Configurar",
"set_up_your_profile": "Configure su perfil", "set_up_your_profile": "Configure su perfil",
"set_up_your_profile_description": "Informe a las personas quién es usted dentro de {{orgName}} cuándo interactúan con su enlace público.", "set_up_your_profile_description": "Informe a las personas quién es usted dentro de {{orgName}} y cuándo interactúen con su enlace público.",
"my_profile": "Mi perfil", "my_profile": "Mi perfil",
"my_settings": "Mi configuración", "my_settings": "Mi configuración",
"crm": "CRM", "crm": "CRM",
@@ -1060,7 +1060,7 @@
"your_unique_api_key": "Votre clé API unique", "your_unique_api_key": "Votre clé API unique",
"copy_safe_api_key": "Copiez cette clé API et conservez-la dans un endroit sûr. Si vous perdez cette clé, vous devrez en générer une nouvelle.", "copy_safe_api_key": "Copiez cette clé API et conservez-la dans un endroit sûr. Si vous perdez cette clé, vous devrez en générer une nouvelle.",
"zapier_setup_instructions": "<0>Connectez-vous à votre compte Zapier et créez un nouveau Zap.</0><1>Sélectionnez Cal.com comme application déclencheur. Choisissez également un événement déclencheur.</1><2>Choisissez votre compte, puis saisissez votre clé API unique.</2><3>Testez votre déclencheur.</3><4>Vous êtes prêt !</4>", "zapier_setup_instructions": "<0>Connectez-vous à votre compte Zapier et créez un nouveau Zap.</0><1>Sélectionnez Cal.com comme application déclencheur. Choisissez également un événement déclencheur.</1><2>Choisissez votre compte, puis saisissez votre clé API unique.</2><3>Testez votre déclencheur.</3><4>Vous êtes prêt !</4>",
"make_setup_instructions": "<0>Connectez-vous à votre compte Make et créez un nouveau Scénario.</0><1>Sélectionnez Cal.com comme application déclencheur. Choisissez également un événement déclencheur.</1><2>Choisissez votre compte, puis saisissez votre clé API unique.</2><3>Testez votre déclencheur.</3><4>Vous êtes prêt !</4>", "make_setup_instructions": "<0>Accédez au <1><0>lien d'invitation Make</0></1> et installez l'application Cal.com.</0><1>Connectez-vous à votre compte Make et créez un nouveau scénario.</1><2>Sélectionnez Cal.com comme application déclencheur. Choisissez également un événement déclencheur.</2><3>Choisissez votre compte, puis saisissez votre clé API unique.</3><4>Testez votre déclencheur.</4><5>Vous êtes prêt !</5>",
"install_zapier_app": "Veuillez d'abord installer l'application Zapier dans l'App Store.", "install_zapier_app": "Veuillez d'abord installer l'application Zapier dans l'App Store.",
"install_make_app": "Veuillez d'abord installer l'application Make dans l'App Store.", "install_make_app": "Veuillez d'abord installer l'application Make dans l'App Store.",
"connect_apple_server": "Se connecter au serveur d'Apple", "connect_apple_server": "Se connecter au serveur d'Apple",
@@ -1093,7 +1093,6 @@
"or_lowercase": "ou", "or_lowercase": "ou",
"nevermind": "Annuler", "nevermind": "Annuler",
"go_to": "Aller à : ", "go_to": "Aller à : ",
"invite_link_make": "<li>Accédez<a>au lien d'invitation Make</a> et installez l'application Cal.com</li>",
"zapier_invite_link": "Lien d'invitation Zapier", "zapier_invite_link": "Lien d'invitation Zapier",
"meeting_url_provided_after_confirmed": "Un lien de rendez-vous sera créé une fois l'événement confirmé.", "meeting_url_provided_after_confirmed": "Un lien de rendez-vous sera créé une fois l'événement confirmé.",
"dynamically_display_attendee_or_organizer": "Affiche dynamiquement le nom du participant pour vous ou votre nom s'il est vu par le participant", "dynamically_display_attendee_or_organizer": "Affiche dynamiquement le nom du participant pour vous ou votre nom s'il est vu par le participant",
@@ -1689,9 +1688,11 @@
"delete_sso_configuration_confirmation_description": "Voulez-vous vraiment supprimer la configuration {{connectionType}} ? Les membres de votre équipe utilisant la connexion {{connectionType}} ne pourront plus accéder à Cal.com.", "delete_sso_configuration_confirmation_description": "Voulez-vous vraiment supprimer la configuration {{connectionType}} ? Les membres de votre équipe utilisant la connexion {{connectionType}} ne pourront plus accéder à Cal.com.",
"organizer_timezone": "Fuseau horaire de l'organisateur", "organizer_timezone": "Fuseau horaire de l'organisateur",
"email_user_cta": "Voir l'invitation", "email_user_cta": "Voir l'invitation",
"email_no_user_invite_heading": "Vous avez été invité à rejoindre une {{entity}} {{appName}}", "email_no_user_invite_heading_team": "Vous avez été invité à rejoindre une équipe {{appName}}",
"email_no_user_invite_heading_org": "Vous avez été invité à rejoindre une organisation {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} vous a invité à rejoindre son équipe sur {{appName}}. {{appName}} est le planificateur d'événements qui vous permet à vous et à votre équipe d'organiser des rendez-vous sans échanges d'e-mails.", "email_no_user_invite_subheading": "{{invitedBy}} vous a invité à rejoindre son équipe sur {{appName}}. {{appName}} est le planificateur d'événements qui vous permet à vous et à votre équipe d'organiser des rendez-vous sans échanges d'e-mails.",
"email_user_invite_subheading": "{{invitedBy}} vous a invité à rejoindre son {{entity}} « {{teamName}} » sur {{appName}}. {{appName}} est le planificateur d'événements qui vous permet à vous et à votre {{entity}} d'organiser des rendez-vous sans échanges d'e-mails.", "email_user_invite_subheading_team": "{{invitedBy}} vous a invité à rejoindre son équipe « {{teamName}} » sur {{appName}}. {{appName}} est le planificateur d'événements qui vous permet à vous et à votre équipe d'organiser des rendez-vous sans échanges d'e-mails.",
"email_user_invite_subheading_org": "{{invitedBy}} vous a invité à rejoindre son organisation « {{teamName}} » sur {{appName}}. {{appName}} est le planificateur d'événements qui vous permet à vous et à votre organisation d'organiser des rendez-vous sans échanges d'e-mails.",
"email_no_user_invite_steps_intro": "Nous vous guiderons à travers quelques étapes courtes et vous profiterez d'une planification sans stress avec votre {{entity}} en un rien de temps.", "email_no_user_invite_steps_intro": "Nous vous guiderons à travers quelques étapes courtes et vous profiterez d'une planification sans stress avec votre {{entity}} en un rien de temps.",
"email_no_user_step_one": "Choisissez votre nom d'utilisateur", "email_no_user_step_one": "Choisissez votre nom d'utilisateur",
"email_no_user_step_two": "Connectez votre compte de calendrier", "email_no_user_step_two": "Connectez votre compte de calendrier",
@@ -1914,7 +1915,6 @@
"install_app_on": "Installer l’application sur", "install_app_on": "Installer l’application sur",
"create_for": "Créer pour", "create_for": "Créer pour",
"currency": "Devise", "currency": "Devise",
"setup_organization": "Configurer une organisation",
"organization_banner_description": "Créez un environnement où vos équipes peuvent créer des applications partagées, des workflows et des types d'événements avec une planification round-robin et collective.", "organization_banner_description": "Créez un environnement où vos équipes peuvent créer des applications partagées, des workflows et des types d'événements avec une planification round-robin et collective.",
"organization_banner_title": "Gérer les organisations avec plusieurs équipes", "organization_banner_title": "Gérer les organisations avec plusieurs équipes",
"set_up_your_organization": "Configurer votre organisation", "set_up_your_organization": "Configurer votre organisation",
@@ -2044,5 +2044,7 @@
"include_calendar_event": "Inclure l'événement du calendrier", "include_calendar_event": "Inclure l'événement du calendrier",
"recently_added": "Ajouté récemment", "recently_added": "Ajouté récemment",
"no_members_found": "Aucun membre trouvé", "no_members_found": "Aucun membre trouvé",
"event_setup_length_error": "Configuration de l'événement : la durée doit être d'au moins 1 minute.",
"availability_schedules": "Horaires de disponibilité",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Ajoutez vos nouvelles chaînes ci-dessus ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Ajoutez vos nouvelles chaînes ci-dessus ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "אתה בטוח שאתה רוצה למחוק את הגדרות {{connectionType}}? חברי הצוות שלך שמשתמשים ב- {{connectionType}} להזדהות לא יוכלו להשתמש בו להכנס ל- Cal.com.", "delete_sso_configuration_confirmation_description": "אתה בטוח שאתה רוצה למחוק את הגדרות {{connectionType}}? חברי הצוות שלך שמשתמשים ב- {{connectionType}} להזדהות לא יוכלו להשתמש בו להכנס ל- Cal.com.",
"organizer_timezone": "מארגן אזורי זמן", "organizer_timezone": "מארגן אזורי זמן",
"email_user_cta": "צפה בהזמנה", "email_user_cta": "צפה בהזמנה",
"email_no_user_invite_heading": "הוזמנת להצטרף ל{{entity}} של {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} הזמין אותך להצטרף לצוות שלו ב- {{appName}}. {{appName}} הינה מתזמן זימונים שמאפשר לך ולצוות שלך לזמן פגישות בלי כל הפינג פונג במיילים.", "email_no_user_invite_subheading": "{{invitedBy}} הזמין אותך להצטרף לצוות שלו ב- {{appName}}. {{appName}} הינה מתזמן זימונים שמאפשר לך ולצוות שלך לזמן פגישות בלי כל הפינג פונג במיילים.",
"email_user_invite_subheading": "{{invitedBy}} הזמין/ה אותך להצטרף ל-{{entity}} שלו/ה בשם ״{{teamName}}״ באפליקציה {{appName}}. אפליקציית {{appName}} היא כלי לקביעת מועדים לאירועים שמאפשר לך ול-{{entity}} שלך לתזמן פגישות בלי הצורך לנהל התכתבויות ארוכות בדוא״ל.", "email_user_invite_subheading_team": "{{invitedBy}} הזמין/ה אותך להצטרף לצוות שלו/ה בשם '{{teamName}}' באפליקציה {{appName}}. אפליקציית {{appName}} היא כלי לקביעת מועדים לאירועים שמאפשר לך ולצוות שלך לתזמן פגישות בלי כל הפינג פונג במיילים.",
"email_no_user_invite_steps_intro": "נדריך אותך במספר קטן של צעדים ותוכל/י להתחיל ליהנות מקביעת מועדים עם ה-{{entity}} שלך במהירות ובלי בעיות.", "email_no_user_invite_steps_intro": "נדריך אותך במספר קטן של צעדים ותוכל/י להתחיל ליהנות מקביעת מועדים עם ה-{{entity}} שלך במהירות ובלי בעיות.",
"email_no_user_step_one": "בחר שם משתמש", "email_no_user_step_one": "בחר שם משתמש",
"email_no_user_step_two": "קשר את לוח השנה שלך", "email_no_user_step_two": "קשר את לוח השנה שלך",
@@ -1878,7 +1877,6 @@
"first_event_type_webhook_description": "צור/צרי את ה-Webhook הראשון שלך עבור סוג האירוע הזה", "first_event_type_webhook_description": "צור/צרי את ה-Webhook הראשון שלך עבור סוג האירוע הזה",
"install_app_on": "התקנת האפליקציה ב-", "install_app_on": "התקנת האפליקציה ב-",
"create_for": "צור/צרי עבור", "create_for": "צור/צרי עבור",
"setup_organization": "הגדרת Organization",
"organization_banner_description": "צור/צרי סביבות שבהן הצוותים שלך יוכלו ליצור אפליקציות, תהליכי עבודה וסוגי אירועים משותפים, עם תכונות כמו סבב וקביעת מועדים שיתופית.", "organization_banner_description": "צור/צרי סביבות שבהן הצוותים שלך יוכלו ליצור אפליקציות, תהליכי עבודה וסוגי אירועים משותפים, עם תכונות כמו סבב וקביעת מועדים שיתופית.",
"organization_banner_title": "ניהול ארגונים עם צוותים מרובים", "organization_banner_title": "ניהול ארגונים עם צוותים מרובים",
"set_up_your_organization": "הגדרת הארגון שלך", "set_up_your_organization": "הגדרת הארגון שלך",
@@ -403,7 +403,7 @@
"recording_ready": "Il link per scaricare la registrazione è pronto", "recording_ready": "Il link per scaricare la registrazione è pronto",
"booking_created": "Prenotazione Creata", "booking_created": "Prenotazione Creata",
"booking_rejected": "Prenotazione Rifiutata", "booking_rejected": "Prenotazione Rifiutata",
"booking_requested": "Prenotazione Richiesta", "booking_requested": "Richiesta di prenotazione inviata",
"meeting_ended": "Riunione terminata", "meeting_ended": "Riunione terminata",
"form_submitted": "Modulo inviato", "form_submitted": "Modulo inviato",
"event_triggers": "Attivatori Evento", "event_triggers": "Attivatori Evento",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "Eliminare la configurazione {{connectionType}}? I membri del tuo team che utilizzano l'accesso {{connectionType}} non saranno più in grado di accedere a Cal.com.", "delete_sso_configuration_confirmation_description": "Eliminare la configurazione {{connectionType}}? I membri del tuo team che utilizzano l'accesso {{connectionType}} non saranno più in grado di accedere a Cal.com.",
"organizer_timezone": "Fuso orario organizzatore", "organizer_timezone": "Fuso orario organizzatore",
"email_user_cta": "Visualizza invito", "email_user_cta": "Visualizza invito",
"email_no_user_invite_heading": "Hai ricevuto un invito a partecipare a un/una {{entity}} di {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} ti ha invitato a unirti al suo team su {{appName}}. {{appName}} è uno strumento di pianificazione di eventi che permette al tuo team di pianificare le riunioni senza scambiare decine di e-mail.", "email_no_user_invite_subheading": "{{invitedBy}} ti ha invitato a unirti al suo team su {{appName}}. {{appName}} è uno strumento di pianificazione di eventi che permette al tuo team di pianificare le riunioni senza scambiare decine di e-mail.",
"email_user_invite_subheading": "{{invitedBy}} ti ha invitato a partecipare al/alla {{entity}} `{{teamName}}` su {{appName}}. {{appName}} è uno strumento di pianificazione di eventi che permette a te e al tuo/tua {{entity}} di pianificare le riunioni senza scambiarvi decine di e-mail.", "email_user_invite_subheading_team": "{{invitedBy}} ti ha invitato a unirti al suo team `{{teamName}}` su {{appName}}. {{appName}} è uno strumento di pianificazione di eventi che permette a te e al tuo team di pianificare le riunioni senza scambiare decine di e-mail.",
"email_no_user_invite_steps_intro": "Ti assisteremo nei passaggi iniziali e potrai rapidamente pianificare eventi per il/la {{entity}} senza fatica.", "email_no_user_invite_steps_intro": "Ti assisteremo nei passaggi iniziali e potrai rapidamente pianificare eventi per il/la {{entity}} senza fatica.",
"email_no_user_step_one": "Scegli il tuo nome utente", "email_no_user_step_one": "Scegli il tuo nome utente",
"email_no_user_step_two": "Collega il tuo account di calendario", "email_no_user_step_two": "Collega il tuo account di calendario",
@@ -1878,7 +1877,6 @@
"first_event_type_webhook_description": "Crea il primo webhook per questo tipo di evento", "first_event_type_webhook_description": "Crea il primo webhook per questo tipo di evento",
"install_app_on": "Installa l'app su", "install_app_on": "Installa l'app su",
"create_for": "Crea per", "create_for": "Crea per",
"setup_organization": "Imposta un'organizzazione",
"organization_banner_description": "Crea ambienti dove i tuoi team potranno creare e condividere applicazioni, flussi di lavoro e tipi di eventi con pianificazioni di gruppo e round robin.", "organization_banner_description": "Crea ambienti dove i tuoi team potranno creare e condividere applicazioni, flussi di lavoro e tipi di eventi con pianificazioni di gruppo e round robin.",
"organization_banner_title": "Gestisci organizzazioni con più team", "organization_banner_title": "Gestisci organizzazioni con più team",
"set_up_your_organization": "Imposta la tua organizzazione", "set_up_your_organization": "Imposta la tua organizzazione",
@@ -1889,7 +1887,7 @@
"admin_username": "Nome utente dell'amministratore", "admin_username": "Nome utente dell'amministratore",
"organization_name": "Nome dell'organizzazione", "organization_name": "Nome dell'organizzazione",
"organization_url": "URL dell'organizzazione", "organization_url": "URL dell'organizzazione",
"organization_verify_header": "Verifica l'e-mail della tua organizzazione", "organization_verify_header": "Verifica il tuo indirizzo e-mail",
"organization_verify_email_body": "Usa il codice sottostante per verificare il tuo indirizzo e-mail e proseguire la configurazione dell'organizzazione.", "organization_verify_email_body": "Usa il codice sottostante per verificare il tuo indirizzo e-mail e proseguire la configurazione dell'organizzazione.",
"additional_url_parameters": "Parametri aggiuntivi dell'URL", "additional_url_parameters": "Parametri aggiuntivi dell'URL",
"about_your_organization": "Informazioni sulla tua organizzazione", "about_your_organization": "Informazioni sulla tua organizzazione",
+10 -12
View File
@@ -306,7 +306,7 @@
"password_has_been_reset_login": "パスワードがリセットされました。新しく作成したパスワードでログインできるようになりました。", "password_has_been_reset_login": "パスワードがリセットされました。新しく作成したパスワードでログインできるようになりました。",
"layout": "レイアウト", "layout": "レイアウト",
"bookerlayout_default_title": "デフォルトの表示", "bookerlayout_default_title": "デフォルトの表示",
"bookerlayout_description": "複数のものを選択することができ、予約者は表示を切り替えることができます。", "bookerlayout_description": "複数のビューを選択することができ、予約者は表示を切り替えることができます。",
"bookerlayout_user_settings_title": "予約のレイアウト", "bookerlayout_user_settings_title": "予約のレイアウト",
"bookerlayout_user_settings_description": "複数のものを選択することができ、予約者は表示を切り替えることができます。これはイベントごとに上書きが可能です。", "bookerlayout_user_settings_description": "複数のものを選択することができ、予約者は表示を切り替えることができます。これはイベントごとに上書きが可能です。",
"bookerlayout_month_view": "月", "bookerlayout_month_view": "月",
@@ -391,7 +391,7 @@
"user_dynamic_booking_disabled": "グループ内の一部のユーザーは、現在動的なグループ予約を無効にしています", "user_dynamic_booking_disabled": "グループ内の一部のユーザーは、現在動的なグループ予約を無効にしています",
"allow_dynamic_booking_tooltip": "\"+\" を使って複数のユーザー名を追加することで動的に作成できるグループ予約リンク。例: \"{{appName}}/bailey+peer\"", "allow_dynamic_booking_tooltip": "\"+\" を使って複数のユーザー名を追加することで動的に作成できるグループ予約リンク。例: \"{{appName}}/bailey+peer\"",
"allow_dynamic_booking": "出席者が動的なグループ予約を通じてあなたを予約できるようにする", "allow_dynamic_booking": "出席者が動的なグループ予約を通じてあなたを予約できるようにする",
"dynamic_booking": "動的なグループリンク", "dynamic_booking": "ダイナミックグループリンク",
"email": "Eメールアドレス", "email": "Eメールアドレス",
"email_placeholder": "jdoe@example.com", "email_placeholder": "jdoe@example.com",
"full_name": "フルネーム", "full_name": "フルネーム",
@@ -555,7 +555,7 @@
"member": "メンバー", "member": "メンバー",
"number_member_one": "{{count}} 人のメンバー", "number_member_one": "{{count}} 人のメンバー",
"number_member_other": "{{count}} 人のメンバー", "number_member_other": "{{count}} 人のメンバー",
"number_selected": "{{count}} 件が選択されました", "number_selected": "{{count}} が選択されました",
"owner": "所有者", "owner": "所有者",
"admin": "管理者", "admin": "管理者",
"administrator_user": "管理者ユーザー", "administrator_user": "管理者ユーザー",
@@ -1150,8 +1150,8 @@
"choose_template": "テンプレートを選択する", "choose_template": "テンプレートを選択する",
"custom": "カスタム", "custom": "カスタム",
"reminder": "リマインダー", "reminder": "リマインダー",
"rescheduled": "スケジュール変更済み", "rescheduled": "スケジュールが変更されました",
"completed": "完了", "completed": "完了しました",
"reminder_email": "リマインダー:{{date}} の {{name}} との {{eventType}}", "reminder_email": "リマインダー:{{date}} の {{name}} との {{eventType}}",
"not_triggering_existing_bookings": "イベントの予約時に電話番号の入力を求められるため、すでにある予約はトリガーされません。", "not_triggering_existing_bookings": "イベントの予約時に電話番号の入力を求められるため、すでにある予約はトリガーされません。",
"minute_one": "{{count}} 分", "minute_one": "{{count}} 分",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "{{connectionType}} の構成を削除してもよろしいですか?{{connectionType}} でのログインを使用しているチームメンバーは、Cal.com にアクセスできなくなります。", "delete_sso_configuration_confirmation_description": "{{connectionType}} の構成を削除してもよろしいですか?{{connectionType}} でのログインを使用しているチームメンバーは、Cal.com にアクセスできなくなります。",
"organizer_timezone": "主催者のタイムゾーン", "organizer_timezone": "主催者のタイムゾーン",
"email_user_cta": "招待を表示", "email_user_cta": "招待を表示",
"email_no_user_invite_heading": "{{appName}} の {{entity}} への参加に招待されました",
"email_no_user_invite_subheading": "{{invitedBy}} は {{appName}} のチームに参加するようあなたを招待しました。{{appName}} は、イベント調整スケジューラーです。チームと延々とメールのやりとりをすることなくミーティングのスケジュール設定を行うことができます。", "email_no_user_invite_subheading": "{{invitedBy}} は {{appName}} のチームに参加するようあなたを招待しました。{{appName}} は、イベント調整スケジューラーです。チームと延々とメールのやりとりをすることなくミーティングのスケジュール設定を行うことができます。",
"email_user_invite_subheading": "{{invitedBy}} から {{appName}} の {{entity}} \"{{teamName}}\" に参加するよう招待されました。{{appName}} はイベント調整スケジューラーであり、{{entity}} 内で延々とメールのやりとりを続けることなくミーティングのスケジュールを設定できます。", "email_user_invite_subheading_team": "{{invitedBy}}から{{appName}}の「{{teamName}}」に参加するよう招待されました。{{appName}}はイベント調整スケジューラーで、チーム内で延々とメールのやりとりをすることなく、ミーティングのスケジュールを設定できます。",
"email_no_user_invite_steps_intro": "いくつかの短い手順を踏むだけで、すぐに {{entity}} のストレスフリーなスケジュール設定をお楽しみいただけます。", "email_no_user_invite_steps_intro": "いくつかの短い手順を踏むだけで、すぐに {{entity}} のストレスフリーなスケジュール設定をお楽しみいただけます。",
"email_no_user_step_one": "ユーザー名を選択", "email_no_user_step_one": "ユーザー名を選択",
"email_no_user_step_two": "カレンダーアカウントを接続", "email_no_user_step_two": "カレンダーアカウントを接続",
@@ -1673,7 +1672,7 @@
"scheduler": "{Scheduler}", "scheduler": "{Scheduler}",
"no_workflows": "ワークフローがありません", "no_workflows": "ワークフローがありません",
"change_filter": "個人やチームのワークフローを表示するためのフィルターを変更します。", "change_filter": "個人やチームのワークフローを表示するためのフィルターを変更します。",
"change_filter_common": "結果を表示するフィルターを変更します。", "change_filter_common": "フィルターを変更して結果を表示します。",
"no_results_for_filter": "このフィルターに該当する結果はありません", "no_results_for_filter": "このフィルターに該当する結果はありません",
"recommended_next_steps": "推奨される次のステップ", "recommended_next_steps": "推奨される次のステップ",
"create_a_managed_event": "管理されたイベントの種類を作成", "create_a_managed_event": "管理されたイベントの種類を作成",
@@ -1697,7 +1696,7 @@
"booking_questions_title": "予約の質問", "booking_questions_title": "予約の質問",
"booking_questions_description": "予約ページで尋ねる質問をカスタマイズする", "booking_questions_description": "予約ページで尋ねる質問をカスタマイズする",
"add_a_booking_question": "質問を追加", "add_a_booking_question": "質問を追加",
"identifier": "識別子", "identifier": "ID",
"duplicate_email": "メールが重複しています", "duplicate_email": "メールが重複しています",
"booking_with_payment_cancelled": "このイベントの支払いはもうできません", "booking_with_payment_cancelled": "このイベントの支払いはもうできません",
"booking_with_payment_cancelled_already_paid": "この予約に関するお支払いの払い戻しについては、現在処理中です。", "booking_with_payment_cancelled_already_paid": "この予約に関するお支払いの払い戻しについては、現在処理中です。",
@@ -1841,7 +1840,7 @@
"invite_link_copied": "招待リンクをコピーしました", "invite_link_copied": "招待リンクをコピーしました",
"invite_link_deleted": "招待リンクを削除しました", "invite_link_deleted": "招待リンクを削除しました",
"invite_link_updated": "招待リンクの設定を保存しました", "invite_link_updated": "招待リンクの設定を保存しました",
"link_expires_after": "リンクが期限切れとなるまで、あと...", "link_expires_after": "リンクの期限切れまで...",
"one_day": "1 日", "one_day": "1 日",
"seven_days": "7 日", "seven_days": "7 日",
"thirty_days": "30 日", "thirty_days": "30 日",
@@ -1878,7 +1877,6 @@
"first_event_type_webhook_description": "このイベントの種類の最初の Webhook を作成", "first_event_type_webhook_description": "このイベントの種類の最初の Webhook を作成",
"install_app_on": "次のアカウントにアプリをインストール", "install_app_on": "次のアカウントにアプリをインストール",
"create_for": "作成対象", "create_for": "作成対象",
"setup_organization": "組織をセットアップする",
"organization_banner_description": "チームがラウンドロビンスケジューリングや一括スケジューリングを活用して、共有アプリ、ワークフロー、イベントの種類を作成できる環境を作成します。", "organization_banner_description": "チームがラウンドロビンスケジューリングや一括スケジューリングを活用して、共有アプリ、ワークフロー、イベントの種類を作成できる環境を作成します。",
"organization_banner_title": "複数のチームを持つ組織を管理する", "organization_banner_title": "複数のチームを持つ組織を管理する",
"set_up_your_organization": "組織をセットアップする", "set_up_your_organization": "組織をセットアップする",
@@ -1938,7 +1936,7 @@
"insights_all_org_filter": "すべて", "insights_all_org_filter": "すべて",
"insights_team_filter": "チーム: {{teamName}}", "insights_team_filter": "チーム: {{teamName}}",
"insights_user_filter": "ユーザー: {{userName}}", "insights_user_filter": "ユーザー: {{userName}}",
"insights_subtitle": "イベント全体での予約に関する分析情報を表示する", "insights_subtitle": "イベント全体での予約に関する Insights を表示する",
"custom_plan": "カスタムプラン", "custom_plan": "カスタムプラン",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ この上に新しい文字列を追加してください ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ この上に新しい文字列を追加してください ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -21,7 +21,7 @@
"verify_email_email_link_text": "버튼 클릭이 마음에 들지 않는 경우 다음 링크를 사용하세요.", "verify_email_email_link_text": "버튼 클릭이 마음에 들지 않는 경우 다음 링크를 사용하세요.",
"email_sent": "이메일이 성공적으로 전송되었습니다", "email_sent": "이메일이 성공적으로 전송되었습니다",
"event_declined_subject": "거절됨: {{date}} {{title}}", "event_declined_subject": "거절됨: {{date}} {{title}}",
"event_cancelled_subject": "취소됨: {{title}} 날짜 {{date}}", "event_cancelled_subject": "취소됨: {{title}}, 날짜 {{date}}",
"event_request_declined": "회의 요청이 거절되었습니다.", "event_request_declined": "회의 요청이 거절되었습니다.",
"event_request_declined_recurring": "되풀이 이벤트 요청이 거부되었습니다", "event_request_declined_recurring": "되풀이 이벤트 요청이 거부되었습니다",
"event_request_cancelled": "예약된 일정이 취소되었습니다", "event_request_cancelled": "예약된 일정이 취소되었습니다",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "{{connectionType}} 구성을 삭제하시겠습니까? {{connectionType}} 로그인을 사용하는 팀원은 더 이상 Cal.com에 액세스할 수 없습니다.", "delete_sso_configuration_confirmation_description": "{{connectionType}} 구성을 삭제하시겠습니까? {{connectionType}} 로그인을 사용하는 팀원은 더 이상 Cal.com에 액세스할 수 없습니다.",
"organizer_timezone": "주최자 시간대", "organizer_timezone": "주최자 시간대",
"email_user_cta": "초대 보기", "email_user_cta": "초대 보기",
"email_no_user_invite_heading": "{{appName}} {{entity}}에 참여 초대를 받으셨습니다",
"email_no_user_invite_subheading": "{{invitedBy}} 님이 귀하를 {{appName}}에서 자신의 팀에 초대했습니다. {{appName}} 앱은 귀하와 귀하의 팀이 이메일을 주고 받지 않고 회의 일정을 잡을 수 있게 해주는 이벤트 정리 스케줄러입니다.", "email_no_user_invite_subheading": "{{invitedBy}} 님이 귀하를 {{appName}}에서 자신의 팀에 초대했습니다. {{appName}} 앱은 귀하와 귀하의 팀이 이메일을 주고 받지 않고 회의 일정을 잡을 수 있게 해주는 이벤트 정리 스케줄러입니다.",
"email_user_invite_subheading": "{{invitedBy}} 님이 {{appName}}에서 자신의 {{entity}} `{{teamName}}`에 귀하의 참여를 초대했습니다. {{appName}}은(는) 사용자와 {{entity}}이(가) 이메일을 주고 받지 않고도 회의 일정을 잡을 수 있게 해주는 이벤트 조정 스케줄러입니다.", "email_user_invite_subheading_team": "{{invitedBy}}님이 {{appName}}에서 자신의 `{{teamName}}` 팀에 가입하도록 당신을 초대했습니다. {{appName}}은 유저와 팀이 이메일을 주고 받지 않고도 회의 일정을 잡을 수 있게 하는 이벤트 조율 스케줄러입니다.",
"email_no_user_invite_steps_intro": "안내해 드릴 몇 가지 간단한 단계만 거치면 곧 스트레스 없이 편리하게 {{entity}} 일정을 관리할 수 있게 될 것입니다.", "email_no_user_invite_steps_intro": "안내해 드릴 몇 가지 간단한 단계만 거치면 곧 스트레스 없이 편리하게 {{entity}} 일정을 관리할 수 있게 될 것입니다.",
"email_no_user_step_one": "사용자 이름 선택", "email_no_user_step_one": "사용자 이름 선택",
"email_no_user_step_two": "캘린더 계정 연결", "email_no_user_step_two": "캘린더 계정 연결",
@@ -1878,7 +1877,6 @@
"first_event_type_webhook_description": "이 이벤트 유형에 대한 첫 번째 웹훅 만들기", "first_event_type_webhook_description": "이 이벤트 유형에 대한 첫 번째 웹훅 만들기",
"install_app_on": "앱 설치 대상", "install_app_on": "앱 설치 대상",
"create_for": "작성 대상", "create_for": "작성 대상",
"setup_organization": "조직 설정",
"organization_banner_description": "팀이 라운드 로빈 및 공동 예약을 통해 공유 앱, 워크플로 및 이벤트 유형을 생성할 수 있는 환경을 만듭니다.", "organization_banner_description": "팀이 라운드 로빈 및 공동 예약을 통해 공유 앱, 워크플로 및 이벤트 유형을 생성할 수 있는 환경을 만듭니다.",
"organization_banner_title": "여러 팀으로 조직 관리", "organization_banner_title": "여러 팀으로 조직 관리",
"set_up_your_organization": "조직 설정", "set_up_your_organization": "조직 설정",
@@ -1663,9 +1663,8 @@
"delete_sso_configuration_confirmation_description": "Weet u zeker dat u de {{connectionType}}-configuratie wilt verwijderen? Uw teamleden die {{connectionType}}-aanmelding gebruiken hebben niet langer toegang tot Cal.com.", "delete_sso_configuration_confirmation_description": "Weet u zeker dat u de {{connectionType}}-configuratie wilt verwijderen? Uw teamleden die {{connectionType}}-aanmelding gebruiken hebben niet langer toegang tot Cal.com.",
"organizer_timezone": "Tijdzone organisator", "organizer_timezone": "Tijdzone organisator",
"email_user_cta": "Uitnodiging weergeven", "email_user_cta": "Uitnodiging weergeven",
"email_no_user_invite_heading": "U bent uitgenodigd om lid te worden van {{appName}} {{entity}}",
"email_no_user_invite_subheading": "{{invitedBy}} heeft u uitgenodigd om lid te worden van zijn team op {{appName}}. {{appName}} is de gebeurtenissenplanner die u en uw team in staat stelt vergaderingen te plannen zonder heen en weer te e-mailen.", "email_no_user_invite_subheading": "{{invitedBy}} heeft u uitgenodigd om lid te worden van zijn team op {{appName}}. {{appName}} is de gebeurtenissenplanner die u en uw team in staat stelt vergaderingen te plannen zonder heen en weer te e-mailen.",
"email_user_invite_subheading": "{{invitedBy}} heeft u uitgenodigd om lid te worden van zijn {{entity}} '{{teamName}}' op {{appName}}. {{appName}} is de gebeurtenissenplanner die u en uw {{entity}} in staat stelt afspraken te plannen zonder heen en weer te e-mailen.", "email_user_invite_subheading_team": "{{invitedBy}} heeft u uitgenodigd om lid te worden van zijn team '{{teamName}}' op {{appName}}. {{appName}} is de gebeurtenissenplanner die u en uw team in staat stelt afspraken te plannen zonder heen en weer te e-mailen.",
"email_no_user_invite_steps_intro": "We doorlopen samen een paar korte stappen en in een mum van tijd kunt u genieten van een stressvrije planning met uw {{entity}}.", "email_no_user_invite_steps_intro": "We doorlopen samen een paar korte stappen en in een mum van tijd kunt u genieten van een stressvrije planning met uw {{entity}}.",
"email_no_user_step_one": "Kies uw gebruikersnaam", "email_no_user_step_one": "Kies uw gebruikersnaam",
"email_no_user_step_two": "Koppel uw agenda-account", "email_no_user_step_two": "Koppel uw agenda-account",
@@ -1885,7 +1884,6 @@
"first_event_type_webhook_description": "Maak uw eerste webhook voor dit gebeurtenistype", "first_event_type_webhook_description": "Maak uw eerste webhook voor dit gebeurtenistype",
"install_app_on": "App installeren op", "install_app_on": "App installeren op",
"create_for": "Maken voor", "create_for": "Maken voor",
"setup_organization": "Een organisatie instellen",
"organization_banner_description": "Maak een omgeving waarin uw teams gedeelde apps, werkstromen en gebeurtenistypen kunnen maken met round-robin en collectieve planning.", "organization_banner_description": "Maak een omgeving waarin uw teams gedeelde apps, werkstromen en gebeurtenistypen kunnen maken met round-robin en collectieve planning.",
"organization_banner_title": "Beheer organisaties met meerdere teams", "organization_banner_title": "Beheer organisaties met meerdere teams",
"set_up_your_organization": "Stel uw organisatie in", "set_up_your_organization": "Stel uw organisatie in",
@@ -12,7 +12,7 @@
"have_any_questions": "Masz pytania? Jesteśmy tutaj, aby pomóc.", "have_any_questions": "Masz pytania? Jesteśmy tutaj, aby pomóc.",
"reset_password_subject": "{{appName}}: Instrukcje resetowania hasła", "reset_password_subject": "{{appName}}: Instrukcje resetowania hasła",
"verify_email_subject": "{{appName}}: zweryfikuj swoje konto", "verify_email_subject": "{{appName}}: zweryfikuj swoje konto",
"check_your_email": "Sprawdź swój adres e-mail", "check_your_email": "Sprawdź swoją pocztę e-mail",
"verify_email_page_body": "Wysłaliśmy wiadomość e-mail na adres {{email}}. Weryfikacja adresu e-mail jest ważna, ponieważ umożliwia zagwarantowanie prawidłowego działania kalendarza i dostarczania wiadomości e-mail z aplikacji {{appName}}.", "verify_email_page_body": "Wysłaliśmy wiadomość e-mail na adres {{email}}. Weryfikacja adresu e-mail jest ważna, ponieważ umożliwia zagwarantowanie prawidłowego działania kalendarza i dostarczania wiadomości e-mail z aplikacji {{appName}}.",
"verify_email_banner_body": "Potwierdź adres e-mail, aby upewnić się, że wiadomości e-mail i powiadomienia z kalendarza będą do Ciebie docierać.", "verify_email_banner_body": "Potwierdź adres e-mail, aby upewnić się, że wiadomości e-mail i powiadomienia z kalendarza będą do Ciebie docierać.",
"verify_email_email_header": "Zweryfikuj swój adres e-mail", "verify_email_email_header": "Zweryfikuj swój adres e-mail",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "Czy na pewno chcesz usunąć konfigurację {{connectionType}}? Członkowie zespołu, którzy używają logowania {{connectionType}} nie będą już mogli uzyskać dostępu do Cal.com.", "delete_sso_configuration_confirmation_description": "Czy na pewno chcesz usunąć konfigurację {{connectionType}}? Członkowie zespołu, którzy używają logowania {{connectionType}} nie będą już mogli uzyskać dostępu do Cal.com.",
"organizer_timezone": "Strefa czasowa organizatora", "organizer_timezone": "Strefa czasowa organizatora",
"email_user_cta": "Wyświetl zaproszenie", "email_user_cta": "Wyświetl zaproszenie",
"email_no_user_invite_heading": "Zaproszono Cię do dołączenia do aplikacji {{appName}} ({{entity}})",
"email_no_user_invite_subheading": "Użytkownik {{invitedBy}} zaprasza Cię do dołączenia do jego zespołu w aplikacji {{appName}}. Aplikacja {{appName}} to terminarz do planowania wydarzeń, który umożliwi Tobie i Twojemu zespołowi planowanie spotkań bez czasochłonnej wymiany wiadomości e-mail.", "email_no_user_invite_subheading": "Użytkownik {{invitedBy}} zaprasza Cię do dołączenia do jego zespołu w aplikacji {{appName}}. Aplikacja {{appName}} to terminarz do planowania wydarzeń, który umożliwi Tobie i Twojemu zespołowi planowanie spotkań bez czasochłonnej wymiany wiadomości e-mail.",
"email_user_invite_subheading": "{{invitedBy}} zaprasza Cię do dołączenia do: {{entity}} „{{teamName}}” w aplikacji {{appName}}. Aplikacja {{appName}} to terminarz do planowania wydarzeń, który umożliwi {{entity}} planowanie spotkań bez czasochłonnej wymiany wiadomości e-mail.", "email_user_invite_subheading_team": "Użytkownik {{invitedBy}} zaprasza Cię do dołączenia do jego zespołu „{{teamName}}” w aplikacji {{appName}}. Aplikacja {{appName}} to terminarz do planowania wydarzeń, który umożliwi Tobie i Twojemu zespołowi planowanie spotkań bez czasochłonnej wymiany wiadomości e-mail.",
"email_no_user_invite_steps_intro": "Przeprowadzimy Cię przez kilka krótkich kroków i wkrótce w ramach {{entity}} zaczniesz z przyjemnością korzystać z bezstresowego planowania.", "email_no_user_invite_steps_intro": "Przeprowadzimy Cię przez kilka krótkich kroków i wkrótce w ramach {{entity}} zaczniesz z przyjemnością korzystać z bezstresowego planowania.",
"email_no_user_step_one": "Wybierz nazwę użytkownika", "email_no_user_step_one": "Wybierz nazwę użytkownika",
"email_no_user_step_two": "Połącz swoje konto kalendarza", "email_no_user_step_two": "Połącz swoje konto kalendarza",
@@ -1878,7 +1877,6 @@
"first_event_type_webhook_description": "Utwórz swój pierwszy element webhook dla tego typu wydarzenia", "first_event_type_webhook_description": "Utwórz swój pierwszy element webhook dla tego typu wydarzenia",
"install_app_on": "Zainstaluj aplikację na koncie", "install_app_on": "Zainstaluj aplikację na koncie",
"create_for": "Utwórz dla", "create_for": "Utwórz dla",
"setup_organization": "Skonfiguruj organizację",
"organization_banner_description": "Utwórz środowisko, w którym zespoły będą mogły tworzyć wspólne aplikacje, przepływy pracy i typy wydarzeń przy użyciu algorytmu karuzelowego lub zbiorowego ustalania harmonogramu.", "organization_banner_description": "Utwórz środowisko, w którym zespoły będą mogły tworzyć wspólne aplikacje, przepływy pracy i typy wydarzeń przy użyciu algorytmu karuzelowego lub zbiorowego ustalania harmonogramu.",
"organization_banner_title": "Zarządzaj organizacjami z wieloma zespołami", "organization_banner_title": "Zarządzaj organizacjami z wieloma zespołami",
"set_up_your_organization": "Skonfiguruj swoją organizację", "set_up_your_organization": "Skonfiguruj swoją organizację",
@@ -1889,7 +1887,7 @@
"admin_username": "Nazwa użytkownika administratora", "admin_username": "Nazwa użytkownika administratora",
"organization_name": "Nazwa organizacji", "organization_name": "Nazwa organizacji",
"organization_url": "Adres URL organizacji", "organization_url": "Adres URL organizacji",
"organization_verify_header": "Zweryfikuj adres e-mail swojej organizacji", "organization_verify_header": "Zweryfikuj swój adres e-mail w organizacji",
"organization_verify_email_body": "Użyj poniższego kodu, aby zweryfikować adres e-mail i kontynuować konfigurację swojej organizacji.", "organization_verify_email_body": "Użyj poniższego kodu, aby zweryfikować adres e-mail i kontynuować konfigurację swojej organizacji.",
"additional_url_parameters": "Dodatkowe parametry adresu URL", "additional_url_parameters": "Dodatkowe parametry adresu URL",
"about_your_organization": "Informacje o Twojej organizacji", "about_your_organization": "Informacje o Twojej organizacji",
@@ -1675,9 +1675,8 @@
"delete_sso_configuration_confirmation_description": "Você tem certeza que deseja remover a configuração de {{connectionType}}? Os membros do seu time que utilizam {{connectionType}} para fazer login não conseguirão acessar o Cal.com.", "delete_sso_configuration_confirmation_description": "Você tem certeza que deseja remover a configuração de {{connectionType}}? Os membros do seu time que utilizam {{connectionType}} para fazer login não conseguirão acessar o Cal.com.",
"organizer_timezone": "Fuso horário do organizador", "organizer_timezone": "Fuso horário do organizador",
"email_user_cta": "Ver convite", "email_user_cta": "Ver convite",
"email_no_user_invite_heading": "Você recebeu um convite para ingressar em {{entity}} de {{appName}}",
"email_no_user_invite_subheading": "Você recebeu um convite de {{invitedBy}} para ingressar em sua equipe em {{appName}}. {{appName}} é um agendador que concilia eventos e permite que sua equipe agende reuniões sem precisar trocar e-mails.", "email_no_user_invite_subheading": "Você recebeu um convite de {{invitedBy}} para ingressar em sua equipe em {{appName}}. {{appName}} é um agendador que concilia eventos e permite que sua equipe agende reuniões sem precisar trocar e-mails.",
"email_user_invite_subheading": "Você recebeu um convite de {{invitedBy}} para ingressar na equipe \"{{teamName}}\" de {{entity}} em {{appName}}. {{appName}} é um agendador que concilia eventos e permite que {{entity}} agende reuniões sem precisar trocar e-mails.", "email_user_invite_subheading_team": "Você recebeu um convite de {{invitedBy}} para ingressar na equipe \"{{teamName}}\" em {{appName}}. {{appName}} é um agendador que concilia eventos e permite que sua equipe agende reuniões sem precisar trocar e-mails.",
"email_no_user_invite_steps_intro": "Orientaremos ao longo de alguns passos rápidos para que você comece logo a agendar eventos com {{entity}} sem preocupação.", "email_no_user_invite_steps_intro": "Orientaremos ao longo de alguns passos rápidos para que você comece logo a agendar eventos com {{entity}} sem preocupação.",
"email_no_user_step_one": "Escolha seu nome de usuário", "email_no_user_step_one": "Escolha seu nome de usuário",
"email_no_user_step_two": "Conecte com sua conta de calendário", "email_no_user_step_two": "Conecte com sua conta de calendário",
@@ -1898,7 +1897,6 @@
"install_app_on": "Instalar aplicativo em", "install_app_on": "Instalar aplicativo em",
"create_for": "Criar para", "create_for": "Criar para",
"currency": "Moeda", "currency": "Moeda",
"setup_organization": "Definir uma Organização",
"organization_banner_description": "Crie um ambiente onde suas equipes podem criar tipos de evento, fluxos de trabalho e aplicativos compartilhados com agendamento coletivo e round robin.", "organization_banner_description": "Crie um ambiente onde suas equipes podem criar tipos de evento, fluxos de trabalho e aplicativos compartilhados com agendamento coletivo e round robin.",
"organization_banner_title": "Gerenciar organizações com múltiplas equipes", "organization_banner_title": "Gerenciar organizações com múltiplas equipes",
"set_up_your_organization": "Configurar sua organização", "set_up_your_organization": "Configurar sua organização",
@@ -12,7 +12,7 @@
"have_any_questions": "Tem perguntas? Estamos disponíveis para ajudar.", "have_any_questions": "Tem perguntas? Estamos disponíveis para ajudar.",
"reset_password_subject": "{{appName}}: Instruções de redefinição da senha", "reset_password_subject": "{{appName}}: Instruções de redefinição da senha",
"verify_email_subject": "{{appName}}: Verifique a sua conta", "verify_email_subject": "{{appName}}: Verifique a sua conta",
"check_your_email": "Confirme o seu e-mail", "check_your_email": "Verifique o seu e-mail",
"verify_email_page_body": "Enviámos um e-mail para {{email}}. É importante verificar o seu endereço de e-mail para garantir que receberá as comunicações de {{appName}}.", "verify_email_page_body": "Enviámos um e-mail para {{email}}. É importante verificar o seu endereço de e-mail para garantir que receberá as comunicações de {{appName}}.",
"verify_email_banner_body": "Confirme o seu endereço de e-mail para garantir a melhor entrega possível de e-mail e de agenda", "verify_email_banner_body": "Confirme o seu endereço de e-mail para garantir a melhor entrega possível de e-mail e de agenda",
"verify_email_email_header": "Confirme o seu endereço de e-mail", "verify_email_email_header": "Confirme o seu endereço de e-mail",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "Tem a certeza que pretende eliminar a configuração {{connectionType}}? Os membros da sua equipa que utilizem {{connectionType}} para o início de sessão deixarão de poder aceder a Cal.com.", "delete_sso_configuration_confirmation_description": "Tem a certeza que pretende eliminar a configuração {{connectionType}}? Os membros da sua equipa que utilizem {{connectionType}} para o início de sessão deixarão de poder aceder a Cal.com.",
"organizer_timezone": "Fuso horário do organizador", "organizer_timezone": "Fuso horário do organizador",
"email_user_cta": "Ver convite", "email_user_cta": "Ver convite",
"email_no_user_invite_heading": "Foi convidado para se juntar a um {{entity}} {{appName}}",
"email_no_user_invite_subheading": "Recebeu um convite de {{invitedBy}} para fazer parte da respetiva equipa em {{appName}}. {{appName}} é um ferramenta de conciliação e agendamento de eventos que lhe permite a si e à sua equipa agendar reuniões sem o pingue-pongue de e-mails.", "email_no_user_invite_subheading": "Recebeu um convite de {{invitedBy}} para fazer parte da respetiva equipa em {{appName}}. {{appName}} é um ferramenta de conciliação e agendamento de eventos que lhe permite a si e à sua equipa agendar reuniões sem o pingue-pongue de e-mails.",
"email_user_invite_subheading": "Recebeu um convite de {{invitedBy}} para fazer parte da sua {{entity}} `{{teamName}}` em {{appName}}. {{appName}} é uma ferramenta de conciliação e agendamento de eventos que lhe permite a si e à sua {{entity}} agendar reuniões sem o pingue-pongue de mensagens eletrónicas.", "email_user_invite_subheading_team": "Recebeu um convite de {{invitedBy}} para fazer parte da equipa `{{teamName}}` em {{appName}}. {{appName}} é uma ferramenta de conciliação e agendamento de eventos que lhe permite a si e à sua equipa agendar reuniões sem o pingue-pongue de mensagens eletrónicas.",
"email_no_user_invite_steps_intro": "Vamos ajudar com alguns pequenos passos para que você e a sua {{entity}} possam desfrutar rapidamente de uma gestão de agendamentos sem complicações.", "email_no_user_invite_steps_intro": "Vamos ajudar com alguns pequenos passos para que você e a sua {{entity}} possam desfrutar rapidamente de uma gestão de agendamentos sem complicações.",
"email_no_user_step_one": "Escolha o seu nome de utilizador", "email_no_user_step_one": "Escolha o seu nome de utilizador",
"email_no_user_step_two": "Associe a sua conta de calendário", "email_no_user_step_two": "Associe a sua conta de calendário",
@@ -1878,7 +1877,6 @@
"first_event_type_webhook_description": "Crie o seu primeiro webhook para este tipo de evento", "first_event_type_webhook_description": "Crie o seu primeiro webhook para este tipo de evento",
"install_app_on": "Instalar aplicação em", "install_app_on": "Instalar aplicação em",
"create_for": "Criar para", "create_for": "Criar para",
"setup_organization": "Configurar uma Organização",
"organization_banner_description": "Crie um ambiente onde as suas equipas possam criar aplicações partilhadas, fluxos de trabalho e tipos de eventos com distribuição equilibrada e agendamento coletivo.", "organization_banner_description": "Crie um ambiente onde as suas equipas possam criar aplicações partilhadas, fluxos de trabalho e tipos de eventos com distribuição equilibrada e agendamento coletivo.",
"organization_banner_title": "Faça a gestão de múltiplas organizações com múltiplas equipas", "organization_banner_title": "Faça a gestão de múltiplas organizações com múltiplas equipas",
"set_up_your_organization": "Configurar a sua organização", "set_up_your_organization": "Configurar a sua organização",
@@ -118,7 +118,7 @@
"team_info": "Informații echipă", "team_info": "Informații echipă",
"request_another_invitation_email": "Dacă preferați să nu utilizați {{toEmail}} ca e-mail {{appName}} sau aveți deja un cont {{appName}}, vă rugăm să solicitați o altă invitație la acel e-mail.", "request_another_invitation_email": "Dacă preferați să nu utilizați {{toEmail}} ca e-mail {{appName}} sau aveți deja un cont {{appName}}, vă rugăm să solicitați o altă invitație la acel e-mail.",
"you_have_been_invited": "Ați fost invitat să vă alăturați echipei {{teamName}}", "you_have_been_invited": "Ați fost invitat să vă alăturați echipei {{teamName}}",
"user_invited_you": "{{user}} v-a invitat să faceți parte din {{entity}} {{team}} de pe {{appName}}", "user_invited_you": "{{user}} v-a invitat să faceți parte din {{entity}} {{team}} pe {{appName}}",
"hidden_team_member_title": "Sunteți ascuns în această echipă", "hidden_team_member_title": "Sunteți ascuns în această echipă",
"hidden_team_member_message": "Licența dvs. nu este plătită. Fie faceți upgrade la Pro, fie anunțați proprietarul echipei că vă poate plăti licența.", "hidden_team_member_message": "Licența dvs. nu este plătită. Fie faceți upgrade la Pro, fie anunțați proprietarul echipei că vă poate plăti licența.",
"hidden_team_owner_message": "Aveți nevoie de un cont Pro pentru a utiliza echipe. Sunteți ascuns până când faceți upgrade.", "hidden_team_owner_message": "Aveți nevoie de un cont Pro pentru a utiliza echipe. Sunteți ascuns până când faceți upgrade.",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "Sigur doriți să ștergeți configurația {{connectionType}}? Membrii echipei dvs. care utilizează conectarea prin {{connectionType}} nu vor mai putea accesa Cal.com.", "delete_sso_configuration_confirmation_description": "Sigur doriți să ștergeți configurația {{connectionType}}? Membrii echipei dvs. care utilizează conectarea prin {{connectionType}} nu vor mai putea accesa Cal.com.",
"organizer_timezone": "Fusul orar al organizatorului", "organizer_timezone": "Fusul orar al organizatorului",
"email_user_cta": "Vizualizare invitație", "email_user_cta": "Vizualizare invitație",
"email_no_user_invite_heading": "Ați fost invitat să faceți parte dintr-o {{entity}} {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} v-a invitat să faceți parte din echipa sa de pe {{appName}}. {{appName}} este un instrument de planificare a evenimentelor, care vă permite dvs. și echipei dvs. să programați ședințe fără a face ping-pong prin e-mail.", "email_no_user_invite_subheading": "{{invitedBy}} v-a invitat să faceți parte din echipa sa de pe {{appName}}. {{appName}} este un instrument de planificare a evenimentelor, care vă permite dvs. și echipei dvs. să programați ședințe fără a face ping-pong prin e-mail.",
"email_user_invite_subheading": "{{invitedBy}} v-a invitat să faceți parte din {{entity}} „{{teamName}}” de pe {{appName}}. {{appName}} este un instrument de planificare a evenimentelor, prin care dvs. și {{entity}} dvs. puteți să programați ședințe fără a face ping-pong prin e-mail.", "email_user_invite_subheading_team": "{{invitedBy}} v-a invitat să faceți parte din echipa sa „{{teamName}}” de pe {{appName}}. {{appName}} este un instrument de planificare a evenimentelor, care vă permite dvs. și echipei dvs. să programați ședințe fără a face ping-pong prin e-mail.",
"email_no_user_invite_steps_intro": "Vom parcurge împreună câțiva pași simpli și vă veți bucura alături de {{entity}} dvs. de programări fără probleme, în cel mai scurt timp.", "email_no_user_invite_steps_intro": "Vom parcurge împreună câțiva pași simpli și vă veți bucura alături de {{entity}} dvs. de programări fără probleme, în cel mai scurt timp.",
"email_no_user_step_one": "Alegeți-vă numele de utilizator", "email_no_user_step_one": "Alegeți-vă numele de utilizator",
"email_no_user_step_two": "Conectați-vă contul de calendar", "email_no_user_step_two": "Conectați-vă contul de calendar",
@@ -1878,7 +1877,6 @@
"first_event_type_webhook_description": "Creați primul dvs. webhook pentru acest tip de eveniment", "first_event_type_webhook_description": "Creați primul dvs. webhook pentru acest tip de eveniment",
"install_app_on": "Instalați aplicația în", "install_app_on": "Instalați aplicația în",
"create_for": "Creare pentru", "create_for": "Creare pentru",
"setup_organization": "Configurarați o organizație",
"organization_banner_description": "Dezvoltați medii în care echipele dvs. să poată crea aplicații, fluxuri de lucru și tipuri de evenimente comune, folosind programarea colectivă sau cu alocare prin rotație.", "organization_banner_description": "Dezvoltați medii în care echipele dvs. să poată crea aplicații, fluxuri de lucru și tipuri de evenimente comune, folosind programarea colectivă sau cu alocare prin rotație.",
"organization_banner_title": "Gestionați organizații cu mai multe echipe", "organization_banner_title": "Gestionați organizații cu mai multe echipe",
"set_up_your_organization": "Configurați organizația", "set_up_your_organization": "Configurați organizația",
@@ -118,7 +118,7 @@
"team_info": "Информация о команде", "team_info": "Информация о команде",
"request_another_invitation_email": "Если вы не хотите использовать {{toEmail}} как ваш {{appName}} адрес электронной почты или уже есть аккаунт {{appName}}, пожалуйста, запросите другое приглашение на это письмо.", "request_another_invitation_email": "Если вы не хотите использовать {{toEmail}} как ваш {{appName}} адрес электронной почты или уже есть аккаунт {{appName}}, пожалуйста, запросите другое приглашение на это письмо.",
"you_have_been_invited": "Вас пригласили присоединиться к команде {{teamName}}", "you_have_been_invited": "Вас пригласили присоединиться к команде {{teamName}}",
"user_invited_you": "{{user}} пригласил вас в команду {{entity}} {{team}} в {{appName}}", "user_invited_you": "{{user}} пригласил вас в команду {{team}} {{entity}} в {{appName}}",
"hidden_team_member_title": "В этой команде вы скрытый пользователь", "hidden_team_member_title": "В этой команде вы скрытый пользователь",
"hidden_team_member_message": "Ваше место не оплачено. Перейдите на аккаунт PRO или свяжитесь с руководителем команды, чтобы сообщить ему, что он может оплатить ваше место.", "hidden_team_member_message": "Ваше место не оплачено. Перейдите на аккаунт PRO или свяжитесь с руководителем команды, чтобы сообщить ему, что он может оплатить ваше место.",
"hidden_team_owner_message": "Чтобы работать с командами, необходим аккаунт Pro. До перехода на этот тариф Вы остаетесь скрытым пользователем.", "hidden_team_owner_message": "Чтобы работать с командами, необходим аккаунт Pro. До перехода на этот тариф Вы остаетесь скрытым пользователем.",
@@ -403,7 +403,7 @@
"recording_ready": "Ссылка для скачивания записи готова", "recording_ready": "Ссылка для скачивания записи готова",
"booking_created": "Бронирование создано", "booking_created": "Бронирование создано",
"booking_rejected": "Бронирование отклонено", "booking_rejected": "Бронирование отклонено",
"booking_requested": "Поступил запрос на бронирование", "booking_requested": "Запрос на бронирование отправлен",
"meeting_ended": "Встреча завершилась", "meeting_ended": "Встреча завершилась",
"form_submitted": "Форма отправлена", "form_submitted": "Форма отправлена",
"event_triggers": "Триггеры событий", "event_triggers": "Триггеры событий",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "Удалить конфигурацию {{connectionType}}? Участники команды, входящие в Cal.com через {{connectionType}}, больше не смогут получить к нему доступ.", "delete_sso_configuration_confirmation_description": "Удалить конфигурацию {{connectionType}}? Участники команды, входящие в Cal.com через {{connectionType}}, больше не смогут получить к нему доступ.",
"organizer_timezone": "Часовой пояс организатора", "organizer_timezone": "Часовой пояс организатора",
"email_user_cta": "Посмотреть приглашение", "email_user_cta": "Посмотреть приглашение",
"email_no_user_invite_heading": "Вас пригласили в {{entity}} {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} пригласил(-а) вас в команду в {{appName}}. {{appName}} — это гибкий планировщик событий, с помощью которого пользователи и целые команды могут планировать встречи без утомительной переписки по электронной почте.", "email_no_user_invite_subheading": "{{invitedBy}} пригласил(-а) вас в команду в {{appName}}. {{appName}} — это гибкий планировщик событий, с помощью которого пользователи и целые команды могут планировать встречи без утомительной переписки по электронной почте.",
"email_user_invite_subheading": "{{invitedBy}} пригласил(-а) вас в {{entity}} `{{teamName}}` в {{appName}}. {{appName}} — это гибкий планировщик событий, с помощью которого вы и ваша {{entity}} можете планировать встречи без утомительной переписки по электронной почте.", "email_user_invite_subheading_team": "{{invitedBy}} пригласил(а) вас в команду в `{{teamName}}` в приложении {{appName}}. {{appName}} — это гибкий планировщик событий, с помощью которого пользователи и целые команды могут планировать встречи без утомительной переписки по электронной почте.",
"email_no_user_invite_steps_intro": "Всего несколько шагов — и вы сможете оперативно и без стресса планировать встречи в рамках вашей {{entity}}.", "email_no_user_invite_steps_intro": "Всего несколько шагов — и вы сможете оперативно и без стресса планировать встречи в рамках вашей {{entity}}.",
"email_no_user_step_one": "Выберите имя пользователя", "email_no_user_step_one": "Выберите имя пользователя",
"email_no_user_step_two": "Подключите аккаунт календаря", "email_no_user_step_two": "Подключите аккаунт календаря",
@@ -1878,10 +1877,9 @@
"first_event_type_webhook_description": "Создайте первый вебхук для этого типа событий", "first_event_type_webhook_description": "Создайте первый вебхук для этого типа событий",
"install_app_on": "Установить приложение в", "install_app_on": "Установить приложение в",
"create_for": "Создать для", "create_for": "Создать для",
"setup_organization": "Настроите организацию",
"organization_banner_description": "Создавайте рабочие среды, в рамках которых ваши команды смогут создавать общие приложения, рабочие процессы и типы событий с назначением участников по очереди и коллективным планированием.", "organization_banner_description": "Создавайте рабочие среды, в рамках которых ваши команды смогут создавать общие приложения, рабочие процессы и типы событий с назначением участников по очереди и коллективным планированием.",
"organization_banner_title": "Управляйте организациями с несколькими командами", "organization_banner_title": "Управляйте организациями с несколькими командами",
"set_up_your_organization": "Настройте организацию", "set_up_your_organization": "Настройка профиля организации",
"organizations_description": "Организация — это общая рабочая среда, в которой команды могут создавать общие типы событий, приложения, рабочие процессы и многое другое.", "organizations_description": "Организация — это общая рабочая среда, в которой команды могут создавать общие типы событий, приложения, рабочие процессы и многое другое.",
"must_enter_organization_name": "Необходимо ввести название организации", "must_enter_organization_name": "Необходимо ввести название организации",
"must_enter_organization_admin_email": "Необходимо ввести ваш адрес электронной почты в организации", "must_enter_organization_admin_email": "Необходимо ввести ваш адрес электронной почты в организации",
@@ -1889,7 +1887,7 @@
"admin_username": "Имя пользователя администратора", "admin_username": "Имя пользователя администратора",
"organization_name": "Название организации", "organization_name": "Название организации",
"organization_url": "URL-адрес организации", "organization_url": "URL-адрес организации",
"organization_verify_header": "Подтвердите адрес электронной почты вашей организации", "organization_verify_header": "Подтвердите свой адрес электронной почты в организации",
"organization_verify_email_body": "С помощью кода ниже подтвердите свой адрес электронной почты, чтобы продолжить настройку организации.", "organization_verify_email_body": "С помощью кода ниже подтвердите свой адрес электронной почты, чтобы продолжить настройку организации.",
"additional_url_parameters": "Дополнительные параметры URL-адреса", "additional_url_parameters": "Дополнительные параметры URL-адреса",
"about_your_organization": "О вашей организации", "about_your_organization": "О вашей организации",
@@ -130,7 +130,7 @@
"team_upgrade_banner_description": "Hvala vam što isprobavate naš novi plan za timove. Primetili smo da vaš tim „{{teamName}}“ treba da se nadogradi.", "team_upgrade_banner_description": "Hvala vam što isprobavate naš novi plan za timove. Primetili smo da vaš tim „{{teamName}}“ treba da se nadogradi.",
"upgrade_banner_action": "Nadogradite ovde", "upgrade_banner_action": "Nadogradite ovde",
"team_upgraded_successfully": "Vaš tim je uspešno pretplaćen!", "team_upgraded_successfully": "Vaš tim je uspešno pretplaćen!",
"org_upgrade_banner_description": "Hvala što isprobavate plan naše organizacije. Primetili smo da tim vaše organizacije „{{teamName}}” treba da se nadogradi.", "org_upgrade_banner_description": "Hvala što isprobavate naš Organization plan. Primetili smo da vaš Organization „{{teamName}}” treba da se nadogradi.",
"org_upgraded_successfully": "Vaš Organization je uspešno nadograđen!", "org_upgraded_successfully": "Vaš Organization je uspešno nadograđen!",
"use_link_to_reset_password": "Resetujte lozinku koristeći link ispod", "use_link_to_reset_password": "Resetujte lozinku koristeći link ispod",
"hey_there": "Zdravo,", "hey_there": "Zdravo,",
@@ -1660,9 +1660,8 @@
"delete_sso_configuration_confirmation_description": "Da li ste sigurni da želite da izbrišete {{connectionType}} konfiguraciju? Članovi vašeg tima koji koriste {{connectionType}} prijavljivanje više neće moći da pristupe Cal.com-u.", "delete_sso_configuration_confirmation_description": "Da li ste sigurni da želite da izbrišete {{connectionType}} konfiguraciju? Članovi vašeg tima koji koriste {{connectionType}} prijavljivanje više neće moći da pristupe Cal.com-u.",
"organizer_timezone": "Vremenska zona organizatora", "organizer_timezone": "Vremenska zona organizatora",
"email_user_cta": "Prikaži pozivnicu", "email_user_cta": "Prikaži pozivnicu",
"email_no_user_invite_heading": "Pozvani ste da se pridružite {{appName}} {{entity}}",
"email_no_user_invite_subheading": "{{invitedBy}} vas je pozvao/la da se pridružite njihovom timu u {{appName}}. {{appName}} je planer za koordinaciju događaja koji omogućava vama i vašem timu da zakazujete sastanke bez dopisivanja imejlovima.", "email_no_user_invite_subheading": "{{invitedBy}} vas je pozvao/la da se pridružite njihovom timu u {{appName}}. {{appName}} je planer za koordinaciju događaja koji omogućava vama i vašem timu da zakazujete sastanke bez dopisivanja imejlovima.",
"email_user_invite_subheading": "{{invitedBy}} vas je pozvao/la da se pridružite {{entity}} `{{teamName}}` na {{appName}}. {{appName}} je uređivač rasporeda koji omogućava vama i vašem {{entity}} da zakažete sastanke bez razmene imejlova.", "email_user_invite_subheading_team": "{{invitedBy}} vas je pozvao/la da se pridružite njihovom timu `{{teamName}}` u {{appName}}. {{appName}} je planer za koordinaciju događaja koji omogućava vama i vašem timu da zakazujete sastanke bez dopisivanja imejlovima.",
"email_no_user_invite_steps_intro": "Provešćemo vas u nekoliko kratkiih koraka i za tren ćete uživati u zakazivanju bez stresa sa vašim {{entity}}.", "email_no_user_invite_steps_intro": "Provešćemo vas u nekoliko kratkiih koraka i za tren ćete uživati u zakazivanju bez stresa sa vašim {{entity}}.",
"email_no_user_step_one": "Izaberite korisničko ime", "email_no_user_step_one": "Izaberite korisničko ime",
"email_no_user_step_two": "Povežite se sa nalogom kalendara", "email_no_user_step_two": "Povežite se sa nalogom kalendara",
@@ -1879,7 +1878,6 @@
"first_event_type_webhook_description": "Napravite svoj prvi webhook za ovaj tip događaja", "first_event_type_webhook_description": "Napravite svoj prvi webhook za ovaj tip događaja",
"install_app_on": "Instaliraj aplikaciju", "install_app_on": "Instaliraj aplikaciju",
"create_for": "Napravi za", "create_for": "Napravi za",
"setup_organization": "Postavi organizaciju",
"organization_banner_description": "Kreirajte okruženje gde vaši timovi mogu da postave deljene aplikacije, radne tokove i vrste događaja sa kružnom dodelom i zajedničko zakazivanje.", "organization_banner_description": "Kreirajte okruženje gde vaši timovi mogu da postave deljene aplikacije, radne tokove i vrste događaja sa kružnom dodelom i zajedničko zakazivanje.",
"organization_banner_title": "Upravljajte organizacijama sa više timova", "organization_banner_title": "Upravljajte organizacijama sa više timova",
"set_up_your_organization": "Postavite svoju organizaciju", "set_up_your_organization": "Postavite svoju organizaciju",
+8 -10
View File
@@ -21,7 +21,7 @@
"verify_email_email_link_text": "Här är länken om du inte gillar att klicka på knappar:", "verify_email_email_link_text": "Här är länken om du inte gillar att klicka på knappar:",
"email_sent": "E-postmeddelandet har skickats", "email_sent": "E-postmeddelandet har skickats",
"event_declined_subject": "Avvisades: {{title}} kl. {{date}}", "event_declined_subject": "Avvisades: {{title}} kl. {{date}}",
"event_cancelled_subject": "Avbröts: {{title}} {{date}}", "event_cancelled_subject": "Avbokad: {{title}} {{date}}",
"event_request_declined": "Din bokningsförfrågan har avbjöts", "event_request_declined": "Din bokningsförfrågan har avbjöts",
"event_request_declined_recurring": "Din återkommande händelse har avböjts", "event_request_declined_recurring": "Din återkommande händelse har avböjts",
"event_request_cancelled": "Din schemalagda bokning ställdes in", "event_request_cancelled": "Din schemalagda bokning ställdes in",
@@ -306,7 +306,7 @@
"password_has_been_reset_login": "Ditt lösenord har återställts. Du kan nu logga in med ditt nyskapade lösenord.", "password_has_been_reset_login": "Ditt lösenord har återställts. Du kan nu logga in med ditt nyskapade lösenord.",
"layout": "Layout", "layout": "Layout",
"bookerlayout_default_title": "Standardvy", "bookerlayout_default_title": "Standardvy",
"bookerlayout_description": "Du kan välja flera och dina bokare kan byta vy.", "bookerlayout_description": "Du kan välja flera och dina bokare kan byta vyer.",
"bookerlayout_user_settings_title": "Bokningslayout", "bookerlayout_user_settings_title": "Bokningslayout",
"bookerlayout_user_settings_description": "Du kan välja flera och bokare kan byta vy. Detta kan åsidosättas för varje enskild händelse.", "bookerlayout_user_settings_description": "Du kan välja flera och bokare kan byta vy. Detta kan åsidosättas för varje enskild händelse.",
"bookerlayout_month_view": "Månad", "bookerlayout_month_view": "Månad",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "Vill du verkligen ta bort {{connectionType}}-konfigurationen? Dina teammedlemmar som använder {{connectionType}}-inloggning kan inte längre komma åt Cal.com.", "delete_sso_configuration_confirmation_description": "Vill du verkligen ta bort {{connectionType}}-konfigurationen? Dina teammedlemmar som använder {{connectionType}}-inloggning kan inte längre komma åt Cal.com.",
"organizer_timezone": "Organisatörens tidszon", "organizer_timezone": "Organisatörens tidszon",
"email_user_cta": "Visa inbjudan", "email_user_cta": "Visa inbjudan",
"email_no_user_invite_heading": "Du har blivit inbjuden att gå med i en/ett {{appName}}-{{entity}}",
"email_no_user_invite_subheading": "{{invitedBy}} har bjudit in dig att gå med i sitt team på {{appName}}. {{appName}} är en händelsejonglerande schemaläggare som du och ditt team kan använda för att planera möten utan att skicka e-post fram och tillbaka.", "email_no_user_invite_subheading": "{{invitedBy}} har bjudit in dig att gå med i sitt team på {{appName}}. {{appName}} är en händelsejonglerande schemaläggare som du och ditt team kan använda för att planera möten utan att skicka e-post fram och tillbaka.",
"email_user_invite_subheading": "{{invitedBy}} har bjudit in dig att gå med i deras {{entity}} '{{teamName}}' på {{appName}}. {{appName}} är schemaläggaren som gör det möjligt för dig och din/ditt {{entity}} att schemalägga möten utan att skicka e-post fram och tillbaka.", "email_user_invite_subheading_team": "{{invitedBy}} har bjudit in dig att gå med i sitt team {{teamName}} den {{appName}}. {{appName}} är en händelsejonglerande schemaläggare som du och ditt team kan använda för att planera möten utan att skicka e-post fram och tillbaka.",
"email_no_user_invite_steps_intro": "Vi guidar dig genom några korta steg och du kommer att kunna schemalägga med din/ditt {{entity}} på nolltid utan stress.", "email_no_user_invite_steps_intro": "Vi guidar dig genom några korta steg och du kommer att kunna schemalägga med din/ditt {{entity}} på nolltid utan stress.",
"email_no_user_step_one": "Välj ditt användarnamn", "email_no_user_step_one": "Välj ditt användarnamn",
"email_no_user_step_two": "Anslut ditt kalenderkonto", "email_no_user_step_two": "Anslut ditt kalenderkonto",
@@ -1687,7 +1686,7 @@
"attendee_no_longer_attending": "En deltagare deltar inte längre i din händelse", "attendee_no_longer_attending": "En deltagare deltar inte längre i din händelse",
"attendee_no_longer_attending_subtitle": "{{name}} har avbokat. Detta innebär att en plats har blivit ledig för denna tid", "attendee_no_longer_attending_subtitle": "{{name}} har avbokat. Detta innebär att en plats har blivit ledig för denna tid",
"create_event_on": "Skapa händelse i", "create_event_on": "Skapa händelse i",
"create_routing_form_on": "Skapa omdirigeringsformulär", "create_routing_form_on": "Skapa omdirigeringsformulär på",
"default_app_link_title": "Skapa en standardapplänk", "default_app_link_title": "Skapa en standardapplänk",
"default_app_link_description": "Om du skapar en standardapplänk kan alla händelsetyper som nyligen skapats använda den applänk som du har angett.", "default_app_link_description": "Om du skapar en standardapplänk kan alla händelsetyper som nyligen skapats använda den applänk som du har angett.",
"organizer_default_conferencing_app": "Arrangörens standardapp", "organizer_default_conferencing_app": "Arrangörens standardapp",
@@ -1878,18 +1877,17 @@
"first_event_type_webhook_description": "Skapa din första webhook för denna händelsetyp", "first_event_type_webhook_description": "Skapa din första webhook för denna händelsetyp",
"install_app_on": "Installera appen på", "install_app_on": "Installera appen på",
"create_for": "Skapa för", "create_for": "Skapa för",
"setup_organization": "Konfigurera en organisation", "organization_banner_description": "Skapa miljöer där dina team kan skapa delade appar, arbetsflöden och händelsetyper med round-robin och kollektiv schemaläggning.",
"organization_banner_description": "Skapa en miljö där dina team kan skapa delade appar, arbetsflöden och händelsetyper med round-robin och kollektiv schemaläggning.",
"organization_banner_title": "Hantera organisationer med flera team", "organization_banner_title": "Hantera organisationer med flera team",
"set_up_your_organization": "Konfigurera din organisation", "set_up_your_organization": "Konfigurera din organisation",
"organizations_description": "Organisationer är delade miljöer där team kan skapa delade händelsetyper, appar, arbetsflöden och mycket mer.", "organizations_description": "Organisationer är delade miljöer där team kan skapa delade händelsetyper, appar, arbetsflöden och mycket mer.",
"must_enter_organization_name": "Ett organisationsnamn måste anges", "must_enter_organization_name": "Ett organisationsnamn måste anges",
"must_enter_organization_admin_email": "En organisations e-postadress måste anges", "must_enter_organization_admin_email": "En organisations e-postadress måste anges",
"admin_email": "Din organisations e-postadress", "admin_email": "Din e-postadress i organisationen",
"admin_username": "Administratörens användarnamn", "admin_username": "Administratörens användarnamn",
"organization_name": "Organisationens namn", "organization_name": "Organisationens namn",
"organization_url": "Organisationens URL", "organization_url": "Organisationens URL",
"organization_verify_header": "Verifiera din organisations e-postadress", "organization_verify_header": "Verifiera din e-postadress i organisationen",
"organization_verify_email_body": "Använd koden nedan för att verifiera din e-postadress så att du kan fortsätta att konfigurera din organisation.", "organization_verify_email_body": "Använd koden nedan för att verifiera din e-postadress så att du kan fortsätta att konfigurera din organisation.",
"additional_url_parameters": "Ytterligare URL-parametrar", "additional_url_parameters": "Ytterligare URL-parametrar",
"about_your_organization": "Om din organisation", "about_your_organization": "Om din organisation",
@@ -1940,5 +1938,5 @@
"insights_user_filter": "Användare: {{userName}}", "insights_user_filter": "Användare: {{userName}}",
"insights_subtitle": "Visa Insights-bokningar för dina händelser", "insights_subtitle": "Visa Insights-bokningar för dina händelser",
"custom_plan": "Anpassad plan", "custom_plan": "Anpassad plan",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Lägg till dina nya strängar här ovanför ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -130,7 +130,7 @@
"upgrade_banner_action": "Buradan yükseltin", "upgrade_banner_action": "Buradan yükseltin",
"team_upgraded_successfully": "Ekibiniz başarıyla yükseltildi!", "team_upgraded_successfully": "Ekibiniz başarıyla yükseltildi!",
"org_upgrade_banner_description": "Yeni Organization planımızı denediğiniz için teşekkür ederiz. \"{{teamName}}\" adlı Kuruluşunuzun planının yükseltilmesi gerektiğini fark ettik.", "org_upgrade_banner_description": "Yeni Organization planımızı denediğiniz için teşekkür ederiz. \"{{teamName}}\" adlı Kuruluşunuzun planının yükseltilmesi gerektiğini fark ettik.",
"org_upgraded_successfully": "Kuruluşunuz başarıyla yükseltildi!", "org_upgraded_successfully": "Organization'ınız başarıyla yükseltildi!",
"use_link_to_reset_password": "Şifrenizi sıfırlamak için aşağıdaki bağlantıyı kullanın", "use_link_to_reset_password": "Şifrenizi sıfırlamak için aşağıdaki bağlantıyı kullanın",
"hey_there": "Selam,", "hey_there": "Selam,",
"forgot_your_password_calcom": "Şifrenizi mi unuttunuz? - {{appName}}", "forgot_your_password_calcom": "Şifrenizi mi unuttunuz? - {{appName}}",
@@ -551,7 +551,7 @@
"team_description": "Birkaç cümleyle ekibinizden bahsedin. Bu, ekibinizin URL sayfasında görünecektir.", "team_description": "Birkaç cümleyle ekibinizden bahsedin. Bu, ekibinizin URL sayfasında görünecektir.",
"org_description": "Birkaç cümleyle kuruluşunuzdan bahsedin. Bu, kuruluşunuzun URL sayfasında görünecektir.", "org_description": "Birkaç cümleyle kuruluşunuzdan bahsedin. Bu, kuruluşunuzun URL sayfasında görünecektir.",
"members": "Üyeler", "members": "Üyeler",
"organization_members": "Kuruluş üyeleri", "organization_members": "Organization üyeleri",
"member": "Üye", "member": "Üye",
"number_member_one": "{{count}} üye", "number_member_one": "{{count}} üye",
"number_member_other": "{{count}} üye", "number_member_other": "{{count}} üye",
@@ -662,7 +662,7 @@
"event_type_updated_successfully": "{{eventTypeTitle}} etkinlik türü başarıyla güncellendi", "event_type_updated_successfully": "{{eventTypeTitle}} etkinlik türü başarıyla güncellendi",
"event_type_deleted_successfully": "Etkinlik türü başarıyla silindi", "event_type_deleted_successfully": "Etkinlik türü başarıyla silindi",
"hours": "Saat", "hours": "Saat",
"people": "İnsan", "people": "İnsanlar",
"your_email": "E-postanız", "your_email": "E-postanız",
"change_avatar": "Avatarı değiştir", "change_avatar": "Avatarı değiştir",
"language": "Dil", "language": "Dil",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "{{connectionType}} yapılandırmasını silmek istediğinizden emin misiniz? {{connectionType}} girişini kullanan ekip üyeleriniz artık Cal.com'a erişemeyecek.", "delete_sso_configuration_confirmation_description": "{{connectionType}} yapılandırmasını silmek istediğinizden emin misiniz? {{connectionType}} girişini kullanan ekip üyeleriniz artık Cal.com'a erişemeyecek.",
"organizer_timezone": "Organizatörün saat dilimi", "organizer_timezone": "Organizatörün saat dilimi",
"email_user_cta": "Daveti görüntüle", "email_user_cta": "Daveti görüntüle",
"email_no_user_invite_heading": "{{appName}} {{entity}} grubuna katılmaya davet edildiniz",
"email_no_user_invite_subheading": "{{invitedBy}}, sizi {{appName}} ekibine katılmaya davet etti. {{appName}}, size ve ekibinize e-posta iletişimine ihtiyaç duymadan toplantı planlama yapma olanağı sağlayan bir etkinlik planlayıcıdır.", "email_no_user_invite_subheading": "{{invitedBy}}, sizi {{appName}} ekibine katılmaya davet etti. {{appName}}, size ve ekibinize e-posta iletişimine ihtiyaç duymadan toplantı planlama yapma olanağı sağlayan bir etkinlik planlayıcıdır.",
"email_user_invite_subheading": "{{invitedBy}}, sizi {{appName}} uygulamasındaki {{entity}} `{{teamName}}` ekibine katılmaya davet etti. {{appName}}, size ve {{entity}} ekibinize e-posta iletişimine ihtiyaç duymadan toplantı planlama yapma olanağı sağlayan bir etkinlik planlayıcıdır.", "email_user_invite_subheading_team": "{{invitedBy}}, sizi {{appName}} uygulamasındaki `{{teamName}}` ekibine katılmaya davet etti. {{appName}}, size ve ekibinize e-posta iletişimine ihtiyaç duymadan toplantı planlama yapma olanağı sağlayan bir etkinlik planlayıcıdır.",
"email_no_user_invite_steps_intro": "{{entity}} ekibinizle birlikte kısa sürede ve sorunsuz planlama yapmanın keyfini çıkarmanız için birkaç adımda size rehberlik edeceğiz.", "email_no_user_invite_steps_intro": "{{entity}} ekibinizle birlikte kısa sürede ve sorunsuz planlama yapmanın keyfini çıkarmanız için birkaç adımda size rehberlik edeceğiz.",
"email_no_user_step_one": "Kullanıcı adınızı seçin", "email_no_user_step_one": "Kullanıcı adınızı seçin",
"email_no_user_step_two": "Takvim hesabınızı bağlayın", "email_no_user_step_two": "Takvim hesabınızı bağlayın",
@@ -1876,9 +1875,8 @@
"connect_google_workspace": "Google Workspace'i bağlayın", "connect_google_workspace": "Google Workspace'i bağlayın",
"google_workspace_admin_tooltip": "Bu özelliği kullanmak için Çalışma Alanı Yöneticisi olmalısınız", "google_workspace_admin_tooltip": "Bu özelliği kullanmak için Çalışma Alanı Yöneticisi olmalısınız",
"first_event_type_webhook_description": "Bu etkinlik türü için ilk web kancanızı oluşturun", "first_event_type_webhook_description": "Bu etkinlik türü için ilk web kancanızı oluşturun",
"install_app_on": "Uygulamayı şurada yükle:", "install_app_on": "Uygulamayı şuraya yükle:",
"create_for": "Oluşturun", "create_for": "Oluşturun",
"setup_organization": "Kuruluş oluşturun",
"organization_banner_description": "Ekiplerinizin, döngüsel ve toplu planlama ile paylaşılan uygulamalar, iş akışları ve olay türleri oluşturabileceği bir ortam oluşturun.", "organization_banner_description": "Ekiplerinizin, döngüsel ve toplu planlama ile paylaşılan uygulamalar, iş akışları ve olay türleri oluşturabileceği bir ortam oluşturun.",
"organization_banner_title": "Kuruluşları birden çok ekiple yönetin", "organization_banner_title": "Kuruluşları birden çok ekiple yönetin",
"set_up_your_organization": "Kuruluşunuzu düzenleyin", "set_up_your_organization": "Kuruluşunuzu düzenleyin",
@@ -551,7 +551,7 @@
"team_description": "Кілька речень про вашу команду. Ця інформація з’явиться на сторінці за URL-адресою вашої команди.", "team_description": "Кілька речень про вашу команду. Ця інформація з’явиться на сторінці за URL-адресою вашої команди.",
"org_description": "Кілька речень про вашу організацію. Ця інформація з’явиться на сторінці за URL-адресою вашої організації.", "org_description": "Кілька речень про вашу організацію. Ця інформація з’явиться на сторінці за URL-адресою вашої організації.",
"members": "Учасники", "members": "Учасники",
"organization_members": "Учасники організації", "organization_members": "Учасники Organization",
"member": "Учасник", "member": "Учасник",
"number_member_one": "{{count}} учасник", "number_member_one": "{{count}} учасник",
"number_member_other": "Учасників: {{count}}", "number_member_other": "Учасників: {{count}}",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "Справді видалити конфігурацію {{connectionType}}? Учасники вашої команди, які входять через {{connectionType}}, не зможуть ввійти в Cal.com.", "delete_sso_configuration_confirmation_description": "Справді видалити конфігурацію {{connectionType}}? Учасники вашої команди, які входять через {{connectionType}}, не зможуть ввійти в Cal.com.",
"organizer_timezone": "Часовий пояс організатора", "organizer_timezone": "Часовий пояс організатора",
"email_user_cta": "Переглянути запрошення", "email_user_cta": "Переглянути запрошення",
"email_no_user_invite_heading": "Вас запрошено приєднатися: {{entity}} в застосунку {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} запрошує вас приєднатися до команди в {{appName}}. {{appName}} — планувальник подій, який дає змогу вам і вашій команді планувати зустрічі без тривалої переписки електронною поштою.", "email_no_user_invite_subheading": "{{invitedBy}} запрошує вас приєднатися до команди в {{appName}}. {{appName}} — планувальник подій, який дає змогу вам і вашій команді планувати зустрічі без тривалої переписки електронною поштою.",
"email_user_invite_subheading": "{{invitedBy}} запрошує вас приєднатися до {{entity}} «{{teamName}}» в застосунку {{appName}}. {{appName}} — планувальник подій, завдяки якому ви й ваша {{entity}} можете планувати наради без довгого листування.", "email_user_invite_subheading_team": "{{invitedBy}} запрошує вас приєднатися до команди «{{teamName}}» в {{appName}}. {{appName}} — планувальник подій, який дає змогу вам і вашій команді планувати зустрічі без тривалої переписки електронною поштою.",
"email_no_user_invite_steps_intro": "Ми ознайомимо вас із застосунком, і вже скоро ви й ваша {{entity}} насолоджуватиметеся плануванням без жодного клопоту.", "email_no_user_invite_steps_intro": "Ми ознайомимо вас із застосунком, і вже скоро ви й ваша {{entity}} насолоджуватиметеся плануванням без жодного клопоту.",
"email_no_user_step_one": "Виберіть ім’я користувача", "email_no_user_step_one": "Виберіть ім’я користувача",
"email_no_user_step_two": "Підключіть обліковий запис календаря", "email_no_user_step_two": "Підключіть обліковий запис календаря",
@@ -1878,7 +1877,6 @@
"first_event_type_webhook_description": "Створіть свій перший вебгук для цього типу заходів", "first_event_type_webhook_description": "Створіть свій перший вебгук для цього типу заходів",
"install_app_on": "Установити застосунок у", "install_app_on": "Установити застосунок у",
"create_for": "Створити для", "create_for": "Створити для",
"setup_organization": "Налаштувати організацію",
"organization_banner_description": "Підготуйте середовища, де ваші команди можуть створювати спільні застосунки, робочі процеси й типи заходів із циклічним і колективним плануванням.", "organization_banner_description": "Підготуйте середовища, де ваші команди можуть створювати спільні застосунки, робочі процеси й типи заходів із циклічним і колективним плануванням.",
"organization_banner_title": "Керування організаціями з кількома командами", "organization_banner_title": "Керування організаціями з кількома командами",
"set_up_your_organization": "Налаштуйте свою організацію", "set_up_your_organization": "Налаштуйте свою організацію",
@@ -1938,7 +1936,7 @@
"insights_all_org_filter": "Усі", "insights_all_org_filter": "Усі",
"insights_team_filter": "Команда: {{teamName}}", "insights_team_filter": "Команда: {{teamName}}",
"insights_user_filter": "Користувач: {{userName}}", "insights_user_filter": "Користувач: {{userName}}",
"insights_subtitle": "Переглядайте аналітичні дані про бронювання для своїх заходів", "insights_subtitle": "Переглядайте дані Insights про бронювання для своїх заходів",
"custom_plan": "Користувацький план", "custom_plan": "Користувацький план",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Додайте нові рядки вище ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ Add your new strings above here ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "Bạn có chắc chắn muốn xóa cấu hình {{connectionType}} không? Các thành viên trong nhóm của bạn sử dụng thông tin đăng nhập {{connectionType}} sẽ không thể truy cập vào Cal.com được nữa.", "delete_sso_configuration_confirmation_description": "Bạn có chắc chắn muốn xóa cấu hình {{connectionType}} không? Các thành viên trong nhóm của bạn sử dụng thông tin đăng nhập {{connectionType}} sẽ không thể truy cập vào Cal.com được nữa.",
"organizer_timezone": "Múi giờ của người tổ chức", "organizer_timezone": "Múi giờ của người tổ chức",
"email_user_cta": "Xem lời mời", "email_user_cta": "Xem lời mời",
"email_no_user_invite_heading": "Bạn đã được mời gia nhập {{entity}} {{appName}}",
"email_no_user_invite_subheading": "{{invitedBy}} đã mời bạn gia nhập nhóm của họ trên {{appName}}. {{appName}} là công cụ lên lịch sắp xếp sự kiện cho phép bạn và nhóm bạn lên lịch các cuộc gặp mà không cần trao đổi email nhiều.", "email_no_user_invite_subheading": "{{invitedBy}} đã mời bạn gia nhập nhóm của họ trên {{appName}}. {{appName}} là công cụ lên lịch sắp xếp sự kiện cho phép bạn và nhóm bạn lên lịch các cuộc gặp mà không cần trao đổi email nhiều.",
"email_user_invite_subheading": "{{invitedBy}} đã mời bạn gia nhập {{entity}} '{{teamName}}' của họ trên {{appName}}. {{appName}} là công cụ lên lịch sắp xếp sự kiện cho phép bạn và {{entity}} của bạn lên lịch các cuộc gặp mà không cần trao đổi email nhiều.", "email_user_invite_subheading_team": "{{invitedBy}} đã mời bạn gia nhập nhóm '{{teamName}}' của họ trên {{appName}}. {{appName}} là công cụ lên lịch sắp xếp sự kiện cho phép bạn và nhóm bạn lên lịch các cuộc gặp mà không cần trao đổi email nhiều.",
"email_no_user_invite_steps_intro": "Chúng tôi sẽ hướng dẫn cho bạn qua vài bước nhỏ và bạn sẽ tận hưởng được ngay cảm giác thoải mái không căng thẳng trong việc lên lịch cùng {{entity}} của mình.", "email_no_user_invite_steps_intro": "Chúng tôi sẽ hướng dẫn cho bạn qua vài bước nhỏ và bạn sẽ tận hưởng được ngay cảm giác thoải mái không căng thẳng trong việc lên lịch cùng {{entity}} của mình.",
"email_no_user_step_one": "Chọn tên người dùng của bạn", "email_no_user_step_one": "Chọn tên người dùng của bạn",
"email_no_user_step_two": "Kết nối tài khoản lịch của bạn", "email_no_user_step_two": "Kết nối tài khoản lịch của bạn",
@@ -1878,7 +1877,6 @@
"first_event_type_webhook_description": "Tạo webhook đầu tiên của bạn cho loại sự kiện này", "first_event_type_webhook_description": "Tạo webhook đầu tiên của bạn cho loại sự kiện này",
"install_app_on": "Cài đặt ứng dụng cho", "install_app_on": "Cài đặt ứng dụng cho",
"create_for": "Tạo cho", "create_for": "Tạo cho",
"setup_organization": "Thiết lập một Tổ chức",
"organization_banner_description": "Tạo môi trường tại đó các nhóm của bạn có thể tạo những ứng dụng, tiến độ công việc và loại sự kiện mà có thể chia sẻ được, với chức năng đặt lịch dạng round-robin và tập thể.", "organization_banner_description": "Tạo môi trường tại đó các nhóm của bạn có thể tạo những ứng dụng, tiến độ công việc và loại sự kiện mà có thể chia sẻ được, với chức năng đặt lịch dạng round-robin và tập thể.",
"organization_banner_title": "Quản lý các tổ chức có nhiều nhóm", "organization_banner_title": "Quản lý các tổ chức có nhiều nhóm",
"set_up_your_organization": "Thiết lập tổ chức của bạn", "set_up_your_organization": "Thiết lập tổ chức của bạn",
@@ -1663,9 +1663,8 @@
"delete_sso_configuration_confirmation_description": "确定要删除 {{connectionType}} 配置吗?使用 {{connectionType}} 登录的团队成员将无法再访问 Cal.com。", "delete_sso_configuration_confirmation_description": "确定要删除 {{connectionType}} 配置吗?使用 {{connectionType}} 登录的团队成员将无法再访问 Cal.com。",
"organizer_timezone": "组织者时区", "organizer_timezone": "组织者时区",
"email_user_cta": "查看邀请", "email_user_cta": "查看邀请",
"email_no_user_invite_heading": "您已被邀请加入 {{appName}} {{entity}}",
"email_no_user_invite_subheading": "{{invitedBy}} 已邀请您加入他们在 {{appName}} 上的团队。{{appName}} 是一个活动安排调度程序,让您和您的团队无需通过电子邮件沟通即可安排会议。", "email_no_user_invite_subheading": "{{invitedBy}} 已邀请您加入他们在 {{appName}} 上的团队。{{appName}} 是一个活动安排调度程序,让您和您的团队无需通过电子邮件沟通即可安排会议。",
"email_user_invite_subheading": "{{invitedBy}} 已邀请您加入他们在 {{appName}} 上的 {{entity}}“{{teamName}}”。{{appName}} 是一个活动日程安排程序,让您和您的 {{entity}} 无需通过电子邮件沟通即可安排会议。", "email_user_invite_subheading_team": "{{invitedBy}} 已邀请您加入他们在 {{appName}} 上的团队“{{teamName}}”。{{appName}} 是一个活动安排调度程序,让您和您的团队无需通过电子邮件沟通即可安排会议。",
"email_no_user_invite_steps_intro": "我们将引导您完成几个简短步骤,您将立即与您的 {{entity}} 一起享受无压力的日程安排。", "email_no_user_invite_steps_intro": "我们将引导您完成几个简短步骤,您将立即与您的 {{entity}} 一起享受无压力的日程安排。",
"email_no_user_step_one": "选择您的用户名", "email_no_user_step_one": "选择您的用户名",
"email_no_user_step_two": "连接您的日历账户", "email_no_user_step_two": "连接您的日历账户",
@@ -1882,7 +1881,6 @@
"first_event_type_webhook_description": "为此活动类型创建第一个 Webhook", "first_event_type_webhook_description": "为此活动类型创建第一个 Webhook",
"install_app_on": "安装应用的账户", "install_app_on": "安装应用的账户",
"create_for": "创建", "create_for": "创建",
"setup_organization": "设置组织",
"organization_banner_description": "创建环境,以便让您的团队可以在其中通过轮流和集体日程安排来创建共享的应用、工作流程和活动类型。", "organization_banner_description": "创建环境,以便让您的团队可以在其中通过轮流和集体日程安排来创建共享的应用、工作流程和活动类型。",
"organization_banner_title": "管理具有多个团队的组织", "organization_banner_title": "管理具有多个团队的组织",
"set_up_your_organization": "设置您的组织", "set_up_your_organization": "设置您的组织",
@@ -89,7 +89,7 @@
"event_has_been_rescheduled": "已更新 - 已經重新預定活動時間", "event_has_been_rescheduled": "已更新 - 已經重新預定活動時間",
"request_reschedule_subtitle": "{{organizer}} 已取消預約,並要求您選擇其他時間。", "request_reschedule_subtitle": "{{organizer}} 已取消預約,並要求您選擇其他時間。",
"request_reschedule_title_organizer": "您已要求 {{attendee}} 重新預約", "request_reschedule_title_organizer": "您已要求 {{attendee}} 重新預約",
"request_reschedule_subtitle_organizer": "您已取消預約,{{attendee}} 應和您重新挑選新的預約時間。", "request_reschedule_subtitle_organizer": "您已取消預約,{{attendee}} 應和您重新挑選預約時間。",
"rescheduled_event_type_subject": "已送出重新預定的申請:在 {{date}} 與 {{name}} 的 {{eventType}}", "rescheduled_event_type_subject": "已送出重新預定的申請:在 {{date}} 與 {{name}} 的 {{eventType}}",
"requested_to_reschedule_subject_attendee": "需進行重新預約操作:請為與 {{name}} 的 {{eventType}} 預訂新時間", "requested_to_reschedule_subject_attendee": "需進行重新預約操作:請為與 {{name}} 的 {{eventType}} 預訂新時間",
"hi_user_name": "哈囉 {{name}}", "hi_user_name": "哈囉 {{name}}",
@@ -306,7 +306,7 @@
"password_has_been_reset_login": "密碼已經重置。現在即可使用新建立的密碼登入。", "password_has_been_reset_login": "密碼已經重置。現在即可使用新建立的密碼登入。",
"layout": "版面", "layout": "版面",
"bookerlayout_default_title": "預設檢視", "bookerlayout_default_title": "預設檢視",
"bookerlayout_description": "您可以選取多個版面,以便預約者切換檢視。", "bookerlayout_description": "您可以選取多種檢視方式供預約者切換。",
"bookerlayout_user_settings_title": "預約版面", "bookerlayout_user_settings_title": "預約版面",
"bookerlayout_user_settings_description": "您可以選取多個版面,以便預約者切換檢視。您可根據不同活動來覆寫此設定。", "bookerlayout_user_settings_description": "您可以選取多個版面,以便預約者切換檢視。您可根據不同活動來覆寫此設定。",
"bookerlayout_month_view": "月", "bookerlayout_month_view": "月",
@@ -1659,9 +1659,8 @@
"delete_sso_configuration_confirmation_description": "確定要刪除 {{connectionType}} 設定?使用 {{connectionType}} 登入的團隊成員將再也無法存取 Cal.com。", "delete_sso_configuration_confirmation_description": "確定要刪除 {{connectionType}} 設定?使用 {{connectionType}} 登入的團隊成員將再也無法存取 Cal.com。",
"organizer_timezone": "主辦者時區", "organizer_timezone": "主辦者時區",
"email_user_cta": "檢視邀請", "email_user_cta": "檢視邀請",
"email_no_user_invite_heading": "您已獲邀加入 {{appName}} {{entity}}",
"email_no_user_invite_subheading": "{{invitedBy}} 已邀請您加入對方在 {{appName}} 上的團隊。{{appName}} 是活動多工排程工具,可讓您和您的團隊無須透過繁複的電子郵件往來就能輕鬆預定會議。", "email_no_user_invite_subheading": "{{invitedBy}} 已邀請您加入對方在 {{appName}} 上的團隊。{{appName}} 是活動多工排程工具,可讓您和您的團隊無須透過繁複的電子郵件往來就能輕鬆預定會議。",
"email_user_invite_subheading": "{{invitedBy}} 已邀請您加入對方在 {{appName}} 上的「{{teamName}}」{{entity}}。{{appName}} 為一款靈活的日程管理工具,可讓您和 {{entity}} 輕鬆預定會議,而無須透過繁複的電子郵件往來。", "email_user_invite_subheading_team": "{{invitedBy}} 已邀請您加入對方在 {{appName}} 上的「{{teamName}}」團隊。{{appName}} 為一款活動多功能排程工具,可讓您和團隊無須透過繁複的電子郵件往來,就能輕鬆預定會議。",
"email_no_user_invite_steps_intro": "我們會逐步引導您完成幾個簡短的步驟,然後您就能馬上與 {{entity}} 享受沒有壓力的排程預定功能。", "email_no_user_invite_steps_intro": "我們會逐步引導您完成幾個簡短的步驟,然後您就能馬上與 {{entity}} 享受沒有壓力的排程預定功能。",
"email_no_user_step_one": "選擇使用者名稱", "email_no_user_step_one": "選擇使用者名稱",
"email_no_user_step_two": "連結行事曆帳號", "email_no_user_step_two": "連結行事曆帳號",
@@ -1687,7 +1686,7 @@
"attendee_no_longer_attending": "一位與會者不再參加您的活動", "attendee_no_longer_attending": "一位與會者不再參加您的活動",
"attendee_no_longer_attending_subtitle": "{{name}} 已取消,這代表此時段空出了一個座位", "attendee_no_longer_attending_subtitle": "{{name}} 已取消,這代表此時段空出了一個座位",
"create_event_on": "活動建立日期", "create_event_on": "活動建立日期",
"create_routing_form_on": "引導表單的建立位置", "create_routing_form_on": "引導表單的建立帳戶",
"default_app_link_title": "設定預設應用程式連結", "default_app_link_title": "設定預設應用程式連結",
"default_app_link_description": "設定預設應用程式連結,即可讓所有全新建立的活動類型使用您設定的應用程式連結。", "default_app_link_description": "設定預設應用程式連結,即可讓所有全新建立的活動類型使用您設定的應用程式連結。",
"organizer_default_conferencing_app": "主辦者的預設應用程式", "organizer_default_conferencing_app": "主辦者的預設應用程式",
@@ -1841,7 +1840,7 @@
"invite_link_copied": "邀請連結已複製", "invite_link_copied": "邀請連結已複製",
"invite_link_deleted": "邀請連結已刪除", "invite_link_deleted": "邀請連結已刪除",
"invite_link_updated": "邀請連結設定已儲存", "invite_link_updated": "邀請連結設定已儲存",
"link_expires_after": "連結設定效期…", "link_expires_after": "將連結效期設為…",
"one_day": "1 天", "one_day": "1 天",
"seven_days": "7 天", "seven_days": "7 天",
"thirty_days": "30 天", "thirty_days": "30 天",
@@ -1878,7 +1877,6 @@
"first_event_type_webhook_description": "為此活動類型建立第一個 Webhook", "first_event_type_webhook_description": "為此活動類型建立第一個 Webhook",
"install_app_on": "應用程式安裝帳號", "install_app_on": "應用程式安裝帳號",
"create_for": "建立", "create_for": "建立",
"setup_organization": "設定組織",
"organization_banner_description": "建立環境,供團隊利用輪流制和全體預定功能建立共用的應用程式、工作流程和活動類型。", "organization_banner_description": "建立環境,供團隊利用輪流制和全體預定功能建立共用的應用程式、工作流程和活動類型。",
"organization_banner_title": "管理有多個團隊的組織", "organization_banner_title": "管理有多個團隊的組織",
"set_up_your_organization": "設定組織", "set_up_your_organization": "設定組織",
@@ -1938,7 +1936,7 @@
"insights_all_org_filter": "所有應用程式", "insights_all_org_filter": "所有應用程式",
"insights_team_filter": "團隊:{{teamName}}", "insights_team_filter": "團隊:{{teamName}}",
"insights_user_filter": "使用者:{{userName}}", "insights_user_filter": "使用者:{{userName}}",
"insights_subtitle": "查看所有活動的預約洞見", "insights_subtitle": "查看所有活動的預約 Insight",
"custom_plan": "自訂方案", "custom_plan": "自訂方案",
"ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ 請在此處新增您的字串 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑" "ADD_NEW_STRINGS_ABOVE_THIS_LINE_TO_PREVENT_MERGE_CONFLICTS": "↑↑↑↑↑↑↑↑↑↑↑↑↑ 請在此處新增您的字串 ↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑"
} }
+6
View File
@@ -93,6 +93,12 @@
--cal-brand-text: black; --cal-brand-text: black;
} }
@layer base {
* {
@apply border-default
}
}
::-moz-selection { ::-moz-selection {
color: var(--cal-brand-text); color: var(--cal-brand-text);
background: var(--cal-brand); background: var(--cal-brand);
+20
View File
@@ -0,0 +1,20 @@
// my-test.ts
import { test as base } from "vitest";
import { getTestEmails } from "@calcom/lib/testEmails";
export interface Fixtures {
emails: ReturnType<typeof getEmailsFixture>;
}
export const test = base.extend<Fixtures>({
emails: async ({}, use) => {
await use(getEmailsFixture());
},
});
function getEmailsFixture() {
return {
get: getTestEmails,
};
}
+2 -302
View File
@@ -1,23 +1,14 @@
import type {
EventType as PrismaEventType,
User as PrismaUser,
Booking as PrismaBooking,
App as PrismaApp,
} from "@prisma/client";
import CalendarManagerMock from "../../../../tests/libs/__mocks__/CalendarManager"; import CalendarManagerMock from "../../../../tests/libs/__mocks__/CalendarManager";
import prismaMock from "../../../../tests/libs/__mocks__/prisma"; import prismaMock from "../../../../tests/libs/__mocks__/prisma";
import { diff } from "jest-diff"; import { diff } from "jest-diff";
import { v4 as uuidv4 } from "uuid";
import { describe, expect, vi, beforeEach, afterEach, test } from "vitest"; import { describe, expect, vi, beforeEach, afterEach, test } from "vitest";
import logger from "@calcom/lib/logger";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import type { SchedulingType } from "@calcom/prisma/enums";
import type { BookingStatus } from "@calcom/prisma/enums"; import type { BookingStatus } from "@calcom/prisma/enums";
import type { Slot } from "@calcom/trpc/server/routers/viewer/slots/types"; import type { Slot } from "@calcom/trpc/server/routers/viewer/slots/types";
import { getAvailableSlots as getSchedule } from "@calcom/trpc/server/routers/viewer/slots/util"; import { getAvailableSlots as getSchedule } from "@calcom/trpc/server/routers/viewer/slots/util";
import { getDate, getGoogleCalendarCredential, createBookingScenario} from "../utils/bookingScenario";
// TODO: Mock properly // TODO: Mock properly
prismaMock.eventType.findUnique.mockResolvedValue(null); prismaMock.eventType.findUnique.mockResolvedValue(null);
@@ -129,6 +120,7 @@ const TestData = {
}, },
users: { users: {
example: { example: {
name: "Example",
username: "example", username: "example",
defaultScheduleId: 1, defaultScheduleId: 1,
email: "example@example.com", email: "example@example.com",
@@ -151,63 +143,6 @@ const TestData = {
}, },
}; };
type App = {
slug: string;
dirName: string;
};
type InputCredential = typeof TestData.credentials.google;
type InputSelectedCalendar = typeof TestData.selectedCalendars.google;
type InputUser = typeof TestData.users.example & { id: number } & {
credentials?: InputCredential[];
selectedCalendars?: InputSelectedCalendar[];
schedules: {
id: number;
name: string;
availability: {
userId: number | null;
eventTypeId: number | null;
days: number[];
startTime: Date;
endTime: Date;
date: string | null;
}[];
timeZone: string;
}[];
};
type InputEventType = {
id: number;
title?: string;
length?: number;
offsetStart?: number;
slotInterval?: number;
minimumBookingNotice?: number;
users?: { id: number }[];
hosts?: { id: number }[];
schedulingType?: SchedulingType;
beforeEventBuffer?: number;
afterEventBuffer?: number;
};
type InputBooking = {
userId?: number;
eventTypeId: number;
startTime: string;
endTime: string;
title?: string;
status: BookingStatus;
attendees?: { email: string }[];
};
type InputHost = {
id: number;
userId: number;
eventTypeId: number;
isFixed: boolean;
};
const cleanup = async () => { const cleanup = async () => {
await prisma.eventType.deleteMany(); await prisma.eventType.deleteMany();
@@ -241,7 +176,6 @@ describe("getSchedule", () => {
]); ]);
const scenarioData = { const scenarioData = {
hosts: [],
eventTypes: [ eventTypes: [
{ {
id: 1, id: 1,
@@ -350,7 +284,6 @@ describe("getSchedule", () => {
endTime: `${plus2DateString}T06:15:00.000Z`, endTime: `${plus2DateString}T06:15:00.000Z`,
}, },
], ],
hosts: [],
}); });
// Day Plus 2 is completely free - It only has non accepted bookings // Day Plus 2 is completely free - It only has non accepted bookings
@@ -449,7 +382,6 @@ describe("getSchedule", () => {
schedules: [TestData.schedules.IstWorkHours], schedules: [TestData.schedules.IstWorkHours],
}, },
], ],
hosts: [],
}); });
const { dateString: plus1DateString } = getDate({ dateIncrement: 1 }); const { dateString: plus1DateString } = getDate({ dateIncrement: 1 });
const { dateString: plus2DateString } = getDate({ dateIncrement: 2 }); const { dateString: plus2DateString } = getDate({ dateIncrement: 2 });
@@ -550,7 +482,6 @@ describe("getSchedule", () => {
schedules: [TestData.schedules.IstWorkHours], schedules: [TestData.schedules.IstWorkHours],
}, },
], ],
hosts: [],
}); });
const { dateString: todayDateString } = getDate(); const { dateString: todayDateString } = getDate();
const { dateString: minus1DateString } = getDate({ dateIncrement: -1 }); const { dateString: minus1DateString } = getDate({ dateIncrement: -1 });
@@ -634,7 +565,6 @@ describe("getSchedule", () => {
selectedCalendars: [TestData.selectedCalendars.google], selectedCalendars: [TestData.selectedCalendars.google],
}, },
], ],
hosts: [],
apps: [TestData.apps.googleCalendar], apps: [TestData.apps.googleCalendar],
}; };
@@ -710,7 +640,6 @@ describe("getSchedule", () => {
}, },
], ],
apps: [TestData.apps.googleCalendar], apps: [TestData.apps.googleCalendar],
hosts: [],
}; };
createBookingScenario(scenarioData); createBookingScenario(scenarioData);
@@ -768,7 +697,6 @@ describe("getSchedule", () => {
selectedCalendars: [TestData.selectedCalendars.google], selectedCalendars: [TestData.selectedCalendars.google],
}, },
], ],
hosts: [],
apps: [TestData.apps.googleCalendar], apps: [TestData.apps.googleCalendar],
}; };
@@ -834,7 +762,6 @@ describe("getSchedule", () => {
schedules: [TestData.schedules.IstWorkHoursWithDateOverride(plus2DateString)], schedules: [TestData.schedules.IstWorkHoursWithDateOverride(plus2DateString)],
}, },
], ],
hosts: [],
}; };
createBookingScenario(scenarioData); createBookingScenario(scenarioData);
@@ -913,15 +840,6 @@ describe("getSchedule", () => {
endTime: `${plus2DateString}T04:15:00.000Z`, endTime: `${plus2DateString}T04:15:00.000Z`,
}, },
], ],
hosts: [
// This user is a host of our Collective event
{
id: 1,
eventTypeId: 1,
userId: 101,
isFixed: true,
},
],
}); });
// Requesting this user's availability for their // Requesting this user's availability for their
@@ -1022,7 +940,6 @@ describe("getSchedule", () => {
endTime: `${plus2DateString}T05:45:00.000Z`, endTime: `${plus2DateString}T05:45:00.000Z`,
}, },
], ],
hosts: [],
}); });
const scheduleForTeamEventOnADayWithNoBooking = await getSchedule({ const scheduleForTeamEventOnADayWithNoBooking = await getSchedule({
@@ -1162,7 +1079,6 @@ describe("getSchedule", () => {
endTime: `${plus3DateString}T04:15:00.000Z`, endTime: `${plus3DateString}T04:15:00.000Z`,
}, },
], ],
hosts: [],
}); });
const scheduleForTeamEventOnADayWithOneBookingForEachUserButOnDifferentTimeslots = await getSchedule({ const scheduleForTeamEventOnADayWithOneBookingForEachUserButOnDifferentTimeslots = await getSchedule({
input: { input: {
@@ -1224,219 +1140,3 @@ describe("getSchedule", () => {
}); });
}); });
function getGoogleCalendarCredential() {
return {
type: "google_calendar",
key: {
scope:
"https://www.googleapis.com/auth/calendar.events https://www.googleapis.com/auth/calendar.readonly",
token_type: "Bearer",
expiry_date: 1656999025367,
access_token: "ACCESS_TOKEN",
refresh_token: "REFRESH_TOKEN",
},
};
}
function addEventTypes(eventTypes: InputEventType[], usersStore: InputUser[]) {
const baseEventType = {
title: "Base EventType Title",
slug: "base-event-type-slug",
timeZone: null,
beforeEventBuffer: 0,
afterEventBuffer: 0,
schedulingType: null,
//TODO: What is the purpose of periodStartDate and periodEndDate? Test these?
periodStartDate: new Date("2022-01-21T09:03:48.000Z"),
periodEndDate: new Date("2022-01-21T09:03:48.000Z"),
periodCountCalendarDays: false,
periodDays: 30,
seatsPerTimeSlot: null,
metadata: {},
minimumBookingNotice: 0,
offsetStart: 0,
};
const foundEvents: Record<number, boolean> = {};
const eventTypesWithUsers = eventTypes.map((eventType) => {
if (!eventType.slotInterval && !eventType.length) {
throw new Error("eventTypes[number]: slotInterval or length must be defined");
}
if (foundEvents[eventType.id]) {
throw new Error(`eventTypes[number]: id ${eventType.id} is not unique`);
}
foundEvents[eventType.id] = true;
const users =
eventType.users?.map((userWithJustId) => {
return usersStore.find((user) => user.id === userWithJustId.id);
}) || [];
return {
...baseEventType,
...eventType,
users,
};
});
logger.silly("TestData: Creating EventType", eventTypes);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
prismaMock.eventType.findUnique.mockImplementation(({ where }) => {
return new Promise((resolve) => {
const eventType = eventTypesWithUsers.find((e) => e.id === where.id) as unknown as PrismaEventType & {
users: PrismaUser[];
};
resolve(eventType);
});
});
}
async function addBookings(bookings: InputBooking[], eventTypes: InputEventType[]) {
logger.silly("TestData: Creating Bookings", bookings);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
prismaMock.booking.findMany.mockImplementation((findManyArg) => {
const where = findManyArg?.where || {};
return new Promise((resolve) => {
resolve(
bookings
// We can improve this filter to support the entire where clause but that isn't necessary yet. So, handle what we know we pass to `findMany` and is needed
.filter((booking) => {
/**
* A user is considered busy within a given time period if there
* is a booking they own OR host. This function mocks some of the logic
* for each condition. For details see the following ticket:
* https://github.com/calcom/cal.com/issues/6374
*/
// ~~ FIRST CONDITION ensures that this booking is owned by this user
// and that the status is what we want
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const statusIn = where.OR[0].status?.in || [];
const firstConditionMatches =
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
statusIn.includes(booking.status) && booking.userId === where.OR[0].userId;
// We return this booking if either condition is met
return firstConditionMatches;
})
.map((booking) => ({
uid: uuidv4(),
title: "Test Booking Title",
...booking,
eventType: eventTypes.find((eventType) => eventType.id === booking.eventTypeId),
})) as unknown as PrismaBooking[]
);
});
});
}
function addUsers(users: InputUser[]) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
prismaMock.user.findUniqueOrThrow.mockImplementation((findUniqueArgs) => {
return new Promise((resolve) => {
resolve({
email: `IntegrationTestUser${findUniqueArgs?.where.id}@example.com`,
} as unknown as PrismaUser);
});
});
prismaMock.user.findMany.mockResolvedValue(
users.map((user) => {
return {
...user,
username: `IntegrationTestUser${user.id}`,
email: `IntegrationTestUser${user.id}@example.com`,
};
}) as unknown as PrismaUser[]
);
}
type ScenarioData = {
// TODO: Support multiple bookings and add tests with that.
bookings?: InputBooking[];
users: InputUser[];
hosts: InputHost[];
credentials?: InputCredential[];
apps?: App[];
selectedCalendars?: InputSelectedCalendar[];
eventTypes: InputEventType[];
calendarBusyTimes?: {
start: string;
end: string;
}[];
};
function createBookingScenario(data: ScenarioData) {
logger.silly("TestData: Creating Scenario", data);
addUsers(data.users);
const eventType = addEventTypes(data.eventTypes, data.users);
if (data.apps) {
prismaMock.app.findMany.mockResolvedValue(data.apps as PrismaApp[]);
// FIXME: How do we know which app to return?
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
prismaMock.app.findUnique.mockImplementation(({ where: { slug: whereSlug } }) => {
return new Promise((resolve) => {
if (!data.apps) {
resolve(null);
return;
}
resolve((data.apps.find(({ slug }) => slug == whereSlug) as PrismaApp) || null);
});
});
}
data.bookings = data.bookings || [];
addBookings(data.bookings, data.eventTypes);
return {
eventType,
};
}
/**
* This fn indents to dynamically compute day, month, year for the purpose of testing.
* We are not using DayJS because that's actually being tested by this code.
* - `dateIncrement` adds the increment to current day
* - `monthIncrement` adds the increment to current month
* - `yearIncrement` adds the increment to current year
*/
const getDate = (param: { dateIncrement?: number; monthIncrement?: number; yearIncrement?: number } = {}) => {
let { dateIncrement, monthIncrement, yearIncrement } = param;
dateIncrement = dateIncrement || 0;
monthIncrement = monthIncrement || 0;
yearIncrement = yearIncrement || 0;
let _date = new Date().getDate() + dateIncrement;
let year = new Date().getFullYear() + yearIncrement;
// Make it start with 1 to match with DayJS requiremet
let _month = new Date().getMonth() + monthIncrement + 1;
// If last day of the month(As _month is plus 1 already it is going to be the 0th day of next month which is the last day of current month)
const lastDayOfMonth = new Date(year, _month, 0).getDate();
const numberOfDaysForNextMonth = +_date - +lastDayOfMonth;
if (numberOfDaysForNextMonth > 0) {
_date = numberOfDaysForNextMonth;
_month = _month + 1;
}
if (_month === 13) {
_month = 1;
year = year + 1;
}
const date = _date < 10 ? "0" + _date : _date;
const month = _month < 10 ? "0" + _month : _month;
return {
date,
month,
year,
dateString: `${year}-${month}-${date}`,
};
};
+742
View File
@@ -0,0 +1,742 @@
import type {
EventType as PrismaEventType,
User as PrismaUser,
Booking as PrismaBooking,
App as PrismaApp,
} from "@prisma/client";
import type { Prisma } from "@prisma/client";
import type { WebhookTriggerEvents } from "@prisma/client";
import { v4 as uuidv4 } from "uuid";
import { expect } from "vitest";
import "vitest-fetch-mock";
import { appStoreMetadata } from "@calcom/app-store/appStoreMetaData";
import logger from "@calcom/lib/logger";
import type { SchedulingType } from "@calcom/prisma/enums";
import type { BookingStatus } from "@calcom/prisma/enums";
import type { EventBusyDate } from "@calcom/types/Calendar";
import type { Fixtures } from "@calcom/web/test/fixtures/fixtures";
import appStoreMock from "../../../../tests/libs/__mocks__/app-store";
import i18nMock from "../../../../tests/libs/__mocks__/libServerI18n";
import prismaMock from "../../../../tests/libs/__mocks__/prisma";
type App = {
slug: string;
dirName: string;
};
type InputWebhook = {
appId: string | null;
userId?: number | null;
teamId?: number | null;
eventTypeId?: number;
active: boolean;
eventTriggers: WebhookTriggerEvents[];
subscriberUrl: string;
};
/**
* Data to be mocked
*/
type ScenarioData = {
// hosts: { id: number; eventTypeId?: number; userId?: number; isFixed?: boolean }[];
/**
* Prisma would return these eventTypes
*/
eventTypes: InputEventType[];
/**
* Prisma would return these users
*/
users: InputUser[];
/**
* Prisma would return these apps
*/
apps?: App[];
bookings?: InputBooking[];
webhooks?: InputWebhook[];
};
type InputCredential = typeof TestData.credentials.google;
type InputSelectedCalendar = typeof TestData.selectedCalendars.google;
type InputUser = typeof TestData.users.example & { id: number } & {
credentials?: InputCredential[];
selectedCalendars?: InputSelectedCalendar[];
schedules: {
id: number;
name: string;
availability: {
userId: number | null;
eventTypeId: number | null;
days: number[];
startTime: Date;
endTime: Date;
date: string | null;
}[];
timeZone: string;
}[];
};
type InputEventType = {
id: number;
title?: string;
length?: number;
offsetStart?: number;
slotInterval?: number;
minimumBookingNotice?: number;
/**
* These user ids are `ScenarioData["users"]["id"]`
*/
users?: { id: number }[];
hosts?: { id: number }[];
schedulingType?: SchedulingType;
beforeEventBuffer?: number;
afterEventBuffer?: number;
requiresConfirmation?: boolean;
};
type InputBooking = {
userId?: number;
eventTypeId: number;
startTime: string;
endTime: string;
title?: string;
status: BookingStatus;
attendees?: { email: string }[];
};
const Timezones = {
"+5:30": "Asia/Kolkata",
"+6:00": "Asia/Dhaka",
};
function addEventTypes(eventTypes: InputEventType[], usersStore: InputUser[]) {
const baseEventType = {
title: "Base EventType Title",
slug: "base-event-type-slug",
timeZone: null,
beforeEventBuffer: 0,
afterEventBuffer: 0,
schedulingType: null,
//TODO: What is the purpose of periodStartDate and periodEndDate? Test these?
periodStartDate: new Date("2022-01-21T09:03:48.000Z"),
periodEndDate: new Date("2022-01-21T09:03:48.000Z"),
periodCountCalendarDays: false,
periodDays: 30,
seatsPerTimeSlot: null,
metadata: {},
minimumBookingNotice: 0,
offsetStart: 0,
};
const foundEvents: Record<number, boolean> = {};
const eventTypesWithUsers = eventTypes.map((eventType) => {
if (!eventType.slotInterval && !eventType.length) {
throw new Error("eventTypes[number]: slotInterval or length must be defined");
}
if (foundEvents[eventType.id]) {
throw new Error(`eventTypes[number]: id ${eventType.id} is not unique`);
}
foundEvents[eventType.id] = true;
const users =
eventType.users?.map((userWithJustId) => {
return usersStore.find((user) => user.id === userWithJustId.id);
}) || [];
return {
...baseEventType,
...eventType,
workflows: [],
users,
};
});
logger.silly("TestData: Creating EventType", eventTypes);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const eventTypeMock = ({ where }) => {
return new Promise((resolve) => {
const eventType = eventTypesWithUsers.find((e) => e.id === where.id) as unknown as PrismaEventType & {
users: PrismaUser[];
};
resolve(eventType);
});
};
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
prismaMock.eventType.findUnique.mockImplementation(eventTypeMock);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
prismaMock.eventType.findUniqueOrThrow.mockImplementation(eventTypeMock);
}
async function addBookings(bookings: InputBooking[], eventTypes: InputEventType[]) {
logger.silly("TestData: Creating Bookings", bookings);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
prismaMock.booking.findMany.mockImplementation((findManyArg) => {
const where = findManyArg?.where || {};
return new Promise((resolve) => {
resolve(
bookings
// We can improve this filter to support the entire where clause but that isn't necessary yet. So, handle what we know we pass to `findMany` and is needed
.filter((booking) => {
/**
* A user is considered busy within a given time period if there
* is a booking they own OR host. This function mocks some of the logic
* for each condition. For details see the following ticket:
* https://github.com/calcom/cal.com/issues/6374
*/
// ~~ FIRST CONDITION ensures that this booking is owned by this user
// and that the status is what we want
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
const statusIn = where.OR[0].status?.in || [];
const firstConditionMatches =
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
statusIn.includes(booking.status) && booking.userId === where.OR[0].userId;
// We return this booking if either condition is met
return firstConditionMatches;
})
.map((booking) => ({
uid: uuidv4(),
title: "Test Booking Title",
...booking,
eventType: eventTypes.find((eventType) => eventType.id === booking.eventTypeId),
})) as unknown as PrismaBooking[]
);
});
});
}
async function addWebhooks(webhooks: InputWebhook[]) {
prismaMock.webhook.findMany.mockResolvedValue(
webhooks.map((webhook) => {
return {
...webhook,
payloadTemplate: null,
secret: null,
id: uuidv4(),
createdAt: new Date(),
userId: webhook.userId || null,
eventTypeId: webhook.eventTypeId || null,
teamId: webhook.teamId || null,
};
})
);
}
function addUsers(users: InputUser[]) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
prismaMock.user.findUniqueOrThrow.mockImplementation((findUniqueArgs) => {
return new Promise((resolve) => {
resolve({
email: `IntegrationTestUser${findUniqueArgs?.where.id}@example.com`,
} as unknown as PrismaUser);
});
});
prismaMock.user.findMany.mockResolvedValue(
users.map((user) => {
return {
...user,
username: `IntegrationTestUser${user.id}`,
email: `IntegrationTestUser${user.id}@example.com`,
};
}) as unknown as PrismaUser[]
);
}
export async function createBookingScenario(data: ScenarioData) {
logger.silly("TestData: Creating Scenario", data);
addUsers(data.users);
const eventType = addEventTypes(data.eventTypes, data.users);
if (data.apps) {
prismaMock.app.findMany.mockResolvedValue(data.apps as PrismaApp[]);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
const appMock = ({ where: { slug: whereSlug } }) => {
return new Promise((resolve) => {
if (!data.apps) {
resolve(null);
return;
}
const foundApp = data.apps.find(({ slug }) => slug == whereSlug);
//TODO: Pass just the app name in data.apps and maintain apps in a separate object or load them dyamically
resolve(
({
...foundApp,
...(foundApp?.slug ? TestData.apps[foundApp.slug as keyof typeof TestData.apps] || {} : {}),
enabled: true,
createdAt: new Date(),
updatedAt: new Date(),
categories: [],
} as PrismaApp) || null
);
});
};
// FIXME: How do we know which app to return?
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
prismaMock.app.findUnique.mockImplementation(appMock);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
prismaMock.app.findFirst.mockImplementation(appMock);
}
data.bookings = data.bookings || [];
allowSuccessfulBookingCreation();
addBookings(data.bookings, data.eventTypes);
// mockBusyCalendarTimes([]);
addWebhooks(data.webhooks || []);
return {
eventType,
};
}
/**
* This fn indents to /ally compute day, month, year for the purpose of testing.
* We are not using DayJS because that's actually being tested by this code.
* - `dateIncrement` adds the increment to current day
* - `monthIncrement` adds the increment to current month
* - `yearIncrement` adds the increment to current year
*/
export const getDate = (
param: { dateIncrement?: number; monthIncrement?: number; yearIncrement?: number } = {}
) => {
let { dateIncrement, monthIncrement, yearIncrement } = param;
dateIncrement = dateIncrement || 0;
monthIncrement = monthIncrement || 0;
yearIncrement = yearIncrement || 0;
let _date = new Date().getDate() + dateIncrement;
let year = new Date().getFullYear() + yearIncrement;
// Make it start with 1 to match with DayJS requiremet
let _month = new Date().getMonth() + monthIncrement + 1;
// If last day of the month(As _month is plus 1 already it is going to be the 0th day of next month which is the last day of current month)
const lastDayOfMonth = new Date(year, _month, 0).getDate();
const numberOfDaysForNextMonth = +_date - +lastDayOfMonth;
if (numberOfDaysForNextMonth > 0) {
_date = numberOfDaysForNextMonth;
_month = _month + 1;
}
if (_month === 13) {
_month = 1;
year = year + 1;
}
const date = _date < 10 ? "0" + _date : _date;
const month = _month < 10 ? "0" + _month : _month;
return {
date,
month,
year,
dateString: `${year}-${month}-${date}`,
};
};
export function getMockedCredential({
metadataLookupKey,
key,
}: {
metadataLookupKey: string;
key: {
expiry_date?: number;
token_type?: string;
access_token?: string;
refresh_token?: string;
scope: string;
};
}) {
return {
type: appStoreMetadata[metadataLookupKey as keyof typeof appStoreMetadata].type,
appId: appStoreMetadata[metadataLookupKey as keyof typeof appStoreMetadata].slug,
key: {
expiry_date: Date.now() + 1000000,
token_type: "Bearer",
access_token: "ACCESS_TOKEN",
refresh_token: "REFRESH_TOKEN",
...key,
},
};
}
export function getGoogleCalendarCredential() {
return getMockedCredential({
metadataLookupKey: "googlecalendar",
key: {
scope:
"https://www.googleapis.com/auth/calendar.events https://www.googleapis.com/auth/calendar.readonly",
},
});
}
export function getZoomAppCredential() {
return getMockedCredential({
metadataLookupKey: "zoomvideo",
key: {
scope: "meeting:writed",
},
});
}
export const TestData = {
selectedCalendars: {
google: {
integration: "google_calendar",
externalId: "john@example.com",
},
},
credentials: {
google: getGoogleCalendarCredential(),
},
schedules: {
IstWorkHours: {
id: 1,
name: "9:30AM to 6PM in India - 4:00AM to 12:30PM in GMT",
availability: [
{
userId: null,
eventTypeId: null,
days: [0, 1, 2, 3, 4, 5, 6],
startTime: new Date("1970-01-01T09:30:00.000Z"),
endTime: new Date("1970-01-01T18:00:00.000Z"),
date: null,
},
],
timeZone: Timezones["+5:30"],
},
IstWorkHoursWithDateOverride: (dateString: string) => ({
id: 1,
name: "9:30AM to 6PM in India - 4:00AM to 12:30PM in GMT but with a Date Override for 2PM to 6PM IST(in GST time it is 8:30AM to 12:30PM)",
availability: [
{
userId: null,
eventTypeId: null,
days: [0, 1, 2, 3, 4, 5, 6],
startTime: new Date("1970-01-01T09:30:00.000Z"),
endTime: new Date("1970-01-01T18:00:00.000Z"),
date: null,
},
{
userId: null,
eventTypeId: null,
days: [0, 1, 2, 3, 4, 5, 6],
startTime: new Date(`1970-01-01T14:00:00.000Z`),
endTime: new Date(`1970-01-01T18:00:00.000Z`),
date: dateString,
},
],
timeZone: Timezones["+5:30"],
}),
},
users: {
example: {
name: "Example",
email: "example@example.com",
username: "example",
defaultScheduleId: 1,
timeZone: Timezones["+5:30"],
},
},
apps: {
"google-calendar": {
slug: "google-calendar",
dirName: "whatever",
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
keys: {
expiry_date: Infinity,
client_id: "client_id",
client_secret: "client_secret",
redirect_uris: ["http://localhost:3000/auth/callback"],
},
},
"daily-video": {
slug: "daily-video",
dirName: "whatever",
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
keys: {
expiry_date: Infinity,
api_key: "",
scale_plan: "false",
client_id: "client_id",
client_secret: "client_secret",
redirect_uris: ["http://localhost:3000/auth/callback"],
},
},
},
};
function allowSuccessfulBookingCreation() {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
prismaMock.booking.create.mockImplementation(function (booking) {
return booking.data;
});
}
export class MockError extends Error {
constructor(message: string) {
super(message);
this.name = "MockError";
}
}
export function getOrganizer({
name,
email,
id,
schedules,
credentials,
selectedCalendars,
}: {
name: string;
email: string;
id: number;
schedules: InputUser["schedules"];
credentials?: InputCredential[];
selectedCalendars?: InputSelectedCalendar[];
}) {
return {
...TestData.users.example,
name,
email,
id,
schedules,
credentials,
selectedCalendars,
};
}
export function getScenarioData({
organizer,
eventTypes,
usersApartFromOrganizer = [],
apps = [],
webhooks,
}: // hosts = [],
{
organizer: ReturnType<typeof getOrganizer>;
eventTypes: ScenarioData["eventTypes"];
apps: ScenarioData["apps"];
usersApartFromOrganizer?: ScenarioData["users"];
webhooks?: ScenarioData["webhooks"];
// hosts?: ScenarioData["hosts"];
}) {
const users = [organizer, ...usersApartFromOrganizer];
eventTypes.forEach((eventType) => {
if (
eventType.users?.filter((eventTypeUser) => {
return !users.find((userToCreate) => userToCreate.id === eventTypeUser.id);
}).length
) {
throw new Error(`EventType ${eventType.id} has users that are not present in ScenarioData["users"]`);
}
});
return {
// hosts: [...hosts],
eventTypes: [...eventTypes],
users,
apps: [...apps],
webhooks,
};
}
export function mockEnableEmailFeature() {
prismaMock.feature.findMany.mockResolvedValue([
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
{
slug: "emails",
// It's a kill switch
enabled: false,
},
]);
}
export function mockNoTranslations() {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
i18nMock.getTranslation.mockImplementation(() => {
return new Promise((resolve) => {
const identityFn = (key: string) => key;
resolve(identityFn);
});
});
}
export function mockCalendarToHaveNoBusySlots(metadataLookupKey: keyof typeof appStoreMetadata) {
const appStoreLookupKey = metadataLookupKey;
appStoreMock.default[appStoreLookupKey as keyof typeof appStoreMock.default].mockResolvedValue({
lib: {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
CalendarService: function MockCalendarService() {
return {
createEvent: () => {
return Promise.resolve({
type: "daily_video",
id: "dailyEventName",
password: "dailyvideopass",
url: "http://dailyvideo.example.com",
});
},
getAvailability: (): Promise<EventBusyDate[]> => {
return new Promise((resolve) => {
resolve([]);
});
},
};
},
},
});
}
export function mockSuccessfulVideoMeetingCreation({
metadataLookupKey,
appStoreLookupKey,
}: {
metadataLookupKey: string;
appStoreLookupKey?: string;
}) {
appStoreLookupKey = appStoreLookupKey || metadataLookupKey;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
appStoreMock.default[appStoreLookupKey as keyof typeof appStoreMock.default].mockImplementation(() => {
return new Promise((resolve) => {
resolve({
lib: {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
VideoApiAdapter: () => ({
createMeeting: () => {
return Promise.resolve({
type: appStoreMetadata[metadataLookupKey as keyof typeof appStoreMetadata].type,
id: "MOCK_ID",
password: "MOCK_PASS",
url: `http://mock-${metadataLookupKey}.example.com`,
});
},
}),
},
});
});
});
}
export function mockErrorOnVideoMeetingCreation({
metadataLookupKey,
appStoreLookupKey,
}: {
metadataLookupKey: string;
appStoreLookupKey?: string;
}) {
appStoreLookupKey = appStoreLookupKey || metadataLookupKey;
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
appStoreMock.default[appStoreLookupKey].mockImplementation(() => {
return new Promise((resolve) => {
resolve({
lib: {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
VideoApiAdapter: () => ({
createMeeting: () => {
throw new MockError("Error creating Video meeting");
},
}),
},
});
});
});
}
export function expectWebhookToHaveBeenCalledWith(
subscriberUrl: string,
data: {
triggerEvent: WebhookTriggerEvents;
payload: { metadata: Record<string, unknown>; responses: Record<string, unknown> };
}
) {
const fetchCalls = fetchMock.mock.calls;
const webhookFetchCall = fetchCalls.find((call) => call[0] === subscriberUrl);
if (!webhookFetchCall) {
throw new Error(`Webhook not called with ${subscriberUrl}`);
}
expect(webhookFetchCall[0]).toBe(subscriberUrl);
const body = webhookFetchCall[1]?.body;
const parsedBody = JSON.parse((body as string) || "{}");
console.log({ payload: parsedBody.payload });
expect(parsedBody.triggerEvent).toBe(data.triggerEvent);
parsedBody.payload.metadata.videoCallUrl = parsedBody.payload.metadata.videoCallUrl
? parsedBody.payload.metadata.videoCallUrl.replace(/\/video\/[a-zA-Z0-9]{22}/, "/video/DYNAMIC_UID")
: parsedBody.payload.metadata.videoCallUrl;
expect(parsedBody.payload.metadata).toContain(data.payload.metadata);
expect(parsedBody.payload.responses).toEqual(data.payload.responses);
}
export function expectWorkflowToBeTriggered() {
// TODO: Implement this.
}
export function expectBookingToBeInDatabase(booking: Partial<Prisma.BookingCreateInput>) {
const createBookingCalledWithArgs = prismaMock.booking.create.mock.calls[0];
expect(createBookingCalledWithArgs[0].data).toEqual(expect.objectContaining(booking));
}
export function getBooker({ name, email }: { name: string; email: string }) {
return {
name,
email,
};
}
declare global {
// eslint-disable-next-line @typescript-eslint/no-namespace
namespace jest {
interface Matchers<R> {
toHaveEmail(expectedEmail: { htmlToContain?: string; to: string }): R;
}
}
}
expect.extend({
toHaveEmail(
testEmail: ReturnType<Fixtures["emails"]["get"]>[number],
expectedEmail: {
//TODO: Support email HTML parsing to target specific elements
htmlToContain?: string;
to: string;
}
) {
let isHtmlContained = true;
let isToAddressExpected = true;
if (expectedEmail.htmlToContain) {
isHtmlContained = testEmail.html.includes(expectedEmail.htmlToContain);
}
isToAddressExpected = expectedEmail.to === testEmail.to;
return {
pass: isHtmlContained && isToAddressExpected,
message: () => {
if (!isHtmlContained) {
return `Email HTML is not as expected. Expected:"${expectedEmail.htmlToContain}" isn't contained in "${testEmail.html}"`;
}
return `Email To address is not as expected. Expected:${expectedEmail.to} isn't contained in ${testEmail.to}`;
},
};
},
});
+2 -1
View File
@@ -89,7 +89,8 @@
"prettier": "^2.8.6", "prettier": "^2.8.6",
"tsc-absolute": "^1.0.0", "tsc-absolute": "^1.0.0",
"typescript": "^4.9.4", "typescript": "^4.9.4",
"vitest": "^0.31.1", "vitest": "^0.34.3",
"vitest-fetch-mock": "^0.2.2",
"vitest-mock-extended": "^1.1.3" "vitest-mock-extended": "^1.1.3"
}, },
"dependencies": { "dependencies": {
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "Basecamp3", "name": "Basecamp3",
"slug": "basecamp3", "slug": "basecamp3",
"type": "basecamp3_other_calendar", "type": "basecamp3_other_calendar",
"logo": "logo.svg", "logo": "icon-dark.svg",
"url": "https://basecamp.com/", "url": "https://basecamp.com/",
"variant": "other", "variant": "other",
"categories": ["other"], "categories": ["other"],
+28 -16
View File
@@ -1,26 +1,38 @@
<svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="128" height="128" viewBox="0 0 128 128" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_117_4)"> <g clip-path="url(#clip0_21_40)">
<rect width="128" height="128" fill="white"/> <mask id="mask0_21_40" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="0" y="0" width="128" height="128">
<circle cx="64" cy="64" r="64" fill="#04BF8A"/> <path d="M128 0H0V128H128V0Z" fill="white"/>
<mask id="path-2-inside-1_117_4" fill="white">
<path d="M32.7099 74.7566C29.6119 75.9781 26.0314 74.4473 25.5846 71.1473C25.1747 68.1192 25.3114 65.0002 26.0042 61.9169C27.1525 56.8057 29.7838 51.9924 33.6065 48.0106C37.4291 44.0289 42.2937 41.0341 47.6612 39.3584C50.9977 38.3167 54.4475 37.8099 57.8599 37.8459C61.1841 37.8809 63.1528 41.2619 62.1562 44.4334V44.4334C61.2866 47.2009 58.433 48.7691 55.5372 48.9409C53.9259 49.0365 52.3131 49.3307 50.7418 49.8213C47.4989 50.8338 44.5597 52.6432 42.2501 55.0489C39.9405 57.4547 38.3507 60.3628 37.6569 63.4509C37.418 64.5141 37.2885 65.5844 37.2675 66.6474C37.2014 69.9769 35.8078 73.5351 32.7099 74.7566V74.7566Z"/>
</mask> </mask>
<path d="M32.7099 74.7566C29.6119 75.9781 26.0314 74.4473 25.5846 71.1473C25.1747 68.1192 25.3114 65.0002 26.0042 61.9169C27.1525 56.8057 29.7838 51.9924 33.6065 48.0106C37.4291 44.0289 42.2937 41.0341 47.6612 39.3584C50.9977 38.3167 54.4475 37.8099 57.8599 37.8459C61.1841 37.8809 63.1528 41.2619 62.1562 44.4334V44.4334C61.2866 47.2009 58.433 48.7691 55.5372 48.9409C53.9259 49.0365 52.3131 49.3307 50.7418 49.8213C47.4989 50.8338 44.5597 52.6432 42.2501 55.0489C39.9405 57.4547 38.3507 60.3628 37.6569 63.4509C37.418 64.5141 37.2885 65.5844 37.2675 66.6474C37.2014 69.9769 35.8078 73.5351 32.7099 74.7566V74.7566Z" fill="white" stroke="white" stroke-width="2" mask="url(#path-2-inside-1_117_4)"/> <g mask="url(#mask0_21_40)">
<mask id="path-3-inside-2_117_4" fill="white"> <path d="M64 128C99.3462 128 128 99.3462 128 64C128 28.6538 99.3462 0 64 0C28.6538 0 0 28.6538 0 64C0 99.3462 28.6538 128 64 128Z" fill="#04BF8A"/>
<path d="M52.9036 31.2935C51.7371 28.1744 53.331 24.6215 56.6383 24.2332C59.6732 23.8768 62.7894 24.0688 65.8599 24.8159C70.95 26.0545 75.716 28.7705 79.6295 32.663C83.543 36.5554 86.4513 41.4723 88.0318 46.8685C89.0144 50.2229 89.46 53.6812 89.3637 57.0924C89.2699 60.4155 85.8546 62.3241 82.7012 61.2715V61.2715C79.9496 60.353 78.4321 57.4722 78.3115 54.5738C78.2444 52.9611 77.9788 51.3433 77.5161 49.7636C76.5611 46.5033 74.804 43.5326 72.4395 41.1808C70.0749 38.829 67.1954 37.188 64.12 36.4396C63.0612 36.182 61.9934 36.0336 60.9309 35.9938C57.6031 35.8689 54.0701 34.4126 52.9036 31.2935V31.2935Z"/> <mask id="mask1_21_40" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="24" y="36" width="40" height="41">
<path d="M32.7098 74.7567C29.6118 75.9782 26.0313 74.4474 25.5845 71.1474C25.1746 68.1193 25.3113 65.0003 26.0041 61.917C27.1524 56.8058 29.7837 51.9925 33.6064 48.0107C37.429 44.029 42.2936 41.0342 47.6611 39.3585C50.9976 38.3168 54.4474 37.81 57.8598 37.846C61.184 37.881 63.1527 41.262 62.1561 44.4335C61.2865 47.201 58.4329 48.7692 55.5371 48.941C53.9258 49.0366 52.313 49.3308 50.7417 49.8214C47.4988 50.8339 44.5596 52.6433 42.25 55.049C39.9404 57.4548 38.3506 60.3629 37.6568 63.451C37.4179 64.5142 37.2884 65.5845 37.2674 66.6475C37.2013 69.977 35.8077 73.5352 32.7098 74.7567Z" fill="white" stroke="white" stroke-width="2"/>
</mask> </mask>
<path d="M52.9036 31.2935C51.7371 28.1744 53.331 24.6215 56.6383 24.2332C59.6732 23.8768 62.7894 24.0688 65.8599 24.8159C70.95 26.0545 75.716 28.7705 79.6295 32.663C83.543 36.5554 86.4513 41.4723 88.0318 46.8685C89.0144 50.2229 89.46 53.6812 89.3637 57.0924C89.2699 60.4155 85.8546 62.3241 82.7012 61.2715V61.2715C79.9496 60.353 78.4321 57.4722 78.3115 54.5738C78.2444 52.9611 77.9788 51.3433 77.5161 49.7636C76.5611 46.5033 74.804 43.5326 72.4395 41.1808C70.0749 38.829 67.1954 37.188 64.12 36.4396C63.0612 36.182 61.9934 36.0336 60.9309 35.9938C57.6031 35.8689 54.0701 34.4126 52.9036 31.2935V31.2935Z" fill="white" stroke="white" stroke-width="2" mask="url(#path-3-inside-2_117_4)"/> <g mask="url(#mask1_21_40)">
<mask id="path-4-inside-3_117_4" fill="white"> <path d="M32.7098 74.7567C29.6118 75.9782 26.0313 74.4474 25.5845 71.1474C25.1746 68.1193 25.3113 65.0003 26.0041 61.917C27.1524 56.8058 29.7837 51.9925 33.6064 48.0107C37.429 44.029 42.2936 41.0342 47.6611 39.3585C50.9976 38.3168 54.4474 37.81 57.8598 37.846C61.184 37.881 63.1527 41.262 62.1561 44.4335C61.2865 47.201 58.4329 48.7692 55.5371 48.941C53.9258 49.0366 52.313 49.3308 50.7417 49.8214C47.4988 50.8339 44.5596 52.6433 42.25 55.049C39.9404 57.4548 38.3506 60.3629 37.6568 63.451C37.4179 64.5142 37.2884 65.5845 37.2674 66.6475C37.2013 69.977 35.8077 73.5352 32.7098 74.7567Z" fill="white" stroke="white" stroke-width="2"/>
<path d="M97.7468 52.0457C100.912 51.0099 104.395 52.7501 104.646 56.0708C104.876 59.1178 104.554 62.2233 103.68 65.2601C102.231 70.2944 99.3192 74.9433 95.2674 78.6916C91.2156 82.4399 86.1821 85.1412 80.7248 86.4961C77.3324 87.3383 73.8587 87.6398 70.4544 87.4017C67.1381 87.1698 65.3731 83.6782 66.5559 80.5713V80.5713C67.5879 77.8602 70.5294 76.4638 73.4303 76.4638C75.0444 76.4638 76.6718 76.2656 78.2694 75.869C81.5666 75.0504 84.6078 73.4183 87.0559 71.1536C89.5039 68.8889 91.2632 66.0801 92.1388 63.0385C92.4402 61.9913 92.6328 60.9306 92.7168 59.8706C92.98 56.551 94.5819 53.0816 97.7468 52.0457V52.0457Z"/> </g>
<mask id="mask2_21_40" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="51" y="23" width="40" height="40">
<path d="M52.9037 31.2934C51.7372 28.1743 53.3311 24.6214 56.6384 24.2331C59.6733 23.8767 62.7895 24.0687 65.86 24.8158C70.9501 26.0544 75.7161 28.7704 79.6296 32.6629C83.5431 36.5553 86.4514 41.4722 88.0319 46.8684C89.0145 50.2228 89.4601 53.6811 89.3638 57.0923C89.27 60.4154 85.8547 62.324 82.7013 61.2714C79.9497 60.3529 78.4322 57.4721 78.3116 54.5737C78.2445 52.961 77.9789 51.3432 77.5162 49.7635C76.5612 46.5032 74.8041 43.5325 72.4396 41.1807C70.075 38.8289 67.1955 37.1879 64.1201 36.4395C63.0613 36.1819 61.9935 36.0335 60.931 35.9937C57.6032 35.8688 54.0702 34.4125 52.9037 31.2934Z" fill="white" stroke="white" stroke-width="2"/>
</mask> </mask>
<path d="M97.7468 52.0457C100.912 51.0099 104.395 52.7501 104.646 56.0708C104.876 59.1178 104.554 62.2233 103.68 65.2601C102.231 70.2944 99.3192 74.9433 95.2674 78.6916C91.2156 82.4399 86.1821 85.1412 80.7248 86.4961C77.3324 87.3383 73.8587 87.6398 70.4544 87.4017C67.1381 87.1698 65.3731 83.6782 66.5559 80.5713V80.5713C67.5879 77.8602 70.5294 76.4638 73.4303 76.4638C75.0444 76.4638 76.6718 76.2656 78.2694 75.869C81.5666 75.0504 84.6078 73.4183 87.0559 71.1536C89.5039 68.8889 91.2632 66.0801 92.1388 63.0385C92.4402 61.9913 92.6328 60.9306 92.7168 59.8706C92.98 56.551 94.5819 53.0816 97.7468 52.0457V52.0457Z" fill="white" stroke="white" stroke-width="2" mask="url(#path-4-inside-3_117_4)"/> <g mask="url(#mask2_21_40)">
<mask id="path-5-inside-4_117_4" fill="white"> <path d="M52.9037 31.2934C51.7372 28.1743 53.3311 24.6214 56.6384 24.2331C59.6733 23.8767 62.7895 24.0687 65.86 24.8158C70.9501 26.0544 75.7161 28.7704 79.6296 32.6629C83.5431 36.5553 86.4514 41.4722 88.0319 46.8684C89.0145 50.2228 89.4601 53.6811 89.3638 57.0923C89.27 60.4154 85.8547 62.324 82.7013 61.2714C79.9497 60.3529 78.4322 57.4721 78.3116 54.5737C78.2445 52.961 77.9789 51.3432 77.5162 49.7635C76.5612 46.5032 74.8041 43.5325 72.4396 41.1807C70.075 38.8289 67.1955 37.1879 64.1201 36.4395C63.0613 36.1819 61.9935 36.0335 60.931 35.9937C57.6032 35.8688 54.0702 34.4125 52.9037 31.2934Z" fill="white" stroke="white" stroke-width="2"/>
<path d="M75.895 95.1969C77.127 98.2907 75.6083 101.876 72.3099 102.334C69.2832 102.755 66.1637 102.628 63.0781 101.946C57.963 100.815 53.1408 98.2 49.1462 94.3909C45.1515 90.5817 42.1403 85.7273 40.4464 80.3655C39.3934 77.0326 38.8749 73.5845 38.8994 70.172C38.9232 66.8477 42.2974 64.8675 45.4723 65.8534V65.8534C48.2427 66.7137 49.8205 69.5619 50.0022 72.4571C50.1033 74.0681 50.4029 75.6799 50.8988 77.2495C51.9223 80.489 53.7416 83.422 56.1551 85.7234C58.5687 88.0249 61.4822 89.6048 64.5727 90.2882C65.6367 90.5235 66.7073 90.6493 67.7705 90.6668C71.1001 90.7215 74.663 92.1031 75.895 95.1969V95.1969Z"/> </g>
<mask id="mask3_21_40" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="65" y="50" width="41" height="39">
<path d="M97.747 52.0457C100.912 51.0099 104.395 52.7501 104.646 56.0708C104.876 59.1178 104.554 62.2233 103.68 65.2601C102.231 70.2944 99.3194 74.9433 95.2676 78.6916C91.2158 82.4399 86.1823 85.1412 80.725 86.4961C77.3326 87.3383 73.8589 87.6398 70.4546 87.4017C67.1383 87.1698 65.3733 83.6782 66.5561 80.5713C67.5881 77.8602 70.5296 76.4638 73.4305 76.4638C75.0446 76.4638 76.672 76.2656 78.2696 75.869C81.5668 75.0504 84.608 73.4183 87.0561 71.1536C89.5041 68.8889 91.2634 66.0801 92.139 63.0385C92.4404 61.9913 92.633 60.9306 92.717 59.8706C92.9802 56.551 94.5821 53.0816 97.747 52.0457Z" fill="white" stroke="white" stroke-width="2"/>
</mask> </mask>
<path d="M75.895 95.1969C77.127 98.2907 75.6083 101.876 72.3099 102.334C69.2832 102.755 66.1637 102.628 63.0781 101.946C57.963 100.815 53.1408 98.2 49.1462 94.3909C45.1515 90.5817 42.1403 85.7273 40.4464 80.3655C39.3934 77.0326 38.8749 73.5845 38.8994 70.172C38.9232 66.8477 42.2974 64.8675 45.4723 65.8534V65.8534C48.2427 66.7137 49.8205 69.5619 50.0022 72.4571C50.1033 74.0681 50.4029 75.6799 50.8988 77.2495C51.9223 80.489 53.7416 83.422 56.1551 85.7234C58.5687 88.0249 61.4822 89.6048 64.5727 90.2882C65.6367 90.5235 66.7073 90.6493 67.7705 90.6668C71.1001 90.7215 74.663 92.1031 75.895 95.1969V95.1969Z" fill="white" stroke="white" stroke-width="2" mask="url(#path-5-inside-4_117_4)"/> <g mask="url(#mask3_21_40)">
<path d="M97.747 52.0457C100.912 51.0099 104.395 52.7501 104.646 56.0708C104.876 59.1178 104.554 62.2233 103.68 65.2601C102.231 70.2944 99.3194 74.9433 95.2676 78.6916C91.2158 82.4399 86.1823 85.1412 80.725 86.4961C77.3326 87.3383 73.8589 87.6398 70.4546 87.4017C67.1383 87.1698 65.3733 83.6782 66.5561 80.5713C67.5881 77.8602 70.5296 76.4638 73.4305 76.4638C75.0446 76.4638 76.672 76.2656 78.2696 75.869C81.5668 75.0504 84.608 73.4183 87.0561 71.1536C89.5041 68.8889 91.2634 66.0801 92.139 63.0385C92.4404 61.9913 92.633 60.9306 92.717 59.8706C92.9802 56.551 94.5821 53.0816 97.747 52.0457Z" fill="white" stroke="white" stroke-width="2"/>
</g>
<mask id="mask4_21_40" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="37" y="64" width="41" height="40">
<path d="M75.8949 95.1969C77.1269 98.2907 75.6082 101.876 72.3098 102.334C69.2831 102.755 66.1636 102.628 63.078 101.946C57.9629 100.815 53.1407 98.2 49.1461 94.3909C45.1514 90.5817 42.1402 85.7273 40.4463 80.3655C39.3933 77.0326 38.8748 73.5845 38.8993 70.172C38.9231 66.8477 42.2973 64.8675 45.4722 65.8534C48.2426 66.7137 49.8204 69.5619 50.0021 72.4571C50.1032 74.0681 50.4028 75.6799 50.8987 77.2495C51.9222 80.489 53.7415 83.422 56.155 85.7234C58.5686 88.0249 61.4821 89.6048 64.5726 90.2882C65.6366 90.5235 66.7072 90.6493 67.7704 90.6668C71.1 90.7215 74.6629 92.1031 75.8949 95.1969Z" fill="white" stroke="white" stroke-width="2"/>
</mask>
<g mask="url(#mask4_21_40)">
<path d="M75.8949 95.1969C77.1269 98.2907 75.6082 101.876 72.3098 102.334C69.2831 102.755 66.1636 102.628 63.078 101.946C57.9629 100.815 53.1407 98.2 49.1461 94.3909C45.1514 90.5817 42.1402 85.7273 40.4463 80.3655C39.3933 77.0326 38.8748 73.5845 38.8993 70.172C38.9231 66.8477 42.2973 64.8675 45.4722 65.8534C48.2426 66.7137 49.8204 69.5619 50.0021 72.4571C50.1032 74.0681 50.4028 75.6799 50.8987 77.2495C51.9222 80.489 53.7415 83.422 56.155 85.7234C58.5686 88.0249 61.4821 89.6048 64.5726 90.2882C65.6366 90.5235 66.7072 90.6493 67.7704 90.6668C71.1 90.7215 74.6629 92.1031 75.8949 95.1969Z" fill="white" stroke="white" stroke-width="2"/>
</g>
</g>
</g> </g>
<defs> <defs>
<clipPath id="clip0_117_4"> <clipPath id="clip0_21_40">
<rect width="128" height="128" fill="white"/> <rect width="128" height="128" fill="white"/>
</clipPath> </clipPath>
</defs> </defs>

Before

Width:  |  Height:  |  Size: 5.7 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

+3 -3
View File
@@ -4,12 +4,12 @@
"slug": "make", "slug": "make",
"type": "make_automation", "type": "make_automation",
"logo": "icon.svg", "logo": "icon.svg",
"url": "https://cal.com/apps/make", "url": "https://github.com/aar2dee2",
"variant": "automation", "variant": "automation",
"categories": ["automation"], "categories": ["automation"],
"publisher": "aa2dee2", "publisher": "aar2dee2",
"email": "support@cal.com", "email": "support@cal.com",
"description": "Automate workflows", "description": "From tasks and workflows to apps and systems, build and automate anything in one powerful visual platform.",
"isTemplate": false, "isTemplate": false,
"__createdUsingCli": true, "__createdUsingCli": true,
"__template": "basic", "__template": "basic",
@@ -112,7 +112,7 @@ export default function MakeSetup({ inviteLink }: InferGetStaticPropsType<typeof
</> </>
<ol className="mb-5 ml-5 mt-5 list-decimal ltr:mr-5 rtl:ml-5"> <ol className="mb-5 ml-5 mt-5 list-decimal ltr:mr-5 rtl:ml-5">
<Trans i18nKey="invite_link_make"> <Trans i18nKey="make_setup_instructions">
<li> <li>
Go to Go to
<a href={inviteLink} className="ml-1 mr-1 text-orange-600 underline"> <a href={inviteLink} className="ml-1 mr-1 text-orange-600 underline">
@@ -120,9 +120,6 @@ export default function MakeSetup({ inviteLink }: InferGetStaticPropsType<typeof
</a> </a>
and install the Cal.com app. and install the Cal.com app.
</li> </li>
</Trans>
<Trans i18nKey="make_setup_instructions">
<li>Log into your Make account and create a new Scenario.</li> <li>Log into your Make account and create a new Scenario.</li>
<li>Select Cal.com as your Trigger app. Also choose a Trigger event.</li> <li>Select Cal.com as your Trigger app. Also choose a Trigger event.</li>
<li>Choose your account and then enter your Unique API Key.</li> <li>Choose your account and then enter your Unique API Key.</li>
+15 -950
View File
@@ -1,951 +1,16 @@
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" <svg width="384" height="216" viewBox="0 0 384 216" fill="none" xmlns="http://www.w3.org/2000/svg">
width="100%" viewBox="0 0 3840 2160" enable-background="new 0 0 3840 2160" xml:space="preserve"> <path d="M196.601 47.4891C198.789 44.6834 200.93 41.8388 203.179 39.0832C205.427 36.3291 207.746 33.6302 210.106 30.9714C211.872 28.9822 213.694 27.0348 215.594 25.1738C220.836 20.0393 226.44 15.3517 232.761 11.5715C238.194 8.32227 243.947 5.87709 250.143 4.49669C254.82 3.45493 259.548 3.17372 264.314 3.42818C272.145 3.84623 279.562 5.87585 286.651 9.19412C293.241 12.2784 299.198 16.3139 304.639 21.1162C306.683 22.9204 308.68 24.7896 310.574 26.7489C314.929 31.2527 318.825 36.1397 322.358 41.3138C326.269 47.0406 329.71 53.0403 332.717 59.2865C336.183 66.4874 339.081 73.9132 341.473 81.54C343.106 86.7442 344.553 91.998 345.644 97.3392C346.528 101.663 347.277 106.014 348.018 110.365C348.407 112.652 348.743 114.956 348.929 117.266C349.054 118.81 349.275 120.342 349.385 121.885C349.545 124.136 349.701 126.387 349.827 128.641C349.922 130.332 349.99 132.026 350.027 133.719C350.091 136.646 350.216 139.576 350.143 142.501C350.061 145.817 349.864 149.134 349.584 152.44C348.895 160.576 347.376 168.554 344.722 176.292C342.89 181.63 340.533 186.729 337.36 191.408C336.037 193.358 334.506 195.166 332.93 197.025C332.437 196.94 332.085 196.821 331.73 196.81C330.798 196.781 329.864 196.809 328.931 196.797C328.175 196.787 328.075 196.739 327.914 195.989C327.804 195.477 327.82 194.935 327.803 194.406C327.791 194.008 327.727 193.606 327.246 193.625C326.569 193.652 326.393 193.225 326.27 192.718C326.166 192.289 325.99 191.972 325.478 191.997C325.019 192.02 324.823 191.737 324.756 191.332C324.696 190.975 324.61 190.616 324.607 190.257C324.592 188.491 324.607 186.724 324.597 184.958C324.593 184.193 324.582 184.172 323.795 184.004C323.454 183.931 323.251 183.78 323.188 183.446C323.12 183.09 323.023 182.734 323.008 182.375C322.98 181.676 322.989 180.975 323.003 180.276C323.015 179.678 322.821 179.283 322.194 179.082C321.4 178.829 321.404 178.787 321.402 177.952C321.396 175.986 321.428 174.019 321.391 172.053C321.362 170.462 321.529 168.868 321.229 167.276C321.129 166.741 320.979 166.372 320.47 166.26C319.867 166.128 319.79 165.743 319.794 165.225C319.809 163.259 319.812 161.293 319.792 159.327C319.787 158.781 319.947 158.475 320.514 158.321C321.534 158.044 321.397 157.917 321.399 157.053C321.403 155.22 321.399 153.387 321.401 151.554C321.401 150.614 321.328 150.54 322.28 150.281C322.84 150.129 323.018 149.831 323.008 149.28C322.984 147.814 323.004 146.347 322.999 144.881C322.995 143.998 323 143.962 322.144 143.692C321.619 143.526 321.387 143.28 321.39 142.707C321.41 139.108 321.408 135.509 321.392 131.91C321.39 131.375 321.61 131.123 322.106 131.01C322.99 130.808 322.998 130.796 322.998 129.932C323.002 125.3 323.002 120.667 322.998 116.035C322.997 115.125 322.948 115.057 322.068 114.788C321.636 114.656 321.38 114.457 321.393 113.954C321.419 112.955 321.408 111.955 321.398 110.955C321.394 110.527 321.556 110.253 321.996 110.177C322.818 110.034 323.019 109.504 323.012 108.731C322.983 105.799 323.002 102.866 322.999 99.9333C322.998 98.9967 322.995 98.9881 322.103 98.6645C321.785 98.5491 321.393 98.4846 321.422 98.0633C321.468 97.3914 321.049 97.2116 320.535 97.07C320.219 96.9826 319.799 96.9203 319.83 96.4958C319.882 95.7664 319.4 95.5975 318.872 95.4508C318.532 95.3565 318.245 95.2446 318.204 94.8264C318.151 94.3006 318.012 93.7771 318.017 93.2535C318.022 92.6738 317.735 92.3861 317.246 92.2442C316.899 92.1435 316.582 92.0165 316.613 91.6023C316.661 90.97 316.232 90.8331 315.772 90.6839C315.467 90.5851 315.018 90.5576 315.038 90.1341C315.076 89.3706 314.587 89.1725 314.014 89.0329C313.649 88.9439 313.393 88.7757 313.406 88.3675C313.43 87.6421 312.966 87.5672 312.372 87.5375C311.725 85.6462 311.137 83.8107 310.508 81.9892C308.073 74.9309 305.072 68.125 301.392 61.6218C298.119 55.8367 294.326 50.423 289.791 45.5567C286.559 42.0876 282.977 39.0096 278.946 36.4863C273.238 32.9128 267.09 30.7022 260.299 30.4159C256.978 30.2759 253.733 30.6424 250.544 31.5434C246.066 32.8086 242.071 35.0274 238.361 37.7921C234.502 40.6672 231.069 44.0037 227.882 47.5926C224.079 51.8751 220.595 56.4122 217.34 61.1231C215.58 63.6695 213.856 66.2409 212.068 68.7589C211.548 68.0777 211.061 67.4479 210.604 66.7979C208.733 64.139 206.902 61.4514 204.998 58.817C202.823 55.8089 200.587 52.8456 198.376 49.8639C197.787 49.0701 197.193 48.2806 196.601 47.4891Z" fill="#0081FA"/>
<path fill="#FFFFFF" opacity="1.000000" stroke="none" <path d="M192.401 102.309C191.69 103.508 190.959 104.695 190.271 105.907C186.871 111.895 183.483 117.89 180.09 123.882C175.943 131.205 171.829 138.548 167.638 145.846C163.56 152.946 159.308 159.94 154.824 166.794C151.596 171.726 148.243 176.567 144.682 181.263C141.827 185.028 138.826 188.669 135.618 192.143C131.906 196.161 127.948 199.899 123.531 203.137C117.376 207.648 110.596 210.76 103.07 212.137C99.8662 212.724 96.628 213.066 93.3611 213.032C91.3292 213.011 89.2901 213.091 87.2671 212.946C83.3889 212.668 79.5557 212.071 75.7977 211.021C70.7292 209.605 65.9636 207.527 61.5694 204.626C58.0253 202.287 54.8539 199.515 51.9991 196.366C48.1891 192.163 45.1606 187.448 42.7087 182.354C40.5534 177.877 38.8908 173.211 37.6976 168.39C37.0568 165.801 36.5778 163.173 36.1008 160.464C36.4175 159.907 36.6592 159.449 36.9076 158.978C36.6323 158.45 36.2007 158.743 35.811 158.8C35.6441 157.729 35.4438 156.662 35.3181 155.586C35.1309 153.983 34.9965 152.375 34.9468 150.684C35.8534 150.599 36.6528 150.6 37.4522 150.598C37.9668 150.597 38.3437 150.395 38.5413 149.891C38.8906 149.001 38.8965 149.003 39.8593 149C40.0591 148.999 40.2591 149.004 40.4588 148.999C41.3727 148.976 41.4997 148.862 41.8127 147.997C41.8913 147.779 42.093 147.466 42.2654 147.448C42.9118 147.377 43.2545 146.97 43.4464 146.6C44.0949 146.6 44.6234 146.561 45.1421 146.615C45.4487 146.647 45.8114 146.753 46.0225 146.957C46.396 147.317 46.7924 147.421 47.2846 147.407C48.1499 147.382 49.0166 147.39 49.8825 147.403C50.6359 147.415 50.6357 147.427 50.8018 148.143C50.9562 148.808 51.1334 148.97 51.8098 148.996C52.342 149.016 52.8806 148.963 53.4057 149.028C53.6072 149.053 53.7791 149.317 53.9645 149.471C53.811 149.625 53.6823 149.834 53.4971 149.917C53.2964 150.006 53.0434 149.991 52.8126 149.997C52.3799 150.008 51.9466 150.004 51.5136 150.002C51.0784 150 50.8739 150.195 50.7913 150.644C50.6324 151.508 50.5004 151.589 49.5865 151.598C48.6872 151.607 47.7875 151.588 46.8885 151.604C46.1313 151.618 46.0274 151.736 46.0003 152.475C45.9675 153.372 46.1807 153.731 46.8439 153.788C47.3068 153.829 47.7763 153.812 48.2421 153.797C48.7577 153.78 49.1748 153.854 49.2265 154.5C49.2378 154.641 49.3592 154.816 49.4817 154.898C49.999 155.246 51.1216 154.965 51.3599 154.367C51.5491 153.893 51.8377 153.768 52.2746 153.802C53.9107 153.929 55.5128 153.668 57.1171 153.404C57.441 153.351 57.7428 153.285 57.7701 152.923C57.8243 152.206 58.2982 152.177 58.8339 152.198C59.1 152.209 59.3686 152.219 59.6329 152.195C60.3021 152.135 60.8829 151.935 61.0052 151.153C61.0695 150.743 61.3254 150.602 61.7051 150.602C62.1048 150.603 62.5072 150.628 62.9036 150.591C63.5378 150.532 64.0844 150.306 64.1985 149.582C64.2727 149.111 64.5646 148.994 64.9761 149C65.3424 149.005 65.7089 149.004 66.0752 149.001C66.3998 149 66.6829 149.079 66.7743 149.432C66.9566 150.138 67.4734 150.241 68.0893 150.203C68.388 150.185 68.6887 150.2 69.0087 150.28C69.0732 150.553 69.1399 150.744 69.1586 150.94C69.4636 154.124 70.1157 157.242 71.0372 160.3C72.2665 164.378 74.0371 168.191 76.7831 171.495C79.8486 175.183 83.7223 177.55 88.4312 178.484C90.6823 178.931 92.9539 179.044 95.2615 178.856C98.2112 178.616 101.03 177.97 103.711 176.722C107.13 175.132 110.058 172.844 112.773 170.271C115.53 167.66 118.012 164.792 120.385 161.833C125.302 155.702 129.773 149.248 134.127 142.714C137.172 138.145 140.155 133.535 143.127 128.919C145.757 124.836 148.326 120.714 150.938 116.62C152.226 114.601 153.552 112.607 154.947 110.601C155.534 110.6 156.034 110.615 156.533 110.593C157.12 110.566 157.54 110.282 157.731 109.708C157.802 109.496 157.857 109.278 157.937 108.998C158.671 108.998 159.366 109.019 160.06 108.992C160.691 108.967 160.958 108.696 160.992 108.07C161.02 107.572 161.008 107.071 160.998 106.572C160.989 106.119 161.167 105.71 161.599 105.656C162.58 105.533 162.644 104.896 162.602 104.141C162.589 103.909 162.606 103.675 162.599 103.442C162.581 102.861 162.812 102.485 163.422 102.397C163.873 102.331 164.135 102.066 164.197 101.614C164.266 101.114 164.553 100.867 165.046 100.789C165.6 100.701 165.813 100.324 165.801 99.7867C165.792 99.3873 165.807 98.9875 165.799 98.5881C165.789 98.0945 165.984 97.7039 166.481 97.6309C167.223 97.522 167.359 97.0189 167.396 96.4204C167.415 96.1219 167.393 95.8211 167.401 95.5216C167.423 94.7485 167.47 94.6557 168.247 94.4048C168.577 94.298 168.759 94.1469 168.798 93.8001C168.853 93.3083 168.979 92.8198 168.987 92.3283C168.997 91.7654 169.146 91.3595 169.73 91.1885C170.386 90.9963 170.426 90.4698 170.402 89.9075C170.378 89.3493 170.489 88.7437 169.703 88.5616C169.567 88.5301 169.482 88.2802 169.387 88.065C170.493 86.2965 171.575 84.5867 172.683 82.8938C173.844 81.1196 175.03 79.3616 176.266 77.6274C177.245 78.9541 178.204 80.2234 179.075 81.5505C182.625 86.9582 186.158 92.3769 189.673 97.8071C190.626 99.2794 191.494 100.807 192.401 102.309Z" fill="#0081FB"/>
d=" <path d="M52.5957 59.991C53.3347 58.4678 54.026 56.9192 54.8218 55.4263C57.0445 51.2564 59.4285 47.1785 62.0604 43.2522C65.2118 38.551 68.6125 34.0403 72.4111 29.835C76.5917 25.2068 81.085 20.9199 86.0813 17.1747C92.6022 12.2865 99.6805 8.46519 107.476 6.02223C110.714 5.00723 114.021 4.29562 117.382 3.82819C121.643 3.23567 125.933 3.17693 130.203 3.46212C138.88 4.0416 147.137 6.25439 154.95 10.1393C161.519 13.4056 167.48 17.5521 173.031 22.3085C175.2 24.1679 177.281 26.1346 179.345 28.1126C180.808 29.5145 182.205 30.9882 183.575 32.4818C185.925 35.0433 188.236 37.64 190.549 40.2348C191.095 40.8468 191.583 41.5101 192.135 42.2615C192.111 42.4482 192.061 42.5384 191.986 42.5962C189.522 44.4949 187.06 46.3954 184.589 48.2855C180.91 51.1002 177.228 53.9096 173.543 56.7165C171.674 58.1399 169.803 59.5595 167.923 60.9678C167.077 61.6011 166.208 62.2028 165.29 62.7916C162.279 59.1597 159.196 55.6771 155.873 52.4062C152.64 49.2237 149.205 46.2967 145.382 43.8414C142.375 41.9096 139.196 40.335 135.775 39.2713C133.1 38.4399 130.371 37.9534 127.573 37.7451C125.38 37.5819 123.2 37.5556 121.031 37.8615C116.344 38.5225 112.08 40.3156 108.119 42.8641C103.918 45.5666 100.281 48.9137 97.0128 52.6704C92.6924 57.6359 89.0902 63.0931 85.9822 68.8855C85.4183 69.9364 84.8289 70.9737 84.1733 72.0119C83.7636 71.8688 83.3699 71.8021 83.1136 71.5781C82.6285 71.1543 82.114 70.9449 81.4773 70.9969C81.1343 71.0249 80.7948 70.9916 80.6205 70.6304C80.4016 70.1768 80.0002 70.2097 79.595 70.1943C79.2025 70.1795 78.655 70.2642 78.4513 70.0469C77.9433 69.5048 77.3895 69.3626 76.6969 69.3631C76.4312 69.3633 76.1125 69.1772 75.9112 68.9805C75.562 68.6394 75.1711 68.5906 74.7245 68.5925C74.3648 68.594 73.8533 68.665 73.6744 68.4664C73.203 67.9431 72.5116 67.8551 72.0217 67.4566C71.561 67.0819 71.1073 67.0069 70.561 66.9812C70.188 66.9637 69.7364 66.8646 69.4778 66.6287C69.1843 66.361 68.9277 66.2064 68.5373 66.1769C68.3223 66.1607 68.0302 66.0585 67.9251 65.8964C67.5932 65.3847 67.1196 65.3644 66.6106 65.4021C66.0561 65.443 65.5636 65.3711 65.1742 64.8987C65.0438 64.7405 64.7792 64.69 64.5724 64.5984C64.3622 64.5054 64.0485 64.4825 63.9527 64.3244C63.6075 63.7546 63.0853 63.8195 62.5505 63.7862C62.2024 63.7644 61.752 63.7139 61.5442 63.4921C61.2145 63.1401 60.8817 62.994 60.428 62.9609C60.2471 62.9477 60.0017 62.836 59.9146 62.6915C59.5948 62.1606 59.104 62.168 58.6001 62.2035C58.0423 62.2427 57.5703 62.1428 57.1609 61.6974C56.9893 61.5106 56.6384 61.4561 56.3578 61.4108C56.0656 61.3637 55.7477 61.3456 55.4624 61.4098C54.4499 61.6377 54.0114 60.4131 53.0522 60.4808C52.9123 60.4907 52.7485 60.1627 52.5957 59.991Z" fill="#0264E0"/>
M2510.000000,2162.000000 <path d="M165.35 62.8189C166.208 62.2029 167.077 61.6013 167.923 60.968C169.803 59.5596 171.674 58.1401 173.543 56.7166C177.228 53.9097 180.91 51.1003 184.589 48.2856C187.06 46.3955 189.522 44.4951 191.986 42.5963C192.061 42.5386 192.111 42.4484 192.185 42.3091C192.843 42.9844 193.504 43.7113 194.131 44.4667C194.932 45.4322 195.705 46.4207 196.546 47.4443C197.193 48.2807 197.787 49.0702 198.376 49.864C200.587 52.8457 202.823 55.809 204.998 58.8171C206.902 61.4515 208.733 64.139 210.604 66.7979C211.061 67.448 211.547 68.0777 212.079 68.832C213.776 71.4541 215.442 73.9431 217.045 76.4715C220.324 81.6405 223.636 86.7899 226.813 92.0209C233.116 102.398 239.273 112.863 245.613 123.217C250.268 130.82 255.118 138.305 259.882 145.842C260.662 147.076 261.444 148.309 262.195 149.61C261.861 149.917 261.589 150.233 261.245 150.38C260.507 150.695 260.415 150.745 260.403 151.513C260.39 152.379 260.411 153.245 260.396 154.111C260.384 154.829 260.269 154.971 259.623 155.198C258.895 155.453 258.815 155.553 258.802 156.342C258.791 157.042 258.774 157.742 258.806 158.44C258.864 159.719 258.657 160.079 257.191 160.006C256.494 159.972 255.793 159.989 255.094 160.004C254.335 160.02 254.117 160.163 254.016 160.876C253.948 161.362 253.759 161.55 253.273 161.617C252.591 161.71 252.435 161.93 252.404 162.596C252.385 162.995 252.406 163.395 252.399 163.795C252.384 164.698 252.306 164.83 251.437 164.992C250.986 165.077 250.799 165.288 250.802 165.721C250.804 166.187 250.812 166.654 250.797 167.12C250.773 167.9 250.593 168.09 249.812 168.2C249.058 168.307 249.014 168.345 249.003 169.149C248.99 170.048 249.004 170.948 248.999 171.847C248.993 172.79 248.993 172.81 248.037 172.994C247.651 173.068 247.39 173.22 247.414 173.621C247.456 174.316 247.104 174.587 246.466 174.602C246.076 174.611 245.794 174.788 245.817 175.193C245.86 175.946 245.467 176.195 244.794 176.211C244.385 176.221 244.184 176.477 244.21 176.865C244.254 177.518 243.91 177.78 243.321 177.795C242.822 177.808 242.637 178.049 242.589 178.537C242.521 179.236 242.371 179.324 241.649 179.404C241.292 179.443 240.941 179.536 240.588 179.605C238.84 177.179 237.056 174.778 235.351 172.322C229.242 163.516 223.65 154.381 218.147 145.191C213.86 138.03 209.638 130.83 205.349 123.67C201.095 116.567 196.792 109.491 192.456 102.356C191.494 100.807 190.626 99.2795 189.673 97.8072C186.158 92.377 182.625 86.9584 179.075 81.5507C178.204 80.2235 177.245 78.9543 176.255 77.5588C173.91 74.3119 171.654 71.1509 169.354 68.0229C168.057 66.2601 166.687 64.5518 165.35 62.8189Z" fill="#0769E1"/>
C1673.333496,2162.000000 837.666992,2162.000000 2.000336,2162.000000 <path d="M312.412 87.5999C312.966 87.5673 313.43 87.6421 313.406 88.3676C313.393 88.7758 313.649 88.944 314.014 89.0329C314.587 89.1726 315.076 89.3707 315.038 90.1342C315.017 90.5577 315.467 90.5852 315.772 90.684C316.232 90.8332 316.661 90.9701 316.613 91.6024C316.582 92.0166 316.899 92.1435 317.246 92.2443C317.735 92.3862 318.022 92.6739 318.017 93.2536C318.012 93.7771 318.151 94.3007 318.203 94.8265C318.245 95.2446 318.532 95.3566 318.871 95.4509C319.4 95.5976 319.882 95.7665 319.83 96.4959C319.799 96.9204 320.219 96.9827 320.535 97.0701C321.049 97.2117 321.468 97.3915 321.421 98.0634C321.393 98.4847 321.785 98.5492 322.103 98.6645C322.995 98.9882 322.998 98.9968 322.999 99.9334C323.002 102.866 322.983 105.799 323.011 108.731C323.019 109.504 322.818 110.034 321.996 110.177C321.556 110.253 321.394 110.527 321.398 110.955C321.408 111.955 321.419 112.955 321.393 113.954C321.38 114.457 321.636 114.656 322.068 114.788C322.948 115.057 322.997 115.125 322.998 116.035C323.002 120.667 323.002 125.3 322.998 129.932C322.998 130.796 322.99 130.808 322.106 131.01C321.609 131.123 321.39 131.375 321.392 131.91C321.408 135.509 321.41 139.108 321.39 142.707C321.387 143.28 321.619 143.526 322.144 143.692C323 143.962 322.995 143.998 322.998 144.881C323.004 146.347 322.984 147.814 323.008 149.28C323.018 149.831 322.84 150.129 322.28 150.281C321.328 150.54 321.401 150.614 321.401 151.554C321.399 153.387 321.403 155.22 321.399 157.053C321.397 157.917 321.534 158.044 320.514 158.321C319.947 158.475 319.787 158.781 319.792 159.327C319.812 161.293 319.809 163.259 319.794 165.226C319.79 165.743 319.867 166.129 320.47 166.26C320.979 166.372 321.129 166.741 321.229 167.276C321.528 168.868 321.362 170.462 321.391 172.053C321.428 174.019 321.396 175.986 321.402 177.952C321.404 178.787 321.4 178.829 322.194 179.082C322.821 179.283 323.015 179.678 323.003 180.276C322.989 180.976 322.98 181.676 323.008 182.375C323.023 182.734 323.12 183.09 323.188 183.446C323.251 183.78 323.454 183.931 323.795 184.004C324.582 184.172 324.593 184.193 324.597 184.958C324.607 186.724 324.592 188.491 324.607 190.257C324.61 190.616 324.696 190.975 324.756 191.332C324.823 191.737 325.019 192.02 325.478 191.997C325.99 191.972 326.166 192.289 326.27 192.718C326.393 193.225 326.569 193.652 327.246 193.625C327.727 193.606 327.791 194.008 327.803 194.406C327.82 194.935 327.804 195.477 327.914 195.989C328.075 196.739 328.175 196.787 328.931 196.797C329.864 196.81 330.798 196.781 331.73 196.81C332.085 196.821 332.437 196.941 332.876 197.06C331.994 198.137 331.039 199.18 330.046 200.186C329.706 200.531 329.256 200.764 328.886 201.084C327.92 201.921 327.011 202.829 326.004 203.611C325.058 204.346 324.031 204.981 323.011 205.614C320.899 206.927 318.73 208.136 316.426 209.088C313.03 210.491 309.545 211.581 305.92 212.231C301.245 213.069 296.536 213.175 291.812 212.964C285.866 212.697 280.083 211.604 274.465 209.286C274.401 208.593 274.376 208.025 274.41 207.461C274.452 206.782 274.668 206.514 275.345 206.411C275.866 206.331 276.012 206.056 276.001 205.597C275.994 205.33 276 205.064 276 204.797C276 203.598 275.984 202.399 276.006 201.2C276.022 200.389 276.203 200.166 277.006 200.004C277.471 199.91 277.635 199.647 277.594 199.237C277.377 197.065 277.998 194.949 277.996 192.793C277.996 192.342 278.152 191.962 278.578 191.854C279.064 191.731 279.202 191.4 279.296 191.003C279.408 190.527 279.681 190.24 280.179 190.202C280.715 190.16 280.81 189.808 280.801 189.363C280.793 188.93 280.778 188.495 280.809 188.064C280.857 187.404 281.174 187.082 281.787 187.006C282.579 186.909 282.978 187.239 282.995 188.055C283.015 189.054 283 190.054 283.002 191.053C283.003 191.412 283.074 191.769 283.515 191.756C283.954 191.744 283.998 191.375 283.999 191.023C284 190.623 283.987 190.223 284.003 189.824C284.036 189.011 284.24 188.72 285.029 188.621C285.566 188.554 285.803 188.357 285.812 187.817C285.819 187.358 286.107 187.113 286.548 187.004C287.385 186.798 287.384 186.789 287.399 185.992C287.404 185.759 287.403 185.526 287.399 185.292C287.387 184.457 287.377 184.484 286.585 184.184C286.303 184.078 285.97 183.859 285.855 183.604C285.415 182.623 285.444 182.61 284.504 182.6C282.389 182.578 282.356 182.546 282.404 180.399C282.41 180.137 282.434 179.866 282.511 179.618C282.612 179.29 282.809 179.069 283.202 178.993C283.984 178.841 283.982 178.811 283.998 178.036C284.007 177.637 283.943 177.226 284.017 176.84C284.087 176.474 284.294 176.135 284.509 175.796C284.696 175.869 284.818 175.922 284.932 175.991C288.412 178.106 292.242 178.929 296.259 178.947C297.711 178.953 299.178 178.814 300.614 178.586C304.275 178.003 307.525 176.5 310.279 173.987C313.356 171.179 315.357 167.686 316.804 163.825C318.271 159.911 319.087 155.845 319.54 151.715C319.84 148.981 319.983 146.219 320.007 143.469C320.041 139.612 319.917 135.754 319.824 131.897C319.783 130.238 319.695 128.578 319.549 126.925C319.337 124.522 319.059 122.124 318.799 119.726C318.596 117.856 318.432 115.98 318.152 114.122C317.749 111.453 317.241 10Line truncated
C2.000224,1442.000244 2.000224,722.000549 2.000112,2.000626 <path d="M284.441 175.783C284.294 176.134 284.087 176.474 284.017 176.84C283.943 177.225 284.007 177.636 283.998 178.036C283.982 178.811 283.984 178.84 283.202 178.992C282.809 179.069 282.612 179.29 282.511 179.618C282.434 179.866 282.41 180.137 282.404 180.399C282.355 182.545 282.389 182.577 284.504 182.6C285.444 182.61 285.415 182.623 285.855 183.604C285.97 183.859 286.303 184.078 286.585 184.184C287.377 184.483 287.387 184.457 287.399 185.292C287.403 185.525 287.404 185.759 287.399 185.992C287.384 186.789 287.385 186.798 286.548 187.004C286.107 187.113 285.819 187.358 285.811 187.817C285.803 188.357 285.566 188.554 285.029 188.621C284.239 188.719 284.035 189.011 284.003 189.823C283.987 190.223 284 190.623 283.999 191.022C283.998 191.374 283.954 191.743 283.515 191.756C283.074 191.768 283.003 191.412 283.002 191.053C283 190.054 283.015 189.054 282.995 188.055C282.978 187.238 282.579 186.909 281.787 187.006C281.174 187.082 280.857 187.404 280.809 188.064C280.777 188.495 280.793 188.93 280.801 189.362C280.81 189.808 280.715 190.16 280.179 190.202C279.681 190.24 279.408 190.526 279.295 191.003C279.202 191.4 279.064 191.731 278.578 191.854C278.151 191.961 277.996 192.342 277.996 192.793C277.998 194.948 277.377 197.065 277.594 199.236C277.635 199.647 277.471 199.91 277.006 200.004C276.203 200.166 276.022 200.389 276.006 201.2C275.983 202.398 276 203.598 276 204.797C276 205.063 275.994 205.33 276 205.596C276.012 206.056 275.866 206.331 275.345 206.411C274.668 206.514 274.452 206.781 274.41 207.46C274.376 208.025 274.401 208.593 274.4 209.247C270.703 207.949 267.283 206.038 264.029 203.821C261.082 201.813 258.355 199.536 255.744 197.105C250.833 192.533 246.521 187.435 242.476 182.019C242.652 181.398 242.407 181.087 241.948 180.803C241.886 180.968 241.844 181.079 241.802 181.191C241.408 180.707 241.014 180.222 240.604 179.671C240.941 179.536 241.292 179.443 241.649 179.404C242.371 179.324 242.521 179.236 242.589 178.537C242.637 178.049 242.822 177.808 243.321 177.795C243.91 177.779 244.254 177.518 244.21 176.865C244.183 176.476 244.385 176.22 244.794 176.211C245.467 176.195 245.86 175.946 245.817 175.193C245.794 174.787 246.076 174.611 246.466 174.602C247.104 174.587 247.456 174.316 247.414 173.62C247.39 173.22 247.651 173.068 248.037 172.994C248.993 172.81 248.993 172.79 248.999 171.847C249.004 170.947 248.99 170.048 249.003 169.149C249.014 168.345 249.057 168.307 249.812 168.2C250.593 168.09 250.773 167.899 250.797 167.12C250.811 166.654 250.804 166.187 250.802 165.721C250.799 165.288 250.986 165.077 251.437 164.992C252.306 164.829 252.384 164.698 252.399 163.795C252.405 163.395 252.385 162.995 252.404 162.596C252.435 161.93 252.591 161.71 253.273 161.616C253.759 161.55 253.948 161.361 254.016 160.875C254.117 160.162 254.334 160.019 255.094 160.003C255.793 159.989 256.494 159.971 257.191 160.006C258.657 160.079 258.864 159.719 258.806 158.44C258.774 157.742 258.791 157.041 258.802 156.342C258.815 155.553 258.895 155.453 259.623 155.197C260.269 154.971 260.384 154.829 260.396 154.111C260.411 153.245 260.39 152.379 260.403 151.513C260.415 150.745 260.507 150.695 261.245 150.38C261.589 150.233 261.861 149.916 262.25 149.651C264.521 152.804 266.679 156.003 268.9 159.156C272.041 163.616 275.479 167.838 279.279 171.757C279.709 172.202 280.247 172.541 280.697 172.969C281.836 174.054 283.067 175.013 284.441 175.783Z" fill="#0572EA"/>
C1281.999512,2.000417 2561.999023,2.000417 3841.999023,2.000209 <path d="M68.9886 150.2C68.6888 150.2 68.3881 150.185 68.0894 150.203C67.4735 150.241 66.9567 150.138 66.7744 149.433C66.6829 149.079 66.3998 149 66.0753 149.002C65.7089 149.004 65.3424 149.005 64.9761 149C64.5647 148.994 64.2727 149.111 64.1986 149.582C64.0845 150.306 63.5379 150.532 62.9037 150.591C62.5073 150.628 62.1049 150.603 61.7052 150.602C61.3255 150.602 61.0695 150.743 61.0052 151.154C60.883 151.935 60.3022 152.135 59.633 152.195C59.3686 152.219 59.1 152.209 58.8339 152.198C58.2982 152.177 57.8243 152.206 57.7702 152.923C57.7428 153.285 57.4411 153.351 57.1172 153.404C55.5129 153.668 53.9107 153.929 52.2746 153.802C51.8377 153.768 51.5491 153.893 51.36 154.367C51.1217 154.966 49.999 155.246 49.4818 154.898C49.3593 154.816 49.2378 154.641 49.2265 154.5C49.1748 153.854 48.7577 153.78 48.2421 153.797C47.7763 153.812 47.3069 153.829 46.8439 153.789C46.1808 153.731 45.9676 153.372 46.0004 152.475C46.0274 151.736 46.1314 151.619 46.8885 151.605C47.7876 151.588 48.6873 151.607 49.5865 151.598C50.5004 151.589 50.6324 151.508 50.7913 150.644C50.8739 150.195 51.0785 150.001 51.5137 150.002C51.9467 150.004 52.3799 150.008 52.8126 149.997C53.0435 149.991 53.2965 150.006 53.4972 149.917C53.6823 149.834 53.811 149.625 53.9646 149.472C53.7792 149.317 53.6073 149.053 53.4058 149.028C52.8807 148.963 52.342 149.016 51.8098 148.996C51.1334 148.97 50.9563 148.808 50.8018 148.143C50.6357 147.427 50.6359 147.415 49.8825 147.404C49.0167 147.39 48.15 147.383 47.2846 147.407C46.7924 147.421 46.3961 147.317 46.0225 146.957C45.8115 146.753 45.4488 146.647 45.1421 146.615C44.6234 146.561 44.095 146.6 43.4465 146.6C43.2546 146.97 42.9119 147.377 42.2655 147.448C42.093 147.467 41.8913 147.779 41.8127 147.997C41.4997 148.862 41.3727 148.976 40.4589 148.999C40.2591 149.004 40.0592 149 39.8593 149C38.8965 149.004 38.8907 149.001 38.5413 149.891C38.3438 150.395 37.9668 150.597 37.4523 150.598C36.6529 150.6 35.8534 150.6 34.9658 150.6C34.7837 149.446 34.6354 148.293 34.6063 147.138C34.5227 143.816 34.4554 140.494 34.4455 137.172C34.4402 135.381 34.5293 133.589 34.6406 131.801C34.8072 129.124 35.031 126.45 35.3389 123.687C36.0359 123.551 36.7443 123.69 37.183 123.408C37.7469 123.046 38.275 123.001 38.8668 123.001C42.3938 123 45.9208 123.015 49.4475 122.984C49.9517 122.979 50.6479 122.914 50.9153 122.594C51.4145 121.996 51.9687 121.998 52.6023 121.998C56.7281 122.002 60.854 122.004 64.9798 121.993C65.3335 121.992 65.7934 122.01 66.0182 121.81C66.4765 121.402 66.9674 121.394 67.5013 121.399C68.2666 121.405 69.0319 121.4 69.8115 121.488C69.6037 123.987 69.3518 126.395 69.1672 128.809C68.9574 131.553 68.7451 134.3 68.6505 137.05C68.5634 139.579 68.6302 142.113 68.6322 144.645C68.6324 144.911 68.6463 145.177 68.6641 145.443C68.7706 147.029 68.8801 148.614 68.9886 150.2Z" fill="#017BF4"/>
C3841.999268,721.999329 3841.999268,1441.998657 3841.999512,2161.999023 <path d="M52.5419 60.0342C52.7486 60.1627 52.9124 60.4907 53.0524 60.4808C54.0115 60.413 54.4501 61.6377 55.4626 61.4098C55.7478 61.3456 56.0658 61.3636 56.358 61.4108C56.6386 61.4561 56.9894 61.5106 57.1611 61.6974C57.5705 62.1428 58.0425 62.2427 58.6003 62.2034C59.1042 62.168 59.595 62.1605 59.9148 62.6915C60.0019 62.836 60.2472 62.9477 60.4282 62.9609C60.8819 62.994 61.2147 63.14 61.5444 63.492C61.7522 63.7139 62.2026 63.7644 62.5507 63.7861C63.0855 63.8195 63.6077 63.7546 63.9529 64.3244C64.0487 64.4825 64.3624 64.5054 64.5726 64.5984C64.7794 64.69 65.0439 64.7405 65.1744 64.8987C65.5638 65.3711 66.0563 65.443 66.6108 65.402C67.1198 65.3644 67.5934 65.3847 67.9253 65.8964C68.0304 66.0585 68.3224 66.1607 68.5375 66.1769C68.9279 66.2063 69.1844 66.361 69.478 66.6287C69.7366 66.8645 70.1882 66.9637 70.5612 66.9812C71.1075 67.0069 71.5612 67.0818 72.0218 67.4566C72.5118 67.8551 73.2032 67.9431 73.6745 68.4664C73.8535 68.665 74.3649 68.594 74.7246 68.5925C75.1713 68.5906 75.5622 68.6394 75.9114 68.9805C76.1127 69.1772 76.4313 69.3633 76.697 69.3631C77.3897 69.3626 77.9435 69.5047 78.4515 70.0468C78.6552 70.2642 79.2027 70.1795 79.5951 70.1943C80.0003 70.2096 80.4017 70.1768 80.6206 70.6303C80.795 70.9916 81.1345 71.0249 81.4775 70.9969C82.1142 70.9449 82.6287 71.1543 83.1137 71.5781C83.3701 71.8021 83.7638 71.8688 84.1616 72.0856C84.1288 72.4105 84.0462 72.6644 83.9283 72.9007C81.8314 77.1023 79.9734 81.4078 78.4075 85.8339C77.4679 88.4895 76.6291 91.1805 75.7285 93.8501C75.5939 94.249 75.3687 94.6174 75.1026 94.9998C74.7673 94.9695 74.5148 94.9391 74.2332 94.9053C74.2861 93.7845 73.7155 93.3225 72.7257 93.3396C72.6755 93.1957 72.6313 93.1067 72.6137 93.0128C72.4183 91.9731 72.2329 91.8144 71.1641 91.801C70.698 91.7952 70.2318 91.7979 69.7656 91.8004C68.5176 91.8073 68.3897 91.9175 68.1365 93.1747C68.1254 93.23 68.0573 93.2738 67.9505 93.4C67.6877 93.4 67.3594 93.4 67.0311 93.4C64.8001 93.4 62.5689 93.421 60.3384 93.3881C59.5991 93.3773 58.9575 93.4737 58.4893 94.1041C58.4662 94.1352 58.3649 94.1081 58.1517 94.1081C58.1034 93.7637 58.0225 93.3963 58.0059 93.026C57.9653 92.118 57.7287 91.8363 56.8215 91.807C55.9234 91.7781 55.0236 91.8068 54.1247 91.7946C53.9153 91.7918 53.7068 91.7262 53.4979 91.6895C53.4802 91.6182 53.4624 91.547 53.4447 91.4757C53.6547 91.3849 53.8586 91.2391 54.076 91.2153C54.4709 91.1719 54.874 91.2087 55.2733 91.1982C56.1216 91.1758 56.3598 90.9519 56.3996 90.1588C56.4564 89.0277 56.2391 88.6395 55.3541 88.6171C53.5904 88.5723 51.8245 88.5834 50.0604 88.616C49.5566 88.6253 49.1215 88.8038 48.9788 89.4379C48.8083 90.1958 48.7541 90.193 47.9458 90.1978C46.614 90.2057 45.282 90.2048 43.9502 90.1978C43.3892 90.1948 42.8902 90.3 42.5823 90.8318C42.356 91.2228 42.0263 91.25 41.6349 91.1179C41.4492 91.0553 41.2486 91.0371 41.0547 90.9988C41.8966 88.1056 42.6902 85.1974 43.5905 82.3225C45.3862 76.5885 47.5207 70.9785 49.9671 65.4898C50.7772 63.6722 51.6459 61.8808 52.5419 60.0342Z" fill="#0169E3"/>
C3398.333252,2162.000000 2954.666748,2162.000000 2510.000000,2162.000000 <path d="M69.7972 121.4C69.0319 121.4 68.2666 121.405 67.5014 121.398C66.9675 121.394 66.4766 121.402 66.0183 121.81C65.7935 122.01 65.3336 121.992 64.9799 121.993C60.8541 122.004 56.7282 122.002 52.6024 121.998C51.9688 121.998 51.4146 121.996 50.9154 122.594C50.648 122.914 49.9518 122.979 49.4475 122.983C45.9209 123.015 42.3939 122.999 38.8669 123.001C38.275 123.001 37.747 123.046 37.1831 123.408C36.7443 123.69 36.036 123.551 35.3624 123.6C35.3318 122.777 35.3435 121.948 35.4481 121.131C35.8719 117.823 36.291 114.513 36.7767 111.213C37.1503 108.676 37.6203 106.153 38.0514 103.624C38.0675 103.529 38.1257 103.441 38.2749 103.273C38.7421 103.13 39.0979 103.013 39.4551 103.009C41.1504 102.989 42.8468 102.974 44.5412 103.018C44.9811 103.03 45.5348 103.14 45.8223 103.423C46.1957 103.79 46.5634 103.799 46.9886 103.799C49.1163 103.801 51.2441 103.806 53.3718 103.796C53.8538 103.793 54.3506 103.816 54.648 104.212C54.9429 104.604 55.3004 104.602 55.7021 104.601C57.5971 104.598 59.4922 104.607 61.3871 104.596C61.8705 104.593 62.3637 104.625 62.6594 105.022C62.9551 105.419 63.3194 105.401 63.7175 105.401C66.1777 105.399 68.6379 105.389 71.098 105.409C71.5873 105.413 72.0757 105.533 72.5695 105.679C72.1357 107.938 71.6323 110.106 71.274 112.298C70.8149 115.107 70.0556 117.871 69.963 120.738C69.9559 120.96 69.8547 121.179 69.7972 121.4Z" fill="#0172ED"/>
M396.017273,966.964172 <path d="M72.5645 105.599C72.0757 105.533 71.5873 105.413 71.098 105.409C68.638 105.389 66.1777 105.399 63.7175 105.401C63.3194 105.401 62.9551 105.419 62.6594 105.022C62.3637 104.625 61.8705 104.593 61.3872 104.596C59.4922 104.607 57.5972 104.598 55.7021 104.601C55.3005 104.602 54.9429 104.604 54.648 104.212C54.3506 103.816 53.8538 103.793 53.3718 103.796C51.2441 103.806 49.1164 103.801 46.9886 103.799C46.5634 103.799 46.1957 103.79 45.8223 103.423C45.5348 103.14 44.9811 103.03 44.5412 103.018C42.8468 102.974 41.1504 102.989 39.4551 103.009C39.0979 103.013 38.7421 103.13 38.3022 103.198C38.6636 101.112 39.1083 99.0239 39.6168 96.8519C39.6941 96.7501 39.7226 96.726 39.7183 96.7158C39.702 96.6771 39.6749 96.6429 39.6519 96.6071C40.0977 94.7855 40.5435 92.964 41.0219 91.0706C41.2483 91.0371 41.449 91.0553 41.6347 91.1179C42.0261 91.25 42.3557 91.2228 42.5821 90.8318C42.89 90.3 43.389 90.1948 43.9499 90.1978C45.2818 90.2048 46.6138 90.2057 47.9456 90.1978C48.7539 90.193 48.8081 90.1959 48.9786 89.4379C49.1213 88.8038 49.5563 88.6253 50.0602 88.616C51.8243 88.5834 53.5902 88.5723 55.3538 88.6171C56.2389 88.6396 56.4562 89.0277 56.3994 90.1588C56.3596 90.9519 56.1214 91.1759 55.2731 91.1982C54.8738 91.2087 54.4707 91.1719 54.0758 91.2153C53.8584 91.2391 53.6545 91.3849 53.4445 91.4757C53.4622 91.547 53.48 91.6182 53.4977 91.6895C53.7066 91.7262 53.9151 91.7918 54.1245 91.7946C55.0234 91.8068 55.9232 91.7781 56.8213 91.807C57.7285 91.8363 57.9651 92.118 58.0057 93.026C58.0223 93.3963 58.1032 93.7637 58.1515 94.1081C58.3647 94.1081 58.466 94.1352 58.4891 94.1041C58.9573 93.4738 59.5989 93.3773 60.3382 93.3881C62.5687 93.421 64.7999 93.4 67.0309 93.4C67.3592 93.4 67.6875 93.4 67.9503 93.4C68.0571 93.2738 68.1252 93.23 68.1363 93.1747C68.3894 91.9176 68.5173 91.8073 69.7654 91.8004C70.2316 91.7979 70.6978 91.7952 71.1639 91.801C72.2326 91.8145 72.4181 91.9731 72.6135 93.0128C72.6311 93.1067 72.6753 93.1957 72.7255 93.3396C73.7153 93.3225 74.2859 93.7845 74.2329 94.9053C74.5146 94.9391 74.7671 94.9695 75.1281 95.0793C75.0593 95.8853 74.8924 96.6144 74.7028 97.3376C74.233 99.1306 73.7471 100.919 73.2791 102.713C73.0287 103.672 72.8019 104.637 72.5645 105.599Z" fill="#016DE9"/>
C396.078247,967.300415 396.139221,967.636597 395.530701,969.360046 <path d="M35.7974 158.881C36.2009 158.742 36.6324 158.45 36.9078 158.978C36.6593 159.449 36.4177 159.907 36.1063 160.382C35.9522 159.92 35.8679 159.441 35.7974 158.881Z" fill="#017BF4"/>
C391.083679,990.239441 386.636688,1011.118896 381.644043,1033.505371 <path d="M241.819 181.254C241.844 181.08 241.886 180.968 241.948 180.803C242.407 181.087 242.652 181.398 242.459 181.954C242.217 181.77 242.026 181.543 241.819 181.254Z" fill="#0769E1"/>
C381.258087,1034.414307 380.676208,1035.289917 380.514740,1036.237183 <path d="M39.6267 96.6518C39.6749 96.643 39.7019 96.6771 39.7183 96.7158C39.7226 96.726 39.6941 96.7502 39.6503 96.7826C39.6138 96.7637 39.6077 96.7301 39.6267 96.6518Z" fill="#0172ED"/>
C376.203705,1061.526123 371.503815,1086.758789 367.768280,1112.133301 <path d="M154.948 110.601C156.064 108.69 157.253 106.768 158.475 104.868C161.82 99.6657 165.178 94.4725 168.533 89.277C168.766 88.9154 169.014 88.5633 169.315 88.1689C169.483 88.2801 169.568 88.53 169.703 88.5615C170.489 88.7436 170.378 89.3492 170.402 89.9074C170.426 90.4697 170.386 90.9962 169.73 91.1884C169.146 91.3594 168.997 91.7653 168.988 92.3282C168.979 92.8197 168.853 93.3082 168.798 93.8001C168.759 94.1468 168.578 94.2979 168.247 94.4047C167.471 94.6556 167.423 94.7484 167.402 95.5215C167.393 95.821 167.415 96.1218 167.396 96.4203C167.359 97.0188 167.223 97.5219 166.481 97.6309C165.984 97.7038 165.789 98.0944 165.799 98.588C165.807 98.9874 165.793 99.3873 165.801 99.7866C165.813 100.324 165.6 100.7 165.047 100.789C164.554 100.867 164.266 101.114 164.197 101.614C164.136 102.066 163.873 102.331 163.423 102.397C162.813 102.485 162.582 102.861 162.599 103.442C162.606 103.675 162.589 103.909 162.602 104.141C162.644 104.896 162.58 105.533 161.6 105.656C161.168 105.71 160.989 106.119 160.998 106.572C161.009 107.071 161.02 107.572 160.993 108.07C160.959 108.696 160.691 108.967 160.06 108.992C159.367 109.019 158.671 108.998 157.938 108.998C157.857 109.277 157.802 109.495 157.731 109.708C157.54 110.282 157.12 110.566 156.533 110.593C156.035 110.615 155.534 110.599 154.948 110.601Z" fill="#047FF9"/>
C362.910583,1145.130005 358.719604,1178.227051 354.482086,1211.311768
C353.435852,1219.480469 353.318787,1227.768066 352.305695,1237.742065
C350.311218,1264.495605 348.074158,1291.234009 346.407440,1318.007935
C345.294647,1335.884277 344.403931,1353.812866 344.457062,1371.714966
C344.555695,1404.936523 345.228210,1438.160645 346.064819,1471.373535
C346.355988,1482.932617 347.838562,1494.461792 348.397919,1507.690552
C349.966827,1523.748901 351.311523,1539.833496 353.183136,1555.856445
C354.439941,1566.616455 356.443024,1577.289429 357.835693,1589.629028
C358.679077,1594.416016 359.522461,1599.203003 360.259888,1605.617798
C365.780029,1631.724976 370.570587,1658.012573 376.977936,1683.900146
C388.910248,1732.109985 405.535950,1778.768799 427.089111,1823.542114
C451.608246,1874.476807 481.893402,1921.624756 519.992676,1963.654541
C548.541077,1995.147949 580.254883,2022.866333 615.695740,2046.261353
C659.638123,2075.268311 707.294250,2096.050049 757.979492,2110.209473
C795.559143,2120.707764 833.891357,2126.678711 872.672668,2129.460205
C892.902832,2130.910889 913.294495,2130.113037 933.613342,2130.323486
C966.281982,2130.661133 998.664429,2127.238525 1030.703125,2121.373535
C1105.966797,2107.594727 1173.757324,2076.480957 1235.311279,2031.365479
C1279.484131,1998.989258 1319.065552,1961.610352 1356.178955,1921.426880
C1388.260742,1886.691650 1418.275024,1850.276489 1446.820679,1812.632202
C1482.431519,1765.670898 1515.965576,1717.256104 1548.238770,1667.934692
C1593.082031,1599.403076 1635.604370,1529.456055 1676.380493,1458.461060
C1718.296143,1385.481934 1759.427734,1312.052368 1800.898193,1238.817505
C1834.828491,1178.898315 1868.712646,1118.953125 1902.712646,1059.073486
C1909.594604,1046.953125 1916.903076,1035.074951 1925.110474,1024.035278
C1967.924438,1094.911743 2010.945679,1165.663940 2053.494629,1236.699097
C2096.380859,1308.298096 2138.599121,1380.297363 2181.471191,1451.904907
C2236.495605,1543.810059 2292.420898,1635.162964 2353.514893,1723.216919
C2370.557617,1747.780518 2388.402588,1771.787720 2406.192627,1797.377808
C2410.135986,1802.221924 2414.079590,1807.066040 2418.355225,1813.160767
C2420.261963,1815.430420 2422.168701,1817.700073 2424.417480,1821.281738
C2465.214844,1874.351562 2508.332275,1925.326782 2557.441162,1971.051392
C2583.546631,1995.357666 2610.822998,2018.135010 2640.292725,2038.212769
C2672.828369,2060.379639 2707.032715,2079.486816 2745.295654,2094.128906
C2800.833984,2116.038818 2858.661133,2126.971191 2918.120850,2129.636230
C2965.358398,2131.753174 3012.449951,2130.684570 3059.198730,2122.304932
C3095.446289,2115.807861 3130.298096,2104.907227 3164.256836,2090.877930
C3187.299561,2081.358398 3208.990967,2069.264404 3230.114014,2056.138184
C3240.307373,2049.803711 3250.577148,2043.454956 3260.036133,2036.112671
C3270.111572,2028.291626 3279.201660,2019.210449 3288.863037,2010.841919
C3292.555664,2007.643311 3297.062744,2005.313232 3300.463867,2001.863159
C3310.385742,1991.799072 3319.936523,1981.369751 3330.699219,1970.386475
C3345.060791,1951.661133 3360.370850,1933.579346 3373.594482,1914.082397
C3405.333008,1867.287964 3428.903809,1816.302124 3447.217041,1762.916260
C3473.758545,1685.543457 3488.950928,1605.761230 3495.841553,1524.397949
C3498.641113,1491.341431 3500.604980,1458.165039 3501.430664,1425.005493
C3502.158936,1395.761230 3500.912842,1366.461426 3500.269043,1337.192139
C3499.896484,1320.255859 3499.215820,1303.318604 3498.270996,1286.404419
C3497.011963,1263.874023 3495.449951,1241.359131 3493.848145,1218.849731
C3492.750000,1203.418335 3490.540283,1188.099243 3489.291992,1172.659058
C3487.424316,1149.557495 3484.071289,1126.517334 3480.176758,1103.650879
C3472.766846,1060.143433 3465.275146,1016.624268 3456.441162,973.391235
C3445.527344,919.978821 3431.054932,867.441101 3414.729736,815.399353
C3390.804688,739.131531 3361.827148,664.873108 3327.167969,592.864441
C3297.103760,530.402527 3262.684570,470.405304 3223.582031,413.136932
C3188.253418,361.395874 3149.292236,312.526428 3105.742432,267.488525
C3086.796387,247.894852 3066.824951,229.203293 3046.384277,211.161331
C2991.976318,163.138443 2932.407471,122.783264 2866.512451,91.940331
C2795.618652,58.757664 2721.447266,38.461437 2643.143311,34.280968
C2595.480957,31.736374 2548.195068,34.548454 2501.432861,44.966084
C2439.469971,58.770096 2381.937988,83.221855 2327.608887,115.713722
C2264.400879,153.515762 2208.356201,200.392288 2155.938477,251.737289
C2136.939941,270.347137 2118.720703,289.820709 2101.061523,309.713226
C2077.458740,336.301483 2054.269043,363.290497 2031.788086,390.830994
C2009.294678,418.386810 1987.892578,446.833527 1964.901733,473.992157
C1957.049194,464.205841 1949.315918,454.320618 1941.305908,444.664948
C1935.039551,437.111328 1928.430298,429.842194 1920.971680,421.497467
C1915.827759,415.100555 1910.948730,408.467529 1905.493652,402.347809
C1882.363647,376.399780 1859.248779,350.433380 1835.752930,324.817902
C1822.052734,309.881622 1808.075195,295.145111 1793.448853,281.125793
C1772.812378,261.345825 1752.003540,241.678589 1730.306885,223.084946
C1674.805176,175.520981 1615.193481,134.055664 1549.503296,101.392632
C1471.372314,62.543747 1388.800415,40.415920 1302.030273,34.621109
C1259.326050,31.769173 1216.427002,32.356586 1173.822754,38.281780
C1140.212524,42.956116 1107.143799,50.072224 1074.756836,60.222172
C996.805359,84.651833 926.022461,122.865204 860.813171,171.746674
C810.850525,209.199173 765.917297,252.067734 724.110840,298.350037
C686.125061,340.402679 652.117737,385.509583 620.604248,432.522064
C594.285339,471.785065 570.445007,512.564209 548.217712,554.262756
C540.259827,569.191833 533.347046,584.677979 524.877563,600.773804
C516.457947,618.807861 507.770294,636.722412 499.669006,654.898376
C475.205322,709.784912 453.860352,765.885071 435.903198,823.225159
C426.900055,851.973633 418.963989,881.056335 409.893982,911.424622
C405.435883,929.639954 400.977783,947.855286 396.017273,966.964172
z"/>
<path fill="#0081FA" opacity="1.000000" stroke="none"
d="
M1966.012207,474.889740
C1987.892578,446.833527 2009.294678,418.386810 2031.788086,390.830994
C2054.269043,363.290497 2077.458740,336.301483 2101.061523,309.713226
C2118.720703,289.820709 2136.939941,270.347137 2155.938477,251.737289
C2208.356201,200.392288 2264.400879,153.515762 2327.608887,115.713722
C2381.937988,83.221855 2439.469971,58.770096 2501.432861,44.966084
C2548.195068,34.548454 2595.480957,31.736374 2643.143311,34.280968
C2721.447266,38.461437 2795.618652,58.757664 2866.512451,91.940331
C2932.407471,122.783264 2991.976318,163.138443 3046.384277,211.161331
C3066.824951,229.203293 3086.796387,247.894852 3105.742432,267.488525
C3149.292236,312.526428 3188.253418,361.395874 3223.582031,413.136932
C3262.684570,470.405304 3297.103760,530.402527 3327.167969,592.864441
C3361.827148,664.873108 3390.804688,739.131531 3414.729736,815.399353
C3431.054932,867.441101 3445.527344,919.978821 3456.441162,973.391235
C3465.275146,1016.624268 3472.766846,1060.143433 3480.176758,1103.650879
C3484.071289,1126.517334 3487.424316,1149.557495 3489.291992,1172.659058
C3490.540283,1188.099243 3492.750000,1203.418335 3493.848145,1218.849731
C3495.449951,1241.359131 3497.011963,1263.874023 3498.270996,1286.404419
C3499.215820,1303.318604 3499.896484,1320.255859 3500.269043,1337.192139
C3500.912842,1366.461426 3502.158936,1395.761230 3501.430664,1425.005493
C3500.604980,1458.165039 3498.641113,1491.341431 3495.841553,1524.397949
C3488.950928,1605.761230 3473.758545,1685.543457 3447.217041,1762.916260
C3428.903809,1816.302124 3405.333008,1867.287964 3373.594482,1914.082397
C3360.370850,1933.579346 3345.060791,1951.661133 3329.297363,1970.246094
C3324.364990,1969.404053 3320.849854,1968.206177 3317.301270,1968.097168
C3307.978760,1967.810913 3298.640625,1968.093628 3289.311035,1967.968018
C3281.750488,1967.866211 3280.752930,1967.389160 3279.142090,1959.890747
C3278.041504,1954.768799 3278.202148,1949.353149 3278.033447,1944.061279
C3277.906250,1940.074707 3277.265137,1936.061279 3272.459961,1936.251465
C3265.689697,1936.519531 3263.926758,1932.251831 3262.696533,1927.177734
C3261.657227,1922.890747 3259.901611,1919.715454 3254.781250,1919.971313
C3250.187012,1920.200562 3248.227783,1917.370361 3247.556152,1913.321533
C3246.963623,1909.748779 3246.101074,1906.156250 3246.069824,1902.566284
C3245.916016,1884.905029 3246.065186,1867.241333 3245.968994,1849.579224
C3245.927246,1841.927246 3245.820557,1841.720215 3237.952148,1840.041016
C3234.537598,1839.312256 3232.510254,1837.799072 3231.876709,1834.461792
C3231.201416,1830.901489 3230.230225,1827.338867 3230.083496,1823.748901
C3229.797852,1816.762085 3229.891357,1809.753540 3230.029297,1802.757812
C3230.147217,1796.777832 3228.210449,1792.824829 3221.937012,1790.823242
C3214.000488,1788.290527 3214.042969,1787.869141 3214.018555,1779.517090
C3213.961182,1759.855103 3214.276123,1740.187744 3213.913086,1720.532349
C3213.619385,1704.618530 3215.284668,1688.677246 3212.293945,1672.754639
C3211.290527,1667.411499 3209.787842,1663.714355 3204.697998,1662.602051
C3198.665283,1661.283569 3197.900391,1657.427734 3197.939697,1652.253540
C3198.089111,1632.592651 3198.123535,1612.928589 3197.922363,1593.268555
C3197.866455,1587.812378 3199.469971,1584.749756 3205.135010,1583.209839
C3215.337891,1580.436157 3213.968506,1579.165039 3213.987549,1570.527588
C3214.028320,1552.198608 3213.989746,1533.869507 3214.004883,1515.540405
C3214.012451,1506.136597 3213.282959,1505.399536 3222.801270,1502.811279
C3228.403076,1501.287964 3230.175049,1498.312988 3230.082031,1492.798584
C3229.834961,1478.139648 3230.040039,1463.473389 3229.984619,1448.810303
C3229.951172,1439.975586 3229.996338,1439.617920 3221.441162,1436.918335
C3216.189697,1435.261108 3213.872314,1432.801270 3213.903809,1427.069458
C3214.100830,1391.078735 3214.082520,1355.086304 3213.920410,1319.095337
C3213.896240,1313.746460 3216.094238,1311.231079 3221.063477,1310.096680
C3229.895752,1308.080566 3229.975098,1307.960205 3229.982178,1299.317017
C3230.020020,1252.994385 3230.023926,1206.671753 3229.979004,1160.349121
C3229.969971,1151.249756 3229.477295,1150.565063 3220.678223,1147.877319
C3216.361816,1146.558838 3213.803223,1144.566528 3213.932129,1139.543091
C3214.188477,1129.552002 3214.077393,1119.549194 3213.983398,1109.552368
C3213.942871,1105.270264 3215.561279,1102.530518 3219.960938,1101.765625
C3228.175049,1100.337646 3230.189209,1095.038208 3230.114502,1087.310547
C3229.830811,1057.986694 3230.020020,1028.658569 3229.988525,999.331970
C3229.978516,989.966370 3229.947266,989.880432 3221.027832,986.643860
C3217.848145,985.489929 3213.926025,984.845154 3214.214600,980.631958
C3214.674805,973.913269 3210.486328,972.115234 3205.353516,970.699097
C3202.187012,969.825562 3197.992920,969.201904 3198.295166,964.957092
C3198.814697,957.663391 3193.995117,955.973938 3188.714355,954.507202
C3185.319824,953.564453 3182.452881,952.444824 3182.034668,948.263184
C3181.508545,943.005005 3180.123779,937.769775 3180.169922,932.533997
C3180.220947,926.737488 3177.353271,923.860657 3172.457764,922.440979
C3168.984863,921.433899 3165.819580,920.164062 3166.132568,916.022339
C3166.610352,909.699646 3162.320312,908.330139 3157.719971,906.838318
C3154.673340,905.850281 3150.174561,905.575256 3150.381836,901.340088
C3150.755615,893.705139 3145.866211,891.724548 3140.136963,890.327698
C3136.489990,889.438538 3133.925293,887.756653 3134.060303,883.674622
C3134.300537,876.419861 3129.657959,875.671387 3123.717773,875.374695
C3117.249756,856.461182 3111.370117,838.106140 3105.083984,819.891418
C3080.725098,749.307983 3050.718750,681.249329 3013.921875,616.217529
C2981.187500,558.366089 2943.257324,504.229218 2897.911377,455.566467
C2865.584717,420.875366 2829.772461,390.095032 2789.463379,364.861877
C2732.377686,329.126862 2670.895508,307.021423 2602.993164,304.158508
C2569.782471,302.758301 2537.328125,306.423309 2505.437744,315.433136
C2460.655029,328.085358 2420.707764,350.272766 2383.605713,377.919891
C2345.022461,406.670746 2310.688232,440.036011 2278.817139,475.925049
C2240.786865,518.749939 2205.948486,564.121277 2173.394043,611.229797
C2155.796631,636.694031 2138.561035,662.407959 2120.683105,687.587952
C2115.475098,680.775757 2110.613770,674.478027 2106.040283,667.977722
C2087.332520,641.388733 2069.022461,614.513672 2049.978027,588.169067
C2028.232910,558.088623 2005.869629,528.454956 1983.759277,498.638611
C1977.872925,490.700562 1971.929443,482.804871 1966.012207,474.889740
z"/>
<path fill="#0081FB" opacity="1.000000" stroke="none"
d="
M1924.014893,1023.084961
C1916.903076,1035.074951 1909.594604,1046.953125 1902.712646,1059.073486
C1868.712646,1118.953125 1834.828491,1178.898315 1800.898193,1238.817505
C1759.427734,1312.052368 1718.296143,1385.481934 1676.380493,1458.461060
C1635.604370,1529.456055 1593.082031,1599.403076 1548.238770,1667.934692
C1515.965576,1717.256104 1482.431519,1765.670898 1446.820679,1812.632202
C1418.275024,1850.276489 1388.260742,1886.691650 1356.178955,1921.426880
C1319.065552,1961.610352 1279.484131,1998.989258 1235.311279,2031.365479
C1173.757324,2076.480957 1105.966797,2107.594727 1030.703125,2121.373535
C998.664429,2127.238525 966.281982,2130.661133 933.613342,2130.323486
C913.294495,2130.113037 892.902832,2130.910889 872.672668,2129.460205
C833.891357,2126.678711 795.559143,2120.707764 757.979492,2110.209473
C707.294250,2096.050049 659.638123,2075.268311 615.695740,2046.261353
C580.254883,2022.866333 548.541077,1995.147949 519.992676,1963.654541
C481.893402,1921.624756 451.608246,1874.476807 427.089111,1823.542114
C405.535950,1778.768799 388.910248,1732.109985 376.977936,1683.900146
C370.570587,1658.012573 365.780029,1631.724976 361.009888,1604.637573
C364.176819,1599.073975 366.593781,1594.490479 369.077972,1589.779541
C366.324738,1584.499146 362.009186,1587.425293 358.112213,1588.001343
C356.443024,1577.289429 354.439941,1566.616455 353.183136,1555.856445
C351.311523,1539.833496 349.966827,1523.748901 349.469910,1506.844360
C358.536072,1505.993896 366.530273,1505.997559 374.524475,1505.982666
C379.669708,1505.973145 383.439331,1503.944946 385.414948,1498.911987
C388.908264,1490.012573 388.967133,1490.034546 398.594727,1490.000977
C400.593262,1489.994019 402.592926,1490.041870 404.590240,1489.991333
C413.728851,1489.760132 414.998810,1488.619263 418.128693,1479.964600
C418.914917,1477.790649 420.931824,1474.664551 422.656586,1474.475952
C429.120392,1473.769043 432.547546,1469.702271 434.466553,1466.003174
C440.951263,1466.003174 446.235809,1465.610107 451.422821,1466.151733
C454.489563,1466.472046 458.116272,1467.529663 460.226685,1469.566040
C463.962433,1473.171143 467.926147,1474.208008 472.847839,1474.068604
C481.501343,1473.823608 490.168488,1473.897705 498.826843,1474.034302
C506.360748,1474.153198 506.358917,1474.272705 508.019897,1481.426270
C509.564392,1488.077881 511.336029,1489.700317 518.099915,1489.958374
C523.422058,1490.161499 528.808411,1489.625488 534.059204,1490.278442
C536.074585,1490.529053 537.793335,1493.164917 539.647278,1494.713989
C538.111816,1496.247925 536.824951,1498.340210 534.973572,1499.164795
C532.966187,1500.058838 530.436462,1499.909790 528.128113,1499.969727
C523.800659,1500.082520 519.468506,1500.038696 515.138428,1500.021118
C510.786285,1500.003296 508.740936,1501.949341 507.914734,1506.440918
C506.325775,1515.078857 505.005798,1515.889526 495.866943,1515.980591
C486.874207,1516.070312 477.877625,1515.876953 468.887115,1516.043823
C461.315216,1516.184204 460.276031,1517.359863 460.005615,1524.746094
C459.677185,1533.716919 461.809479,1537.307739 468.440796,1537.883667
C473.070282,1538.285767 477.764771,1538.114990 482.422760,1537.966553
C487.578857,1537.802246 491.750031,1538.543213 492.266785,1544.997314
C492.379852,1546.409546 493.594177,1548.159912 494.819489,1548.982788
C499.991699,1552.455444 511.218323,1549.654053 513.601562,1543.672729
C515.492676,1538.926270 518.378662,1537.677002 522.748108,1538.016479
C539.108948,1539.287231 555.130371,1536.675659 571.173401,1534.040649
C574.412354,1533.508667 577.429749,1532.847778 577.703430,1529.225830
C578.244690,1522.062744 582.983765,1521.773071 588.341125,1521.981934
C591.001709,1522.085693 593.687805,1522.191895 596.331177,1521.952637
C603.023499,1521.346924 608.831360,1519.344971 610.054077,1511.534180
C610.696716,1507.428711 613.256592,1506.018188 617.053467,1506.021973
C621.050476,1506.026001 625.074463,1506.281494 629.038269,1505.910400
C635.380432,1505.316772 640.846313,1503.057373 641.987610,1495.816528
C642.729065,1491.112915 645.648499,1489.938354 649.762756,1489.998413
C653.426025,1490.051880 657.090637,1490.035156 660.754456,1490.013794
C663.999756,1489.994873 666.830994,1490.786377 667.745361,1494.324341
C669.568359,1501.378418 674.736328,1502.405151 680.895508,1502.031250
C683.882385,1501.849731 686.889343,1501.999268 690.088684,1502.795410
C690.733948,1505.526001 691.400696,1507.438599 691.588196,1509.397217
C694.637756,1541.244019 701.159607,1572.422485 710.374451,1602.996216
C722.666931,1643.781006 740.373474,1681.909424 767.833435,1714.946045
C798.488586,1751.827271 837.225525,1775.501953 884.314453,1784.843018
C906.824768,1789.308472 929.541443,1790.439575 952.617065,1788.559448
C982.114502,1786.156372 1010.303406,1779.698975 1037.116577,1767.224365
C1071.303955,1751.318726 1100.578369,1728.435547 1127.730225,1702.713257
C1155.300537,1676.594727 1180.119873,1647.921387 1203.855713,1618.325562
C1253.023438,1557.019165 1297.733276,1492.481201 1341.274170,1427.138794
C1371.718140,1381.451050 1401.547974,1335.349365 1431.275269,1289.189941
C1457.571167,1248.358765 1483.262451,1207.138794 1509.386719,1166.196533
C1522.265625,1146.012573 1535.520020,1126.068237 1549.476807,1106.011475
C1555.343628,1105.994751 1560.345703,1106.148193 1565.330811,1105.925537
C1571.197876,1105.663696 1575.401123,1102.821655 1577.310059,1097.083252
C1578.018066,1094.955322 1578.568481,1092.774902 1579.374512,1089.981812
C1586.710449,1089.981812 1593.666016,1090.191772 1600.602661,1089.919678
C1606.909302,1089.672363 1609.586670,1086.956299 1609.927002,1080.700806
C1610.197998,1075.720459 1610.087036,1070.712769 1609.982544,1065.720459
C1609.887573,1061.192749 1611.674683,1057.098999 1615.995972,1056.558594
C1625.801392,1055.332520 1626.441406,1048.961060 1626.020386,1041.414185
C1625.890747,1039.090698 1626.063354,1036.751709 1625.992065,1034.423096
C1625.814331,1028.613281 1628.126587,1024.851196 1634.226807,1023.967224
C1638.731567,1023.314331 1641.355469,1020.656311 1641.973511,1016.142700
C1642.657959,1011.143311 1645.536499,1008.671082 1650.466309,1007.886597
C1656.002686,1007.005432 1658.130981,1003.240112 1658.012695,997.866699
C1657.924683,993.873047 1658.068481,989.874390 1657.988892,985.880371
C1657.890625,980.944824 1659.843262,977.038818 1664.810913,976.309021
C1672.229614,975.219177 1673.587280,970.188171 1673.961426,964.203552
C1674.148071,961.218323 1673.931641,958.210083 1674.014771,955.215576
C1674.229492,947.484558 1674.706421,946.556335 1682.470215,944.047974
C1685.776611,942.979614 1687.593140,941.468201 1687.981812,938.001038
C1688.533203,933.082092 1689.790283,928.197449 1689.875977,923.282959
C1689.974243,917.653748 1691.462891,913.594849 1697.299316,911.884827
C1703.860596,909.962463 1704.263184,904.697205 1704.021240,899.074341
C1703.781006,893.492310 1704.890259,887.436401 1697.034058,885.615417
C1695.676636,885.300781 1694.825684,882.801514 1693.872070,880.649719
C1704.937012,862.964294 1715.756958,845.866150 1726.835815,828.937317
C1738.446655,811.195435 1750.305908,793.616028 1762.657959,776.273987
C1772.448242,789.540955 1782.042847,802.233154 1790.754517,815.504944
C1826.250610,869.582031 1861.581787,923.768250 1896.731934,978.070801
C1906.261963,992.793518 1914.943726,1008.065247 1924.014893,1023.084961
z"/>
<path fill="#0264E0" opacity="1.000000" stroke="none"
d="
M525.957214,599.909912
C533.347046,584.677979 540.259827,569.191833 548.217712,554.262756
C570.445007,512.564209 594.285339,471.785065 620.604248,432.522064
C652.117737,385.509583 686.125061,340.402679 724.110840,298.350037
C765.917297,252.067734 810.850525,209.199173 860.813171,171.746674
C926.022461,122.865204 996.805359,84.651833 1074.756836,60.222172
C1107.143799,50.072224 1140.212524,42.956116 1173.822754,38.281780
C1216.427002,32.356586 1259.326050,31.769173 1302.030273,34.621109
C1388.800415,40.415920 1471.372314,62.543747 1549.503296,101.392632
C1615.193481,134.055664 1674.805176,175.520981 1730.306885,223.084946
C1752.003540,241.678589 1772.812378,261.345825 1793.448853,281.125793
C1808.075195,295.145111 1822.052734,309.881622 1835.752930,324.817902
C1859.248779,350.433380 1882.363647,376.399780 1905.493652,402.347809
C1910.948730,408.467529 1915.827759,415.100555 1921.346802,422.614594
C1921.105835,424.482330 1920.606323,425.384186 1919.856812,425.961792
C1895.219360,444.949066 1870.595215,463.953766 1845.891724,482.854828
C1809.104126,511.001648 1772.276123,539.095703 1735.429321,567.164795
C1716.743408,581.399231 1698.026978,595.594421 1679.227295,609.677979
C1670.773438,616.011169 1662.082153,622.027588 1652.899414,627.916321
C1622.792725,591.597046 1591.958984,556.771118 1558.728149,524.062073
C1526.395752,492.237183 1492.049438,462.967041 1453.823242,438.413879
C1423.747559,419.096039 1391.963501,403.349548 1357.748413,392.712799
C1331.004150,384.398529 1303.709595,379.533722 1275.727051,377.450897
C1253.802612,375.818970 1232.001099,375.556000 1210.313843,378.614563
C1163.442017,385.224945 1120.801636,403.155640 1081.189453,428.641052
C1039.184692,455.665894 1002.813293,489.137085 970.127930,526.703613
C926.924255,576.359253 890.901733,630.930481 859.821899,688.855042
C854.183105,699.364319 848.289551,709.736938 841.733582,720.118652
C837.636536,718.687683 833.699036,718.020813 831.135803,715.781067
C826.285400,711.542664 821.140564,709.448608 814.773315,709.968628
C811.343201,710.248657 807.948242,709.915771 806.204956,706.303467
C804.015930,701.767639 800.001770,702.096436 795.949707,701.943115
C792.025208,701.794739 786.550171,702.642151 784.513184,700.468506
C779.432983,695.047424 773.895020,693.625854 766.968811,693.631287
C764.311890,693.633362 761.125122,691.771912 759.112183,689.805237
C755.620605,686.394043 751.710999,685.906128 747.244751,685.924805
C743.647888,685.939819 738.533203,686.650330 736.743835,684.663696
C732.030212,679.430664 725.116516,678.551025 720.216919,674.565613
C715.610168,670.818481 711.073608,670.068970 705.610657,669.812134
C701.880249,669.636719 697.364136,668.645386 694.778381,666.287354
C691.842773,663.610168 689.277039,662.063416 685.373230,661.769226
C683.222717,661.607178 680.302612,660.585022 679.250977,658.963745
C675.932251,653.846985 671.196228,653.644226 666.106506,654.020508
C660.560974,654.430359 655.636292,653.710938 651.742065,648.986755
C650.437927,647.404785 647.792664,646.899719 645.724182,645.984253
C643.622681,645.054138 640.485657,644.825317 639.527649,643.244080
C636.075439,637.546021 630.853149,638.195068 625.505432,637.861450
C622.024048,637.644348 617.520630,637.139221 615.442505,634.920410
C612.145630,631.400513 608.817261,629.940247 604.280640,629.608948
C602.470703,629.476807 600.017456,628.359985 599.146606,626.914612
C595.947998,621.605530 591.040527,621.680054 586.001526,622.034546
C580.423584,622.426819 575.703430,621.427856 571.609619,616.973816
C569.892883,615.106018 566.384033,614.561279 563.578064,614.108215
C560.656372,613.636536 557.476929,613.455750 554.624207,614.098022
C544.499451,616.377136 540.113953,604.130371 530.522034,604.808350
C529.122864,604.907288 527.484802,601.626709 525.957214,599.909912
z"/>
<path fill="#0769E1" opacity="1.000000" stroke="none"
d="
M1653.498657,628.187744
C1662.082153,622.027588 1670.773438,616.011169 1679.227295,609.677979
C1698.026978,595.594421 1716.743408,581.399231 1735.429321,567.164795
C1772.276123,539.095703 1809.104126,511.001648 1845.891724,482.854828
C1870.595215,463.953766 1895.219360,444.949066 1919.856812,425.961792
C1920.606323,425.384186 1921.105835,424.482330 1921.847656,423.089172
C1928.430298,429.842194 1935.039551,437.111328 1941.305908,444.664948
C1949.315918,454.320618 1957.049194,464.205841 1965.457031,474.440918
C1971.929443,482.804871 1977.872925,490.700562 1983.759277,498.638611
C2005.869629,528.454956 2028.232910,558.088623 2049.978027,588.169067
C2069.022461,614.513672 2087.332520,641.388733 2106.040283,667.977722
C2110.613770,674.478027 2115.475098,680.775757 2120.792480,688.318604
C2137.757812,714.539124 2154.416748,739.428955 2170.453125,764.713501
C2203.237061,816.403442 2236.358398,867.897522 2268.131592,920.206970
C2331.160645,1023.974548 2392.733398,1128.629761 2456.130127,1232.169922
C2502.684570,1308.203247 2551.182861,1383.046143 2598.819580,1458.416626
C2606.621094,1470.760376 2614.444092,1483.090332 2621.954590,1496.097168
C2618.607422,1499.165527 2615.891357,1502.333008 2612.450439,1503.802002
C2605.073486,1506.951294 2604.152588,1507.446167 2604.032471,1515.132568
C2603.897705,1523.789062 2604.108398,1532.451172 2603.963867,1541.107300
C2603.843994,1548.286621 2602.694336,1549.708496 2596.233154,1551.973877
C2588.952637,1554.526489 2588.151611,1555.529907 2588.024658,1563.421997
C2587.912109,1570.413696 2587.739502,1577.420410 2588.056885,1584.399536
C2588.638184,1597.189209 2586.568604,1600.786499 2571.913086,1600.059448
C2564.936768,1599.713501 2557.926514,1599.886475 2550.936279,1600.034058
C2543.345947,1600.194214 2541.174805,1601.625488 2540.164795,1608.753540
C2539.476074,1613.615112 2537.586426,1615.498047 2532.730713,1616.164673
C2525.914307,1617.100342 2524.348389,1619.297485 2524.039795,1625.958984
C2523.854980,1629.946777 2524.055420,1633.950806 2523.989258,1637.946167
C2523.839600,1646.980225 2523.061035,1648.294434 2514.366943,1649.922241
C2509.858154,1650.766357 2507.992188,1652.881714 2508.016602,1657.209961
C2508.042725,1661.872070 2508.115234,1666.537964 2507.971924,1671.196045
C2507.731934,1678.994263 2505.926758,1680.896851 2498.125000,1682.001465
C2490.575684,1683.070557 2490.143555,1683.447021 2490.030518,1691.491577
C2489.904297,1700.481567 2490.041016,1709.474731 2489.988525,1718.466064
C2489.933350,1727.900146 2489.933838,1728.102905 2480.367920,1729.940796
C2476.506104,1730.682983 2473.896973,1732.197632 2474.138916,1736.204590
C2474.559082,1743.160889 2471.037354,1745.869751 2464.662109,1746.018921
C2460.758545,1746.110229 2457.939209,1747.873291 2458.169922,1751.928223
C2458.598389,1759.460449 2454.672363,1761.946777 2447.941162,1762.106445
C2443.852051,1762.203369 2441.835693,1764.765625 2442.097900,1768.652100
C2442.538086,1775.177490 2439.103027,1777.794556 2433.211670,1777.949463
C2428.223145,1778.080566 2426.368164,1780.488892 2425.892090,1785.367188
C2425.209473,1792.360596 2423.708740,1793.238159 2416.490723,1794.037598
C2412.923096,1794.432861 2409.414795,1795.362427 2405.879639,1796.050171
C2388.402588,1771.787720 2370.557617,1747.780518 2353.514893,1723.216919
C2292.420898,1635.162964 2236.495605,1543.810059 2181.471191,1451.904907
C2138.599121,1380.297363 2096.380859,1308.298096 2053.494629,1236.699097
C2010.945679,1165.663940 1967.924438,1094.911743 1924.562744,1023.560120
C1914.943726,1008.065247 1906.261963,992.793518 1896.731934,978.070801
C1861.581787,923.768250 1826.250610,869.582031 1790.754517,815.504944
C1782.042847,802.233154 1772.448242,789.540955 1762.550049,775.586182
C1739.096924,743.117676 1716.540894,711.507324 1693.536255,680.227051
C1680.572388,662.599670 1666.869019,645.516174 1653.498657,628.187744
z"/>
<path fill="#027BF3" opacity="1.000000" stroke="none"
d="
M3124.119141,875.997559
C3129.657959,875.671387 3134.300537,876.419861 3134.060303,883.674622
C3133.925293,887.756653 3136.489990,889.438538 3140.136963,890.327698
C3145.866211,891.724548 3150.755615,893.705139 3150.381836,901.340088
C3150.174561,905.575256 3154.673340,905.850281 3157.719971,906.838318
C3162.320312,908.330139 3166.610352,909.699646 3166.132568,916.022339
C3165.819580,920.164062 3168.984863,921.433899 3172.457764,922.440979
C3177.353271,923.860657 3180.220947,926.737488 3180.169922,932.533997
C3180.123779,937.769775 3181.508545,943.005005 3182.034668,948.263184
C3182.452881,952.444824 3185.319824,953.564453 3188.714355,954.507202
C3193.995117,955.973938 3198.814697,957.663391 3198.295166,964.957092
C3197.992920,969.201904 3202.187012,969.825562 3205.353516,970.699097
C3210.486328,972.115234 3214.674805,973.913269 3214.214600,980.631958
C3213.926025,984.845154 3217.848145,985.489929 3221.027832,986.643860
C3229.947266,989.880432 3229.978516,989.966370 3229.988525,999.331970
C3230.020020,1028.658569 3229.830811,1057.986694 3230.114502,1087.310547
C3230.189209,1095.038208 3228.175049,1100.337646 3219.960938,1101.765625
C3215.561279,1102.530518 3213.942871,1105.270264 3213.983398,1109.552368
C3214.077393,1119.549194 3214.188477,1129.552002 3213.932129,1139.543091
C3213.803223,1144.566528 3216.361816,1146.558838 3220.678223,1147.877319
C3229.477295,1150.565063 3229.969971,1151.249756 3229.979004,1160.349121
C3230.023926,1206.671753 3230.020020,1252.994385 3229.982178,1299.317017
C3229.975098,1307.960205 3229.895752,1308.080566 3221.063477,1310.096680
C3216.094238,1311.231079 3213.896240,1313.746460 3213.920410,1319.095337
C3214.082520,1355.086304 3214.100830,1391.078735 3213.903809,1427.069458
C3213.872314,1432.801270 3216.189697,1435.261108 3221.441162,1436.918335
C3229.996338,1439.617920 3229.951172,1439.975586 3229.984619,1448.810303
C3230.040039,1463.473389 3229.834961,1478.139648 3230.082031,1492.798584
C3230.175049,1498.312988 3228.403076,1501.287964 3222.801270,1502.811279
C3213.282959,1505.399536 3214.012451,1506.136597 3214.004883,1515.540405
C3213.989746,1533.869507 3214.028320,1552.198608 3213.987549,1570.527588
C3213.968506,1579.165039 3215.337891,1580.436157 3205.135010,1583.209839
C3199.469971,1584.749756 3197.866455,1587.812378 3197.922363,1593.268555
C3198.123535,1612.928589 3198.089111,1632.592651 3197.939697,1652.253540
C3197.900391,1657.427734 3198.665283,1661.283569 3204.697998,1662.602051
C3209.787842,1663.714355 3211.290527,1667.411499 3212.293945,1672.754639
C3215.284668,1688.677246 3213.619385,1704.618530 3213.913086,1720.532349
C3214.276123,1740.187744 3213.961182,1759.855103 3214.018555,1779.517090
C3214.042969,1787.869141 3214.000488,1788.290527 3221.937012,1790.823242
C3228.210449,1792.824829 3230.147217,1796.777832 3230.029297,1802.757812
C3229.891357,1809.753540 3229.797852,1816.762085 3230.083496,1823.748901
C3230.230225,1827.338867 3231.201416,1830.901489 3231.876709,1834.461792
C3232.510254,1837.799072 3234.537598,1839.312256 3237.952148,1840.041016
C3245.820557,1841.720215 3245.927246,1841.927246 3245.968994,1849.579224
C3246.065186,1867.241333 3245.916016,1884.905029 3246.069824,1902.566284
C3246.101074,1906.156250 3246.963623,1909.748779 3247.556152,1913.321533
C3248.227783,1917.370361 3250.187012,1920.200562 3254.781250,1919.971313
C3259.901611,1919.715454 3261.657227,1922.890747 3262.696533,1927.177734
C3263.926758,1932.251831 3265.689697,1936.519531 3272.459961,1936.251465
C3277.265137,1936.061279 3277.906250,1940.074707 3278.033447,1944.061279
C3278.202148,1949.353149 3278.041504,1954.768799 3279.142090,1959.890747
C3280.752930,1967.389160 3281.750488,1967.866211 3289.311035,1967.968018
C3298.640625,1968.093628 3307.978760,1967.810913 3317.301270,1968.097168
C3320.849854,1968.206177 3324.364990,1969.404053 3328.764160,1970.594604
C3319.936523,1981.369751 3310.385742,1991.799072 3300.463867,2001.863159
C3297.062744,2005.313232 3292.555664,2007.643311 3288.863037,2010.841919
C3279.201660,2019.210449 3270.111572,2028.291626 3260.036133,2036.112671
C3250.577148,2043.454956 3240.307373,2049.803711 3230.114014,2056.138184
C3208.990967,2069.264404 3187.299561,2081.358398 3164.256836,2090.877930
C3130.298096,2104.907227 3095.446289,2115.807861 3059.198730,2122.304932
C3012.449951,2130.684570 2965.358398,2131.753174 2918.120850,2129.636230
C2858.661133,2126.971191 2800.833984,2116.038818 2744.646973,2092.858887
C2744.010254,2085.926514 2743.756104,2080.247559 2744.104004,2074.605469
C2744.522461,2067.814941 2746.681152,2065.140625 2753.453857,2064.106201
C2758.660400,2063.311279 2760.120117,2060.556885 2760.004883,2055.964355
C2759.938232,2053.301270 2759.999268,2050.635010 2759.999756,2047.970215
C2760.002197,2035.978516 2759.835205,2023.983765 2760.064209,2011.996338
C2760.218994,2003.886597 2762.027832,2001.656982 2770.059082,2000.036499
C2774.708008,1999.098389 2776.349121,1996.471313 2775.938232,1992.364014
C2773.766113,1970.651611 2779.981201,1949.484375 2779.963623,1927.928833
C2779.959961,1923.419678 2781.515381,1919.614380 2785.784180,1918.537109
C2790.644531,1917.310669 2792.018066,1914.002930 2792.955078,1910.033081
C2794.080811,1905.265259 2796.813965,1902.400391 2801.791016,1902.016602
C2807.148438,1901.603394 2808.097168,1898.079346 2808.014160,1893.624512
C2807.933594,1889.296021 2807.775879,1884.946533 2808.089600,1880.638306
C2808.570312,1874.039307 2811.740479,1870.816162 2817.873047,1870.062134
C2825.790039,1869.088745 2829.784668,1872.383911 2829.949707,1880.550903
C2830.151123,1890.539917 2830.001709,1900.536011 2830.020264,1910.529053
C2830.026855,1914.118652 2830.744141,1917.684082 2835.146729,1917.558960
C2839.538574,1917.434326 2839.979004,1913.745605 2839.990723,1910.225464
C2840.003662,1906.228271 2839.873047,1902.225952 2840.031738,1898.234985
C2840.355225,1890.106934 2842.395264,1887.195557 2850.292725,1886.208496
C2855.656738,1885.537964 2858.026611,1883.566772 2858.114746,1878.167603
C2858.189941,1873.578491 2861.072510,1871.128052 2865.479248,1870.043091
C2873.850586,1867.982056 2873.839355,1867.891602 2873.992432,1859.918091
C2874.037109,1857.587280 2874.028320,1855.254395 2873.994629,1852.923218
C2873.874512,1844.569946 2873.766357,1844.834961 2865.850830,1841.841553
C2863.034424,1840.776367 2859.701416,1838.589722 2858.554688,1836.038208
C2854.146729,1826.233276 2854.441650,1826.100708 2845.038330,1826.000122
C2823.888672,1825.773804 2823.554932,1825.454834 2824.038818,1803.992188
C2824.097900,1801.372070 2824.340820,1798.658569 2825.106689,1796.175903
C2826.117432,1792.900513 2828.089844,1790.686890 2832.019287,1789.923828
C2839.839600,1788.405029 2839.817627,1788.107300 2839.984131,1780.359619
C2840.070068,1776.364258 2839.429199,1772.255615 2840.168457,1768.400024
C2840.870117,1764.740723 2842.944092,1761.344482 2845.094482,1757.953979
C2846.957031,1758.684204 2848.181885,1759.223022 2849.315674,1759.912109
C2884.123535,1781.061401 2922.422363,1789.291260 2962.585449,1789.467163
C2977.108643,1789.530884 2991.784424,1788.138184 3006.143066,1785.853760
C3042.752197,1780.029541 3075.251953,1765.001953 3102.792969,1739.865601
C3133.556885,1711.788208 3153.571533,1676.854492 3168.039551,1638.250000
C3182.709229,1599.107666 3190.869873,1558.449219 3195.398193,1517.148926
C3198.395996,1489.809814 3199.830566,1462.192871 3200.072266,1434.683716
C3200.410645,1396.118774 3199.170410,1357.534058 3198.236084,1318.966797
C3197.834473,1302.379517 3196.950684,1285.775757 3195.493408,1269.249268
C3193.373779,1245.217285 3190.593994,1221.242310 3187.989258,1197.254639
C3185.959229,1178.559937 3184.316406,1159.800049 3181.516357,1141.217651
C3177.494141,1114.526367 3172.410400,1087.996948 3168.080322,1061.349731
C3161.791260,1022.644165 3152.650146,984.569336 3142.986572,946.614990
C3136.975098,923.005188 3130.426758,899.532043 3124.119141,875.997559
z"/>
<path fill="#0572EA" opacity="1.000000" stroke="none"
d="
M2844.414307,1757.832642
C2842.944092,1761.344482 2840.870117,1764.740723 2840.168457,1768.400024
C2839.429199,1772.255615 2840.070068,1776.364258 2839.984131,1780.359619
C2839.817627,1788.107300 2839.839600,1788.405029 2832.019287,1789.923828
C2828.089844,1790.686890 2826.117432,1792.900513 2825.106689,1796.175903
C2824.340820,1798.658569 2824.097900,1801.372070 2824.038818,1803.992188
C2823.554932,1825.454834 2823.888672,1825.773804 2845.038330,1826.000122
C2854.441650,1826.100708 2854.146729,1826.233276 2858.554688,1836.038208
C2859.701416,1838.589722 2863.034424,1840.776367 2865.850830,1841.841553
C2873.766357,1844.834961 2873.874512,1844.569946 2873.994629,1852.923218
C2874.028320,1855.254395 2874.037109,1857.587280 2873.992432,1859.918091
C2873.839355,1867.891602 2873.850586,1867.982056 2865.479248,1870.043091
C2861.072510,1871.128052 2858.189941,1873.578491 2858.114746,1878.167603
C2858.026611,1883.566772 2855.656738,1885.537964 2850.292725,1886.208496
C2842.395264,1887.195557 2840.355225,1890.106934 2840.031738,1898.234985
C2839.873047,1902.225952 2840.003662,1906.228271 2839.990723,1910.225464
C2839.979004,1913.745605 2839.538574,1917.434326 2835.146729,1917.558960
C2830.744141,1917.684082 2830.026855,1914.118652 2830.020264,1910.529053
C2830.001709,1900.536011 2830.151123,1890.539917 2829.949707,1880.550903
C2829.784668,1872.383911 2825.790039,1869.088745 2817.873047,1870.062134
C2811.740479,1870.816162 2808.570312,1874.039307 2808.089600,1880.638306
C2807.775879,1884.946533 2807.933594,1889.296021 2808.014160,1893.624512
C2808.097168,1898.079346 2807.148438,1901.603394 2801.791016,1902.016602
C2796.813965,1902.400391 2794.080811,1905.265259 2792.955078,1910.033081
C2792.018066,1914.002930 2790.644531,1917.310669 2785.784180,1918.537109
C2781.515381,1919.614380 2779.959961,1923.419678 2779.963623,1927.928833
C2779.981201,1949.484375 2773.766113,1970.651611 2775.938232,1992.364014
C2776.349121,1996.471313 2774.708008,1999.098389 2770.059082,2000.036499
C2762.027832,2001.656982 2760.218994,2003.886597 2760.064209,2011.996338
C2759.835205,2023.983765 2760.002197,2035.978516 2759.999756,2047.970215
C2759.999268,2050.635010 2759.938232,2053.301270 2760.004883,2055.964355
C2760.120117,2060.556885 2758.660400,2063.311279 2753.453857,2064.106201
C2746.681152,2065.140625 2744.522461,2067.814941 2744.104004,2074.605469
C2743.756104,2080.247559 2744.010254,2085.926514 2744.002441,2092.465820
C2707.032715,2079.486816 2672.828369,2060.379639 2640.292725,2038.212769
C2610.822998,2018.135010 2583.546631,1995.357666 2557.441162,1971.051392
C2508.332275,1925.326782 2465.214844,1874.351562 2424.761719,1820.190430
C2426.520508,1813.980347 2424.067627,1810.867920 2419.479492,1808.026001
C2418.859131,1809.680420 2418.441162,1810.795288 2418.022949,1811.910156
C2414.079590,1807.066040 2410.135986,1802.221924 2406.036133,1796.713989
C2409.414795,1795.362427 2412.923096,1794.432861 2416.490723,1794.037598
C2423.708740,1793.238159 2425.209473,1792.360596 2425.892090,1785.367188
C2426.368164,1780.488892 2428.223145,1778.080566 2433.211670,1777.949463
C2439.103027,1777.794556 2442.538086,1775.177490 2442.097900,1768.652100
C2441.835693,1764.765625 2443.852051,1762.203369 2447.941162,1762.106445
C2454.672363,1761.946777 2458.598389,1759.460449 2458.169922,1751.928223
C2457.939209,1747.873291 2460.758545,1746.110229 2464.662109,1746.018921
C2471.037354,1745.869751 2474.559082,1743.160889 2474.138916,1736.204590
C2473.896973,1732.197632 2476.506104,1730.682983 2480.367920,1729.940796
C2489.933838,1728.102905 2489.933350,1727.900146 2489.988525,1718.466064
C2490.041016,1709.474731 2489.904297,1700.481567 2490.030518,1691.491577
C2490.143555,1683.447021 2490.575684,1683.070557 2498.125000,1682.001465
C2505.926758,1680.896851 2507.731934,1678.994263 2507.971924,1671.196045
C2508.115234,1666.537964 2508.042725,1661.872070 2508.016602,1657.209961
C2507.992188,1652.881714 2509.858154,1650.766357 2514.366943,1649.922241
C2523.061035,1648.294434 2523.839600,1646.980225 2523.989258,1637.946167
C2524.055420,1633.950806 2523.854980,1629.946777 2524.039795,1625.958984
C2524.348389,1619.297485 2525.914307,1617.100342 2532.730713,1616.164673
C2537.586426,1615.498047 2539.476074,1613.615112 2540.164795,1608.753540
C2541.174805,1601.625488 2543.345947,1600.194214 2550.936279,1600.034058
C2557.926514,1599.886475 2564.936768,1599.713501 2571.913086,1600.059448
C2586.568604,1600.786499 2588.638184,1597.189209 2588.056885,1584.399536
C2587.739502,1577.420410 2587.912109,1570.413696 2588.024658,1563.421997
C2588.151611,1555.529907 2588.952637,1554.526489 2596.233154,1551.973877
C2602.694336,1549.708496 2603.843994,1548.286621 2603.963867,1541.107300
C2604.108398,1532.451172 2603.897705,1523.789062 2604.032471,1515.132568
C2604.152588,1507.446167 2605.073486,1506.951294 2612.450439,1503.802002
C2615.891357,1502.333008 2618.607422,1499.165527 2622.504883,1496.514404
C2645.215088,1528.045166 2666.787354,1560.030396 2688.999268,1591.565186
C2720.412109,1636.162598 2754.792480,1678.378662 2792.786865,1717.572266
C2797.095459,1722.016846 2802.473145,1725.407349 2806.970459,1729.690796
C2818.365967,1740.544434 2830.673340,1750.127319 2844.414307,1757.832642
z"/>
<path fill="#017BF4" opacity="1.000000" stroke="none"
d="
M689.887207,1501.998901
C686.889343,1501.999268 683.882385,1501.849731 680.895508,1502.031250
C674.736328,1502.405151 669.568359,1501.378418 667.745361,1494.324341
C666.830994,1490.786377 663.999756,1489.994873 660.754456,1490.013794
C657.090637,1490.035156 653.426025,1490.051880 649.762756,1489.998413
C645.648499,1489.938354 642.729065,1491.112915 641.987610,1495.816528
C640.846313,1503.057373 635.380432,1505.316772 629.038269,1505.910400
C625.074463,1506.281494 621.050476,1506.026001 617.053467,1506.021973
C613.256592,1506.018188 610.696716,1507.428711 610.054077,1511.534180
C608.831360,1519.344971 603.023499,1521.346924 596.331177,1521.952637
C593.687805,1522.191895 591.001709,1522.085693 588.341125,1521.981934
C582.983765,1521.773071 578.244690,1522.062744 577.703430,1529.225830
C577.429749,1532.847778 574.412354,1533.508667 571.173401,1534.040649
C555.130371,1536.675659 539.108948,1539.287231 522.748108,1538.016479
C518.378662,1537.677002 515.492676,1538.926270 513.601562,1543.672729
C511.218323,1549.654053 499.991699,1552.455444 494.819489,1548.982788
C493.594177,1548.159912 492.379852,1546.409546 492.266785,1544.997314
C491.750031,1538.543213 487.578857,1537.802246 482.422760,1537.966553
C477.764771,1538.114990 473.070282,1538.285767 468.440796,1537.883667
C461.809479,1537.307739 459.677185,1533.716919 460.005615,1524.746094
C460.276031,1517.359863 461.315216,1516.184204 468.887115,1516.043823
C477.877625,1515.876953 486.874207,1516.070312 495.866943,1515.980591
C505.005798,1515.889526 506.325775,1515.078857 507.914734,1506.440918
C508.740936,1501.949341 510.786285,1500.003296 515.138428,1500.021118
C519.468506,1500.038696 523.800659,1500.082520 528.128113,1499.969727
C530.436462,1499.909790 532.966187,1500.058838 534.973572,1499.164795
C536.824951,1498.340210 538.111816,1496.247925 539.647278,1494.713989
C537.793335,1493.164917 536.074585,1490.529053 534.059204,1490.278442
C528.808411,1489.625488 523.422058,1490.161499 518.099915,1489.958374
C511.336029,1489.700317 509.564392,1488.077881 508.019897,1481.426270
C506.358917,1474.272705 506.360748,1474.153198 498.826843,1474.034302
C490.168488,1473.897705 481.501343,1473.823608 472.847839,1474.068604
C467.926147,1474.208008 463.962433,1473.171143 460.226685,1469.566040
C458.116272,1467.529663 454.489563,1466.472046 451.422821,1466.151733
C446.235809,1465.610107 440.951263,1466.003174 434.466553,1466.003174
C432.547546,1469.702271 429.120392,1473.769043 422.656586,1474.475952
C420.931824,1474.664551 418.914917,1477.790649 418.128693,1479.964600
C414.998810,1488.619263 413.728851,1489.760132 404.590240,1489.991333
C402.592926,1490.041870 400.593262,1489.994019 398.594727,1490.000977
C388.967133,1490.034546 388.908264,1490.012573 385.414948,1498.911987
C383.439331,1503.944946 379.669708,1505.973145 374.524475,1505.982666
C366.530273,1505.997559 358.536072,1505.993896 349.659424,1506.001465
C347.838562,1494.461792 346.355988,1482.932617 346.064819,1471.373535
C345.228210,1438.160645 344.555695,1404.936523 344.457062,1371.714966
C344.403931,1353.812866 345.294647,1335.884277 346.407440,1318.007935
C348.074158,1291.234009 350.311218,1264.495605 353.390869,1236.868652
C360.361084,1235.512451 367.444305,1236.896118 371.831604,1234.079834
C377.470428,1230.460327 382.751251,1230.007080 388.670166,1230.005249
C423.939362,1229.994629 459.209900,1230.146973 494.476318,1229.834839
C499.518860,1229.790161 506.480591,1229.142212 509.154968,1225.937134
C514.146423,1219.955444 519.688721,1219.976562 526.024780,1219.981934
C567.283081,1220.017090 608.541504,1220.040161 649.799500,1219.928345
C653.336731,1219.918701 657.935974,1220.095215 660.183655,1218.095947
C664.767090,1214.019409 669.675842,1213.940186 675.014893,1213.983887
C682.667175,1214.046753 690.320251,1213.999146 698.116943,1214.876953
C696.039001,1239.863281 693.519531,1263.948730 691.674133,1288.085571
C689.575928,1315.529053 687.452759,1342.997070 686.506409,1370.494507
C685.635925,1395.786133 686.303833,1421.131104 686.323242,1446.452515
C686.325256,1449.109985 686.464783,1451.771240 686.642883,1454.423950
C687.707642,1470.283447 688.802490,1486.140747 689.887207,1501.998901
z"/>
<path fill="#0169E3" opacity="1.000000" stroke="none"
d="
M525.417358,600.341858
C527.484802,601.626709 529.122864,604.907288 530.522034,604.808350
C540.113953,604.130371 544.499451,616.377136 554.624207,614.098022
C557.476929,613.455750 560.656372,613.636536 563.578064,614.108215
C566.384033,614.561279 569.892883,615.106018 571.609619,616.973816
C575.703430,621.427856 580.423584,622.426819 586.001526,622.034546
C591.040527,621.680054 595.947998,621.605530 599.146606,626.914612
C600.017456,628.359985 602.470703,629.476807 604.280640,629.608948
C608.817261,629.940247 612.145630,631.400513 615.442505,634.920410
C617.520630,637.139221 622.024048,637.644348 625.505432,637.861450
C630.853149,638.195068 636.075439,637.546021 639.527649,643.244080
C640.485657,644.825317 643.622681,645.054138 645.724182,645.984253
C647.792664,646.899719 650.437927,647.404785 651.742065,648.986755
C655.636292,653.710938 660.560974,654.430359 666.106506,654.020508
C671.196228,653.644226 675.932251,653.846985 679.250977,658.963745
C680.302612,660.585022 683.222717,661.607178 685.373230,661.769226
C689.277039,662.063416 691.842773,663.610168 694.778381,666.287354
C697.364136,668.645386 701.880249,669.636719 705.610657,669.812134
C711.073608,670.068970 715.610168,670.818481 720.216919,674.565613
C725.116516,678.551025 732.030212,679.430664 736.743835,684.663696
C738.533203,686.650330 743.647888,685.939819 747.244751,685.924805
C751.710999,685.906128 755.620605,686.394043 759.112183,689.805237
C761.125122,691.771912 764.311890,693.633362 766.968811,693.631287
C773.895020,693.625854 779.432983,695.047424 784.513184,700.468506
C786.550171,702.642151 792.025208,701.794739 795.949707,701.943115
C800.001770,702.096436 804.015930,701.767639 806.204956,706.303467
C807.948242,709.915771 811.343201,710.248657 814.773315,709.968628
C821.140564,709.448608 826.285400,711.542664 831.135803,715.781067
C833.699036,718.020813 837.636536,718.687683 841.614868,720.856323
C841.286133,724.104919 840.460693,726.643982 839.281616,729.006592
C818.312805,771.023438 799.732605,814.078369 784.073059,858.338989
C774.677612,884.894653 766.289368,911.805542 757.283447,938.501099
C755.937683,942.490234 753.685425,946.173584 751.024536,949.998413
C747.671509,949.694885 745.146423,949.391357 742.330078,949.052856
C742.859131,937.844971 737.153137,933.224792 727.255127,933.395691
C726.753357,931.957214 726.311951,931.067383 726.135315,930.127747
C724.181580,919.731445 722.327087,918.144531 711.639465,918.010193
C706.978516,917.951599 702.316162,917.978577 697.654602,918.004150
C685.174011,918.072632 683.895020,919.175476 681.363586,931.747437
C681.252380,932.299927 680.571594,932.737732 679.503967,934.000000
C676.875610,934.000000 673.592346,934.000000 670.309143,934.000000
C647.999756,934.000000 625.687256,934.209900 603.382751,933.881409
C595.989197,933.772583 589.573425,934.737488 584.891602,941.041199
C584.660828,941.351807 583.647461,941.081177 581.515381,941.081177
C581.032776,937.636841 580.223206,933.962708 580.057495,930.259644
C579.651367,921.180420 577.285645,918.362610 568.213684,918.070435
C559.232544,917.781250 550.234131,918.067566 541.245361,917.946350
C539.151672,917.918152 537.066406,917.262207 534.977295,916.895020
C534.800110,916.182373 534.622864,915.469788 534.445679,914.757141
C536.545410,913.849060 538.584778,912.391357 540.758118,912.152649
C544.707336,911.718933 548.738220,912.087402 552.731323,911.982117
C561.214661,911.758484 563.596680,909.519348 563.994690,901.587708
C564.562256,890.276733 562.389404,886.395508 553.539062,886.170776
C535.902893,885.722961 518.243713,885.834045 500.602264,886.159729
C495.564026,886.252686 491.213257,888.037598 489.786591,894.379150
C488.081451,901.958496 487.539429,901.930298 479.456879,901.978088
C466.138306,902.056824 452.818695,902.048462 439.500031,901.977966
C433.890411,901.948303 428.900604,902.999939 425.821655,908.317871
C423.557983,912.227722 420.261658,912.500000 416.347137,911.179382
C414.490540,910.552979 412.483978,910.371094 410.545349,909.987854
C418.963989,881.056335 426.900055,851.973633 435.903198,823.225159
C453.860352,765.885071 475.205322,709.784912 499.669006,654.898376
C507.770294,636.722412 516.457947,618.807861 525.417358,600.341858
z"/>
<path fill="#0172ED" opacity="1.000000" stroke="none"
d="
M697.973022,1213.998779
C690.320251,1213.999146 682.667175,1214.046753 675.014893,1213.983887
C669.675842,1213.940186 664.767090,1214.019409 660.183655,1218.095947
C657.935974,1220.095215 653.336731,1219.918701 649.799500,1219.928345
C608.541504,1220.040161 567.283081,1220.017090 526.024780,1219.981934
C519.688721,1219.976562 514.146423,1219.955444 509.154968,1225.937134
C506.480591,1229.142212 499.518860,1229.790161 494.476318,1229.834839
C459.209900,1230.146973 423.939362,1229.994629 388.670166,1230.005249
C382.751251,1230.007080 377.470428,1230.460327 371.831604,1234.079834
C367.444305,1236.896118 360.361084,1235.512451 353.625305,1235.998291
C353.318787,1227.768066 353.435852,1219.480469 354.482086,1211.311768
C358.719604,1178.227051 362.910583,1145.130005 367.768280,1112.133301
C371.503815,1086.758789 376.203705,1061.526123 380.514740,1036.237183
C380.676208,1035.289917 381.258087,1034.414307 382.750275,1032.729736
C387.421356,1031.304077 390.980103,1030.133789 394.552032,1030.092285
C411.505096,1029.894531 428.468628,1029.741577 445.412445,1030.184082
C449.811676,1030.299072 455.348724,1031.401978 458.223846,1034.227783
C461.957428,1037.897339 465.634399,1037.987427 469.886871,1037.991333
C491.164215,1038.010498 512.441895,1038.058716 533.718689,1037.955811
C538.538513,1037.932495 543.506592,1038.157837 546.480896,1042.115356
C549.429932,1046.039429 553.005310,1046.020630 557.022034,1046.013916
C575.972168,1045.982178 594.922729,1046.065186 613.872253,1045.955200
C618.705505,1045.927246 623.637695,1046.247803 626.594727,1050.218506
C629.551941,1054.189453 633.195068,1054.008789 637.175598,1054.006592
C661.777527,1053.993286 686.380310,1053.893555 710.980652,1054.090454
C715.873718,1054.129639 720.757568,1055.329834 725.695923,1056.790771
C721.357361,1079.376465 716.324280,1101.060791 712.741150,1122.982178
C708.149780,1151.071167 700.556946,1178.710571 699.631226,1207.378052
C699.559448,1209.600586 698.547852,1211.792603 697.973022,1213.998779
z"/>
<path fill="#016DE9" opacity="1.000000" stroke="none"
d="
M725.645630,1055.994629
C720.757568,1055.329834 715.873718,1054.129639 710.980652,1054.090454
C686.380310,1053.893555 661.777527,1053.993286 637.175598,1054.006592
C633.195068,1054.008789 629.551941,1054.189453 626.594727,1050.218506
C623.637695,1046.247803 618.705505,1045.927246 613.872253,1045.955200
C594.922729,1046.065186 575.972168,1045.982178 557.022034,1046.013916
C553.005310,1046.020630 549.429932,1046.039429 546.480896,1042.115356
C543.506592,1038.157837 538.538513,1037.932495 533.718689,1037.955811
C512.441895,1038.058716 491.164215,1038.010498 469.886871,1037.991333
C465.634399,1037.987427 461.957428,1037.897339 458.223846,1034.227783
C455.348724,1031.401978 449.811676,1030.299072 445.412445,1030.184082
C428.468628,1029.741577 411.505096,1029.894531 394.552032,1030.092285
C390.980103,1030.133789 387.421356,1031.304077 383.023071,1031.976196
C386.636688,1011.118896 391.083679,990.239441 396.168915,968.519409
C396.941528,967.501221 397.226868,967.259888 397.183533,967.157471
C397.020142,966.770691 396.749908,966.429138 396.519684,966.070618
C400.977783,947.855286 405.435883,929.639954 410.219666,910.706238
C412.483978,910.371094 414.490540,910.552979 416.347137,911.179382
C420.261658,912.500000 423.557983,912.227722 425.821655,908.317871
C428.900604,902.999939 433.890411,901.948303 439.500031,901.977966
C452.818695,902.048462 466.138306,902.056824 479.456879,901.978088
C487.539429,901.930298 488.081451,901.958496 489.786591,894.379150
C491.213257,888.037598 495.564026,886.252686 500.602264,886.159729
C518.243713,885.834045 535.902893,885.722961 553.539062,886.170776
C562.389404,886.395508 564.562256,890.276733 563.994690,901.587708
C563.596680,909.519348 561.214661,911.758484 552.731323,911.982117
C548.738220,912.087402 544.707336,911.718933 540.758118,912.152649
C538.584778,912.391357 536.545410,913.849060 534.445679,914.757141
C534.622864,915.469788 534.800110,916.182373 534.977295,916.895020
C537.066406,917.262207 539.151672,917.918152 541.245361,917.946350
C550.234131,918.067566 559.232544,917.781250 568.213684,918.070435
C577.285645,918.362610 579.651367,921.180420 580.057495,930.259644
C580.223206,933.962708 581.032776,937.636841 581.515381,941.081177
C583.647461,941.081177 584.660828,941.351807 584.891602,941.041199
C589.573425,934.737488 595.989197,933.772583 603.382751,933.881409
C625.687256,934.209900 647.999756,934.000000 670.309143,934.000000
C673.592346,934.000000 676.875610,934.000000 679.503967,934.000000
C680.571594,932.737732 681.252380,932.299927 681.363586,931.747437
C683.895020,919.175476 685.174011,918.072632 697.654602,918.004150
C702.316162,917.978577 706.978516,917.951599 711.639465,918.010193
C722.327087,918.144531 724.181580,919.731445 726.135315,930.127747
C726.311951,931.067383 726.753357,931.957214 727.255127,933.395691
C737.153137,933.224792 742.859131,937.844971 742.330078,949.052856
C745.146423,949.391357 747.671509,949.694885 751.281250,950.793335
C750.593689,958.852722 748.924255,966.143982 747.029053,973.376160
C742.330505,991.305786 737.471924,1009.193604 732.791138,1027.127808
C730.288086,1036.718384 728.019836,1046.370361 725.645630,1055.994629
z"/>
<path fill="#017BF4" opacity="1.000000" stroke="none"
d="
M357.973938,1588.815186
C362.009186,1587.425293 366.324738,1584.499146 369.077972,1589.779541
C366.593781,1594.490479 364.176819,1599.073975 361.062866,1603.823730
C359.522461,1599.203003 358.679077,1594.416016 357.973938,1588.815186
z"/>
<path fill="#0769E1" opacity="1.000000" stroke="none"
d="
M2418.188965,1812.535400
C2418.441162,1810.795288 2418.859131,1809.680420 2419.479492,1808.026001
C2424.067627,1810.867920 2426.520508,1813.980347 2424.590820,1819.534302
C2422.168701,1817.700073 2420.261963,1815.430420 2418.188965,1812.535400
z"/>
<path fill="#0172ED" opacity="1.000000" stroke="none"
d="
M396.268494,966.517395
C396.749908,966.429138 397.020142,966.770691 397.183533,967.157471
C397.226868,967.259888 396.941528,967.501221 396.503662,967.825806
C396.139221,967.636597 396.078247,967.300415 396.268494,966.517395
z"/>
<path fill="#FFFFFF" opacity="1.000000" stroke="none"
d="
M2845.094482,1757.953979
C2830.673340,1750.127319 2818.365967,1740.544434 2806.970459,1729.690796
C2802.473145,1725.407349 2797.095459,1722.016846 2792.786865,1717.572266
C2754.792480,1678.378662 2720.412109,1636.162598 2688.999268,1591.565186
C2666.787354,1560.030396 2645.215088,1528.045166 2622.807373,1495.843750
C2614.444092,1483.090332 2606.621094,1470.760376 2598.819580,1458.416626
C2551.182861,1383.046143 2502.684570,1308.203247 2456.130127,1232.169922
C2392.733398,1128.629761 2331.160645,1023.974548 2268.131592,920.206970
C2236.358398,867.897522 2203.237061,816.403442 2170.453125,764.713501
C2154.416748,739.428955 2137.757812,714.539124 2121.271484,688.739990
C2138.561035,662.407959 2155.796631,636.694031 2173.394043,611.229797
C2205.948486,564.121277 2240.786865,518.749939 2278.817139,475.925049
C2310.688232,440.036011 2345.022461,406.670746 2383.605713,377.919891
C2420.707764,350.272766 2460.655029,328.085358 2505.437744,315.433136
C2537.328125,306.423309 2569.782471,302.758301 2602.993164,304.158508
C2670.895508,307.021423 2732.377686,329.126862 2789.463379,364.861877
C2829.772461,390.095032 2865.584717,420.875366 2897.911377,455.566467
C2943.257324,504.229218 2981.187500,558.366089 3013.921875,616.217529
C3050.718750,681.249329 3080.725098,749.307983 3105.083984,819.891418
C3111.370117,838.106140 3117.249756,856.461182 3123.717773,875.374634
C3130.426758,899.532043 3136.975098,923.005188 3142.986572,946.614990
C3152.650146,984.569336 3161.791260,1022.644165 3168.080322,1061.349731
C3172.410400,1087.996948 3177.494141,1114.526367 3181.516357,1141.217651
C3184.316406,1159.800049 3185.959229,1178.559937 3187.989258,1197.254639
C3190.593994,1221.242310 3193.373779,1245.217285 3195.493408,1269.249268
C3196.950684,1285.775757 3197.834473,1302.379517 3198.236084,1318.966797
C3199.170410,1357.534058 3200.410645,1396.118774 3200.072266,1434.683716
C3199.830566,1462.192871 3198.395996,1489.809814 3195.398193,1517.148926
C3190.869873,1558.449219 3182.709229,1599.107666 3168.039551,1638.250000
C3153.571533,1676.854492 3133.556885,1711.788208 3102.792969,1739.865601
C3075.251953,1765.001953 3042.752197,1780.029541 3006.143066,1785.853760
C2991.784424,1788.138184 2977.108643,1789.530884 2962.585449,1789.467163
C2922.422363,1789.291260 2884.123535,1781.061401 2849.315674,1759.912109
C2848.181885,1759.223022 2846.957031,1758.684204 2845.094482,1757.953979
z"/>
<path fill="#FFFFFF" opacity="1.000000" stroke="none"
d="
M725.695923,1056.790771
C728.019836,1046.370361 730.288086,1036.718384 732.791138,1027.127808
C737.471924,1009.193604 742.330505,991.305786 747.029053,973.376160
C748.924255,966.143982 750.593689,958.852722 752.109192,950.793335
C753.685425,946.173584 755.937683,942.490234 757.283447,938.501099
C766.289368,911.805542 774.677612,884.894653 784.073059,858.338989
C799.732605,814.078369 818.312805,771.023438 839.281616,729.006592
C840.460693,726.643982 841.286133,724.104919 842.394836,720.910278
C848.289551,709.736938 854.183105,699.364319 859.821899,688.855042
C890.901733,630.930481 926.924255,576.359253 970.127930,526.703613
C1002.813293,489.137085 1039.184692,455.665894 1081.189453,428.641052
C1120.801636,403.155640 1163.442017,385.224945 1210.313843,378.614563
C1232.001099,375.556000 1253.802612,375.818970 1275.727051,377.450897
C1303.709595,379.533722 1331.004150,384.398529 1357.748413,392.712799
C1391.963501,403.349548 1423.747559,419.096039 1453.823242,438.413879
C1492.049438,462.967041 1526.395752,492.237183 1558.728149,524.062073
C1591.958984,556.771118 1622.792725,591.597046 1652.899414,627.916321
C1666.869019,645.516174 1680.572388,662.599670 1693.536255,680.227051
C1716.540894,711.507324 1739.096924,743.117676 1761.948608,775.277832
C1750.305908,793.616028 1738.446655,811.195435 1726.835815,828.937317
C1715.756958,845.866150 1704.937012,862.964294 1693.280273,881.028259
C1690.143921,885.633545 1687.662476,889.154602 1685.327759,892.770386
C1651.780029,944.725220 1618.196899,996.657288 1584.748779,1048.676147
C1572.529663,1067.679321 1560.642822,1086.895996 1548.604370,1106.015381
C1535.520020,1126.068237 1522.265625,1146.012573 1509.386719,1166.196533
C1483.262451,1207.138794 1457.571167,1248.358765 1431.275269,1289.189941
C1401.547974,1335.349365 1371.718140,1381.451050 1341.274170,1427.138794
C1297.733276,1492.481201 1253.023438,1557.019165 1203.855713,1618.325562
C1180.119873,1647.921387 1155.300537,1676.594727 1127.730225,1702.713257
C1100.578369,1728.435547 1071.303955,1751.318726 1037.116577,1767.224365
C1010.303406,1779.698975 982.114502,1786.156372 952.617065,1788.559448
C929.541443,1790.439575 906.824768,1789.308472 884.314453,1784.843018
C837.225525,1775.501953 798.488586,1751.827271 767.833435,1714.946045
C740.373474,1681.909424 722.666931,1643.781006 710.374451,1602.996216
C701.159607,1572.422485 694.637756,1541.244019 691.588196,1509.397217
C691.400696,1507.438599 690.733948,1505.526001 690.088684,1502.795410
C688.802490,1486.140747 687.707642,1470.283447 686.642883,1454.423950
C686.464783,1451.771240 686.325256,1449.109985 686.323242,1446.452515
C686.303833,1421.131104 685.635925,1395.786133 686.506409,1370.494507
C687.452759,1342.997070 689.575928,1315.529053 691.674133,1288.085571
C693.519531,1263.948730 696.039001,1239.863281 698.116943,1214.876953
C698.547852,1211.792603 699.559448,1209.600586 699.631226,1207.378052
C700.556946,1178.710571 708.149780,1151.071167 712.741150,1122.982178
C716.324280,1101.060791 721.357361,1079.376465 725.695923,1056.790771
z"/>
<path fill="#047FF9" opacity="1.000000" stroke="none"
d="
M1549.476807,1106.011475
C1560.642822,1086.895996 1572.529663,1067.679321 1584.748779,1048.676147
C1618.196899,996.657288 1651.780029,944.725220 1685.327759,892.770386
C1687.662476,889.154602 1690.143921,885.633545 1693.148926,881.689941
C1694.825684,882.801514 1695.676636,885.300781 1697.034058,885.615417
C1704.890259,887.436401 1703.781006,893.492310 1704.021240,899.074341
C1704.263184,904.697205 1703.860596,909.962463 1697.299316,911.884827
C1691.462891,913.594849 1689.974243,917.653748 1689.875977,923.282959
C1689.790283,928.197449 1688.533203,933.082092 1687.981812,938.001038
C1687.593140,941.468201 1685.776611,942.979614 1682.470215,944.047974
C1674.706421,946.556335 1674.229492,947.484558 1674.014771,955.215576
C1673.931641,958.210083 1674.148071,961.218323 1673.961426,964.203552
C1673.587280,970.188171 1672.229614,975.219177 1664.810913,976.309021
C1659.843262,977.038818 1657.890625,980.944824 1657.988892,985.880371
C1658.068481,989.874390 1657.924683,993.873047 1658.012695,997.866699
C1658.130981,1003.240112 1656.002686,1007.005432 1650.466309,1007.886597
C1645.536499,1008.671082 1642.657959,1011.143311 1641.973511,1016.142700
C1641.355469,1020.656311 1638.731567,1023.314331 1634.226807,1023.967224
C1628.126587,1024.851196 1625.814331,1028.613281 1625.992065,1034.423096
C1626.063354,1036.751709 1625.890747,1039.090698 1626.020386,1041.414185
C1626.441406,1048.961060 1625.801392,1055.332520 1615.995972,1056.558594
C1611.674683,1057.098999 1609.887573,1061.192749 1609.982544,1065.720459
C1610.087036,1070.712769 1610.197998,1075.720459 1609.927002,1080.700806
C1609.586670,1086.956299 1606.909302,1089.672363 1600.602661,1089.919678
C1593.666016,1090.191772 1586.710449,1089.981812 1579.374512,1089.981812
C1578.568481,1092.774902 1578.018066,1094.955322 1577.310059,1097.083252
C1575.401123,1102.821655 1571.197876,1105.663696 1565.330811,1105.925537
C1560.345703,1106.148193 1555.343628,1105.994751 1549.476807,1106.011475
z"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 64 KiB

After

Width:  |  Height:  |  Size: 33 KiB

@@ -3,15 +3,15 @@ import type { App_RoutingForms_Form } from "@prisma/client";
import { BaseEmailHtml, Info } from "@calcom/emails/src/components"; import { BaseEmailHtml, Info } from "@calcom/emails/src/components";
import { WEBAPP_URL } from "@calcom/lib/constants"; import { WEBAPP_URL } from "@calcom/lib/constants";
import type { Response } from "../../types/types"; import type { OrderedResponses } from "../../types/types";
export const ResponseEmail = ({ export const ResponseEmail = ({
form, form,
response, orderedResponses,
...props ...props
}: { }: {
form: Pick<App_RoutingForms_Form, "id" | "name">; form: Pick<App_RoutingForms_Form, "id" | "name">;
response: Response; orderedResponses: OrderedResponses;
subject: string; subject: string;
} & Partial<React.ComponentProps<typeof BaseEmailHtml>>) => { } & Partial<React.ComponentProps<typeof BaseEmailHtml>>) => {
return ( return (
@@ -36,11 +36,11 @@ export const ResponseEmail = ({
title={form.name} title={form.name}
subtitle="New Response Received" subtitle="New Response Received"
{...props}> {...props}>
{Object.entries(response).map(([fieldId, fieldResponse]) => { {orderedResponses.map((fieldResponse, index) => {
return ( return (
<Info <Info
withSpacer withSpacer
key={fieldId} key={index}
label={fieldResponse.label} label={fieldResponse.label}
description={ description={
fieldResponse.value instanceof Array ? fieldResponse.value.join(",") : fieldResponse.value fieldResponse.value instanceof Array ? fieldResponse.value.join(",") : fieldResponse.value
@@ -3,17 +3,25 @@ import type { App_RoutingForms_Form } from "@prisma/client";
import { renderEmail } from "@calcom/emails"; import { renderEmail } from "@calcom/emails";
import BaseEmail from "@calcom/emails/templates/_base-email"; import BaseEmail from "@calcom/emails/templates/_base-email";
import type { Response } from "../../types/types"; import type { OrderedResponses } from "../../types/types";
type Form = Pick<App_RoutingForms_Form, "id" | "name">; type Form = Pick<App_RoutingForms_Form, "id" | "name">;
export default class ResponseEmail extends BaseEmail { export default class ResponseEmail extends BaseEmail {
response: Response; orderedResponses: OrderedResponses;
toAddresses: string[]; toAddresses: string[];
form: Form; form: Form;
constructor({ toAddresses, response, form }: { form: Form; toAddresses: string[]; response: Response }) { constructor({
toAddresses,
orderedResponses,
form,
}: {
form: Form;
toAddresses: string[];
orderedResponses: OrderedResponses;
}) {
super(); super();
this.form = form; this.form = form;
this.response = response; this.orderedResponses = orderedResponses;
this.toAddresses = toAddresses; this.toAddresses = toAddresses;
} }
@@ -26,7 +34,7 @@ export default class ResponseEmail extends BaseEmail {
subject, subject,
html: renderEmail("ResponseEmail", { html: renderEmail("ResponseEmail", {
form: this.form, form: this.form,
response: this.response, orderedResponses: this.orderedResponses,
subject, subject,
}), }),
}; };
@@ -6,6 +6,7 @@ import logger from "@calcom/lib/logger";
import { WebhookTriggerEvents } from "@calcom/prisma/client"; import { WebhookTriggerEvents } from "@calcom/prisma/client";
import type { Ensure } from "@calcom/types/utils"; import type { Ensure } from "@calcom/types/utils";
import type { OrderedResponses } from "../types/types";
import type { Response, SerializableForm } from "../types/types"; import type { Response, SerializableForm } from "../types/types";
export async function onFormSubmission( export async function onFormSubmission(
@@ -61,23 +62,28 @@ export async function onFormSubmission(
}); });
await Promise.all(promises); await Promise.all(promises);
const orderedResponses = form.fields.reduce((acc, field) => {
acc.push(response[field.id]);
return acc;
}, [] as OrderedResponses);
if (form.settings?.emailOwnerOnSubmission) { if (form.settings?.emailOwnerOnSubmission) {
logger.debug( logger.debug(
`Preparing to send Form Response email for Form:${form.id} to form owner: ${form.user.email}` `Preparing to send Form Response email for Form:${form.id} to form owner: ${form.user.email}`
); );
await sendResponseEmail(form, response, form.user.email); await sendResponseEmail(form, orderedResponses, form.user.email);
} }
} }
export const sendResponseEmail = async ( export const sendResponseEmail = async (
form: Pick<App_RoutingForms_Form, "id" | "name">, form: Pick<App_RoutingForms_Form, "id" | "name">,
response: Response, orderedResponses: OrderedResponses,
ownerEmail: string ownerEmail: string
) => { ) => {
try { try {
if (typeof window === "undefined") { if (typeof window === "undefined") {
const { default: ResponseEmail } = await import("../emails/templates/response-email"); const { default: ResponseEmail } = await import("../emails/templates/response-email");
const email = new ResponseEmail({ form: form, toAddresses: [ownerEmail], response: response }); const email = new ResponseEmail({ form: form, toAddresses: [ownerEmail], orderedResponses });
await email.sendEmail(); await email.sendEmail();
} }
} catch (e) { } catch (e) {
+2
View File
@@ -45,3 +45,5 @@ export type SerializableRoute =
isFallback?: LocalRoute["isFallback"]; isFallback?: LocalRoute["isFallback"];
}) })
| GlobalRoute; | GlobalRoute;
export type OrderedResponses = Response[string][];
+4
View File
@@ -1,3 +1,7 @@
---
items:
- 1.jpg
---
Vital App is an app that can can help you combine your health peripherals with your calendar. Vital App is an app that can can help you combine your health peripherals with your calendar.
#### Supported Actions: #### Supported Actions:
+1 -1
View File
@@ -8,7 +8,7 @@ export const metadata = {
installed: true, installed: true,
category: "automation", category: "automation",
categories: ["automation"], categories: ["automation"],
logo: "icon.svg", logo: "icon-dark.svg",
label: "Vital", label: "Vital",
publisher: "Vital", publisher: "Vital",
slug: "vital-automation", slug: "vital-automation",
Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

+14 -2
View File
@@ -1,4 +1,5 @@
import type { NextApiRequest, NextApiResponse } from "next"; import type { NextApiRequest, NextApiResponse } from "next";
import { stringify } from "querystring";
import { WEBAPP_URL } from "@calcom/lib/constants"; import { WEBAPP_URL } from "@calcom/lib/constants";
@@ -13,7 +14,18 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
if (!client_id) return res.status(400).json({ message: "zohocrm client id missing." }); if (!client_id) return res.status(400).json({ message: "zohocrm client id missing." });
const state = encodeOAuthState(req); const state = encodeOAuthState(req);
const redirectUri = WEBAPP_URL + "/api/integrations/zohocrm/callback"; const params = {
const url = `https://accounts.zoho.com/oauth/v2/auth?scope=ZohoCRM.modules.ALL,ZohoCRM.users.READ,AaaServer.profile.READ&client_id=${client_id}&response_type=code&access_type=offline&redirect_uri=${redirectUri}&state=${state}`; client_id,
response_type: "code",
redirect_uri: WEBAPP_URL + "/api/integrations/zohocrm/callback",
scope: ["ZohoCRM.modules.ALL", "ZohoCRM.users.READ", "AaaServer.profile.READ"],
access_type: "offline",
state,
prompt: "consent",
};
const query = stringify(params);
const url = `https://accounts.zoho.com/oauth/v2/auth?${query}`;
res.status(200).json({ url }); res.status(200).json({ url });
} }
+1 -1
View File
@@ -3,7 +3,7 @@
"name": "ZohoCRM", "name": "ZohoCRM",
"slug": "zohocrm", "slug": "zohocrm",
"type": "zohocrm_other_calendar", "type": "zohocrm_other_calendar",
"logo": "icon.png", "logo": "icon.svg",
"url": "https://github.com/jatinsandilya", "url": "https://github.com/jatinsandilya",
"variant": "other", "variant": "other",
"categories": ["crm"], "categories": ["crm"],
@@ -0,0 +1,2 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg width="290.01" height="100" version="1.1" viewBox="0 0 290.01 100" xml:space="preserve" xmlns="http://www.w3.org/2000/svg"><defs><linearGradient id="linearGradient30" x2="1" gradientTransform="matrix(-7e-6 -164.3 -164.3 7e-6 636.24 170.92)" gradientUnits="userSpaceOnUse"><stop stop-color="#ffe500" offset="0"/><stop stop-color="#fcb822" offset="1"/></linearGradient><linearGradient id="linearGradient56" x2="1" gradientTransform="matrix(161.08 -129.36 -129.36 -161.08 380.05 153.54)" gradientUnits="userSpaceOnUse"><stop stop-color="#168ccc" offset="0"/><stop stop-color="#00649e" offset="1"/></linearGradient><clipPath id="clipPath70"><path d="m248.83 206.33 139.83-63.093-63.094-143.23-139.83 63.089 63.094 143.24"/></clipPath><linearGradient id="linearGradient84" x2="1" gradientTransform="matrix(-6e-6 -143.94 -143.94 6e-6 287.19 149.02)" gradientUnits="userSpaceOnUse"><stop stop-color="#25a149" offset="0"/><stop stop-color="#008a52" offset="1"/></linearGradient><linearGradient id="linearGradient110" x2="1" gradientTransform="matrix(24.754 -149.44 -149.44 -24.754 78.386 163.11)" gradientUnits="userSpaceOnUse"><stop stop-color="#d92231" offset="0"/><stop stop-color="#ba2234" offset="1"/></linearGradient></defs><g transform="matrix(1.3333 0 0 -1.3333 0 100.08)"><g transform="matrix(.29378 0 0 .29378 0 .042373)"><g transform="translate(740.38 200.84)"><path d="m0 0v-175.61l-24.248-23.659v171.73l24.248 27.54" fill="#e79224"/></g><path d="m716.52 173.3h-160.57v-171.94h160.57z" fill="url(#linearGradient30)"/><g transform="translate(581.1 200.72)"><path d="m0 0-25.151-27.424h160.57l23.857 27.54-159.28-0.116" fill="#fef26f"/></g><g transform="translate(382.23 193.19)"><path d="M 0,0 157.946,21.956 144.731,-15.916 -4.901,-39.646 -4.264,-12.575 0,0" fill="#91c9ed"/></g><path d="m526.96 177.28 21.881-154.04-155.74-21.883-21.03 148.92 9.094 7.106 145.8 19.893" fill="url(#linearGradient56)"/><g transform="translate(540.18 215.15)"><path d="m0 0 0.122-0.93 20.484-157.73-11.94-33.25-21.881 154.04" fill="#0b9ad6"/></g><g clip-path="url(#clipPath70)"><path d="m0 255.36h740.38v-255.3h-740.38z" fill="url(#linearGradient84)"/></g><g transform="translate(234.31 255.36)"><path d="M 0,0 14.515,-49.028 154.343,-112.121 142.588,-65.273 0,0" fill="#98d0a0"/></g><g transform="translate(234.31 255.36)"><path d="m 0,0 -56.279,-133.569 7.7,-58.697 L 14.515,-49.028 0,0" fill="#68bf6b"/></g><path d="m156.3 177.5 23.047-151.58-154.53-24.23-24.82 151.87 156.3 23.932" fill="url(#linearGradient110)"/><g transform="translate(0 153.57)"><path d="M 0,0 10.852,54.119 166.879,79.129 156.304,23.932 0,0" fill="#ef463d"/></g><g transform="translate(166.88 232.7)"><path d="M 0,0 22.877,-153.042 12.472,-206.773 -10.575,-55.197 0,0" fill="#761116"/></g><g transform="translate(500.47 147.76)"><path d="m0 0c-0.703 4.784-2.337 8.434-4.985 10.825-2.105 1.91-4.753 2.875-7.771 2.87-0.77 0-1.563-0.062-2.386-0.182-4.043-0.581-7.14-2.454-9.038-5.546-1.38-2.234-2.05-4.929-2.05-8.029 0-1.187 0.099-2.438 0.293-3.75l5.681-40.081-44.78-6.59-5.681 40.089c-0.687 4.66-2.298 8.273-4.91 10.729-2.109 1.991-4.739 3.009-7.705 3.002-0.7 0-1.419-0.056-2.153-0.164-4.215-0.607-7.425-2.445-9.374-5.491-1.414-2.194-2.096-4.902-2.096-8.051 0-1.209 0.103-2.487 0.298-3.835l15.322-104.24c0.703-4.793 2.38-8.435 5.135-10.789 2.149-1.839 4.843-2.764 7.929-2.758 0.843 0 1.72 0.066 2.625 0.2 3.855 0.558 6.833 2.423 8.629 5.511 1.287 2.195 1.913 4.832 1.913 7.85 0 1.208-0.099 2.474-0.295 3.8l-6.261 41.184 44.778 6.581 6.265-41.183c0.689-4.73 2.349-8.351 5.066-10.736 2.158-1.898 4.826-2.853 7.85-2.848 0.777 0 1.573 0.059 2.395 0.18 4.028 0.586 7.113 2.431 8.955 5.498 1.327 2.188 1.967 4.841 1.967 7.899 0 1.21-0.097 2.483-0.293 3.82zm-182.12-57.657c-5.269-12.41-12.224-20.924-20.83-25.641-4.612-2.527-9.338-3.777-14.227-3.779-4.248 0-8.627 0.949-13.149 2.863-9.786 4.172-15.882 10.877-18.521 20.334-0.882 3.173-1.326 6.508-1.326 10.013 0 6.941 1.742 14.556 5.256 22.841 5.388 12.704 12.421 21.371 21.034 26.117 4.599 2.535 9.329 3.794 14.234 3.794 4.295 0 8.733-0.961 13.33-2.912 9.724-4.137 15.759-10.857 18.35-20.357 0.842-3.106 1.266-6.375 1.266-9.817 0-7.088-1.791-14.909-5.417-23.456zm15.318 62.394c-5.494 5.794-12.167 10.351-19.993 13.67-7.768 3.3-15.622 4.946-23.537 4.946l-0.365-2e-3c-8.037-0.052-15.98-1.841-23.809-5.353v3e-3c-8.195-3.567-15.337-8.558-21.396-14.968-6.06-6.406-10.995-14.112-14.805-23.088-3.758-8.872-5.844-17.747-6.231-26.624-0.045-1.004-0.066-2.009-0.066-3.01 0-7.834 1.343-15.509 4.027-23.008 2.848-7.916 7.047-14.769 12.584-20.545 5.535-5.776 12.344-10.373 20.401-13.782v2e-3c7.706-3.274 15.531-4.912 23.457-4.908h0.203c7.994 0.037 15.922 1.75 23.76 5.117l7e-3 3e-3 5e-3 3e-3c8.245 3.679 15.436 8.737 21.568 15.139 6.129 6.408 11.084 14.092 14.872 23.017 3.787 8.924 5.85 17.809 6.189 26.647 0.032 0.852 0.048 1.702 0.048 2.55 0 7.947-1.404 15.734-4.214 23.352-2.974 8.094-7.214 15.047-12.705 20.839zm-193.97-102.44c-1.218 1.455-2.858 2.53-4.856 3.229-2.055 0.717-4.538 1.062-7.463 1.062-2.Line truncated

After

Width:  |  Height:  |  Size: 7.2 KiB

+9 -1
View File
@@ -10,6 +10,7 @@ import { appKeysSchema as calVideoKeysSchema } from "@calcom/app-store/dailyvide
import { getEventLocationTypeFromApp } from "@calcom/app-store/locations"; import { getEventLocationTypeFromApp } from "@calcom/app-store/locations";
import { MeetLocationType } from "@calcom/app-store/locations"; import { MeetLocationType } from "@calcom/app-store/locations";
import getApps from "@calcom/app-store/utils"; import getApps from "@calcom/app-store/utils";
import logger from "@calcom/lib/logger";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
import { createdEventSchema } from "@calcom/prisma/zod-utils"; import { createdEventSchema } from "@calcom/prisma/zod-utils";
import type { NewCalendarEventType } from "@calcom/types/Calendar"; import type { NewCalendarEventType } from "@calcom/types/Calendar";
@@ -436,7 +437,14 @@ export default class EventManager {
* This might happen if someone tries to use a location with a missing credential, so we fallback to Cal Video. * This might happen if someone tries to use a location with a missing credential, so we fallback to Cal Video.
* @todo remove location from event types that has missing credentials * @todo remove location from event types that has missing credentials
* */ * */
if (!videoCredential) videoCredential = { ...FAKE_DAILY_CREDENTIAL, appName: "FAKE" }; if (!videoCredential) {
logger.warn(
'Falling back to "daily" video integration for event with location: ' +
event.location +
" because credential is missing for the app"
);
videoCredential = { ...FAKE_DAILY_CREDENTIAL, appName: "FAKE" };
}
return videoCredential; return videoCredential;
} }
@@ -33,7 +33,7 @@ export const SlugReplacementEmail = (
</Trans> </Trans>
<Trans i18nKey="email_body_slug_replacement_info"> <Trans i18nKey="email_body_slug_replacement_info">
<p style={{ fontWeight: 400, lineHeight: "24px" }}> <p style={{ fontWeight: 400, lineHeight: "24px" }}>
Your link will continue to work but somesettings for it may have changed. You can review it in Your link will continue to work but some settings for it may have changed. You can review it in
event types. event types.
</p> </p>
</Trans> </Trans>
@@ -27,9 +27,8 @@ export const TeamInviteEmail = (
})}> })}>
<p style={{ fontSize: "24px", marginBottom: "16px", textAlign: "center" }}> <p style={{ fontSize: "24px", marginBottom: "16px", textAlign: "center" }}>
<> <>
{props.language("email_no_user_invite_heading", { {props.language(`email_no_user_invite_heading_${props.isOrg ? "org" : "team"}`, {
appName: APP_NAME, appName: APP_NAME,
entity: props.language(props.isOrg ? "organization" : "team").toLowerCase(),
})} })}
</> </>
</p> </p>
@@ -57,11 +56,10 @@ export const TeamInviteEmail = (
lineHeightStep: "24px", lineHeightStep: "24px",
}}> }}>
<> <>
{props.language("email_user_invite_subheading", { {props.language(`email_user_invite_subheading_${props.isOrg ? "org" : "team"}`, {
invitedBy: props.from, invitedBy: props.from,
appName: APP_NAME, appName: APP_NAME,
teamName: props.teamName, teamName: props.teamName,
entity: props.language(props.isOrg ? "organization" : "team").toLowerCase(),
})} })}
</> </>
</p> </p>
+11
View File
@@ -6,6 +6,7 @@ import dayjs from "@calcom/dayjs";
import { getFeatureFlagMap } from "@calcom/features/flags/server/utils"; import { getFeatureFlagMap } from "@calcom/features/flags/server/utils";
import { getErrorFromUnknown } from "@calcom/lib/errors"; import { getErrorFromUnknown } from "@calcom/lib/errors";
import { serverConfig } from "@calcom/lib/serverConfig"; import { serverConfig } from "@calcom/lib/serverConfig";
import { setTestEmail } from "@calcom/lib/testEmails";
import prisma from "@calcom/prisma"; import prisma from "@calcom/prisma";
export default class BaseEmail { export default class BaseEmail {
@@ -34,6 +35,16 @@ export default class BaseEmail {
return new Promise((r) => r("Skipped Sending Email due to active Kill Switch")); return new Promise((r) => r("Skipped Sending Email due to active Kill Switch"));
} }
if (process.env.INTEGRATION_TEST_MODE === "true") {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-expect-error
setTestEmail(this.getNodeMailerPayload());
console.log(
"Skipped Sending Email as process.env.NEXT_PUBLIC_UNIT_TESTS is set. Emails are available in globalThis.testEmails"
);
return new Promise((r) => r("Skipped sendEmail for Unit Tests"));
}
const payload = this.getNodeMailerPayload(); const payload = this.getNodeMailerPayload();
const parseSubject = z.string().safeParse(payload?.subject); const parseSubject = z.string().safeParse(payload?.subject);
const payloadWithUnEscapedSubject = { const payloadWithUnEscapedSubject = {
@@ -21,11 +21,7 @@ function RenderIcon({
return ( return (
<img <img
src={eventLocationType.iconUrl} src={eventLocationType.iconUrl}
className={classNames( className="me-[10px] h-4 w-4 opacity-70 invert-[.65] dark:invert-0"
"me-[10px] h-4 w-4 opacity-70 dark:opacity-100",
eventLocationType.iconUrl?.includes("-dark") ? "dark:invert-[.65]" : "",
eventLocationType.iconUrl?.includes("-dark") && isTooltip && "invert"
)}
alt={`${eventLocationType.label} icon`} alt={`${eventLocationType.label} icon`}
/> />
); );
@@ -338,7 +338,67 @@ export async function handleConfirmation(args: {
); );
}) })
); );
await Promise.all(promises); await Promise.all(promises);
if (paid) {
let paymentExternalId: string | undefined;
const subscriberMeetingPaid = await getWebhooks({
userId: triggerForUser ? booking.userId : null,
eventTypeId: booking.eventTypeId,
triggerEvent: WebhookTriggerEvents.BOOKING_PAID,
teamId: booking.eventType?.teamId,
});
const bookingWithPayment = await prisma.booking.findFirst({
where: {
id: bookingId,
},
select: {
payment: {
select: {
id: true,
success: true,
externalId: true,
},
},
},
});
const successPayment = bookingWithPayment?.payment?.find((item) => item.success);
if (successPayment) {
paymentExternalId = successPayment.externalId;
}
const paymentMetadata = {
identifier: "cal.com",
bookingId,
eventTypeId: booking.eventType?.id,
bookerEmail: evt.attendees[0].email,
eventTitle: booking.eventType?.title,
externalId: paymentExternalId,
};
const bookingPaidSubscribers = subscriberMeetingPaid.map((sub) =>
sendPayload(sub.secret, WebhookTriggerEvents.BOOKING_PAID, new Date().toISOString(), sub, {
...evt,
...eventTypeInfo,
bookingId,
eventTypeId: booking.eventType?.id,
status: "ACCEPTED",
smsReminderNumber: booking.smsReminderNumber || undefined,
paymentId: bookingWithPayment?.payment?.[0].id,
metadata: {
...(paid ? paymentMetadata : {}),
},
}).catch((e) => {
console.error(
`Error executing webhook for event: ${WebhookTriggerEvents.BOOKING_PAID}, URL: ${sub.subscriberUrl}`,
e
);
})
);
// I don't need to await for this
Promise.all(bookingPaidSubscribers);
}
} catch (error) { } catch (error) {
// Silently fail // Silently fail
console.error(error); console.error(error);
@@ -0,0 +1,511 @@
/**
* How to ensure that unmocked prisma queries aren't called?
*/
import type { Request, Response } from "express";
import type { NextApiRequest, NextApiResponse } from "next";
import { createMocks } from "node-mocks-http";
import { describe, expect, beforeEach } from "vitest";
import { WEBAPP_URL } from "@calcom/lib/constants";
import { BookingStatus } from "@calcom/prisma/enums";
import { test } from "@calcom/web/test/fixtures/fixtures";
import {
createBookingScenario,
getDate,
expectWorkflowToBeTriggered,
getGoogleCalendarCredential,
TestData,
getOrganizer,
getBooker,
getScenarioData,
expectBookingToBeInDatabase,
getZoomAppCredential,
mockEnableEmailFeature,
mockNoTranslations,
mockErrorOnVideoMeetingCreation,
mockSuccessfulVideoMeetingCreation,
mockCalendarToHaveNoBusySlots,
expectWebhookToHaveBeenCalledWith,
MockError,
} from "@calcom/web/test/utils/bookingScenario";
type CustomNextApiRequest = NextApiRequest & Request;
type CustomNextApiResponse = NextApiResponse & Response;
// Local test runs sometime gets too slow
const timeout = process.env.CI ? 5000 : 20000;
describe.sequential("handleNewBooking", () => {
beforeEach(() => {
// Required to able to generate token in email in some cases
process.env.CALENDSO_ENCRYPTION_KEY="abcdefghjnmkljhjklmnhjklkmnbhjui"
mockNoTranslations();
mockEnableEmailFeature();
globalThis.testEmails = [];
fetchMock.resetMocks();
});
describe.sequential("Frontend:", () => {
test(
`should create a successful booking with Cal Video(Daily Video) if no explicit location is provided
1. Should create a booking in the database
2. Should send emails to the booker as well as organizer
3. Should trigger BOOKING_CREATED webhook
`,
async ({ emails }) => {
const handleNewBooking = (await import("@calcom/features/bookings/lib/handleNewBooking")).default;
const booker = getBooker({
email: "booker@example.com",
name: "Booker",
});
const organizer = getOrganizer({
name: "Organizer",
email: "organizer@example.com",
id: 101,
schedules: [TestData.schedules.IstWorkHours],
credentials: [getGoogleCalendarCredential()],
selectedCalendars: [TestData.selectedCalendars.google],
});
const mockBookingData = getMockRequestDataForBooking({
data: {
eventTypeId: 1,
responses: {
email: booker.email,
name: booker.name,
location: { optionValue: "", value: "integrations:daily" },
},
},
});
const { req } = createMockNextJsRequest({
method: "POST",
body: mockBookingData,
});
const scenarioData = getScenarioData({
webhooks: [
{
userId: organizer.id,
eventTriggers: ["BOOKING_CREATED"],
subscriberUrl: "http://my-webhook.example.com",
active: true,
eventTypeId: 1,
appId: null,
},
],
eventTypes: [
{
id: 1,
slotInterval: 45,
length: 45,
users: [
{
id: 101,
},
],
},
],
organizer,
apps: [TestData.apps["google-calendar"], TestData.apps["daily-video"]],
});
mockSuccessfulVideoMeetingCreation({
metadataLookupKey: "dailyvideo",
});
mockCalendarToHaveNoBusySlots("googlecalendar");
createBookingScenario(scenarioData);
const createdBooking = await handleNewBooking(req);
expect(createdBooking.responses).toContain({
email: booker.email,
name: booker.name,
});
expect(createdBooking).toContain({
location: "integrations:daily",
});
expectBookingToBeInDatabase({
description: "",
eventType: {
connect: {
id: mockBookingData.eventTypeId,
},
},
status: BookingStatus.ACCEPTED,
});
expectWorkflowToBeTriggered();
const testEmails = emails.get();
expect(testEmails[0]).toHaveEmail({
htmlToContain: "<title>confirmed_event_type_subject</title>",
to: `${organizer.email}`,
});
expect(testEmails[1]).toHaveEmail({
htmlToContain: "<title>confirmed_event_type_subject</title>",
to: `${booker.name} <${booker.email}>`,
});
expect(testEmails[1].html).toContain("<title>confirmed_event_type_subject</title>");
expectWebhookToHaveBeenCalledWith("http://my-webhook.example.com", {
triggerEvent: "BOOKING_CREATED",
payload: {
metadata: {
videoCallUrl: `${WEBAPP_URL}/video/DYNAMIC_UID`,
},
responses: {
name: { label: "your_name", value: "Booker" },
email: { label: "email_address", value: "booker@example.com" },
location: {
label: "location",
value: { optionValue: "", value: "integrations:daily" },
},
title: { label: "what_is_this_meeting_about" },
notes: { label: "additional_notes" },
guests: { label: "additional_guests" },
rescheduleReason: { label: "reason_for_reschedule" },
},
},
});
},
timeout
);
test(
`should submit a booking request for event requiring confirmation
1. Should create a booking in the database with status PENDING
2. Should send emails to the booker as well as organizer for booking request and awaiting approval
3. Should trigger BOOKING_REQUESTED webhook
`,
async ({ emails }) => {
const handleNewBooking = (await import("@calcom/features/bookings/lib/handleNewBooking")).default;
const booker = getBooker({
email: "booker@example.com",
name: "Booker",
});
const organizer = getOrganizer({
name: "Organizer",
email: "organizer@example.com",
id: 101,
schedules: [TestData.schedules.IstWorkHours],
credentials: [getGoogleCalendarCredential()],
selectedCalendars: [TestData.selectedCalendars.google],
});
const mockBookingData = getMockRequestDataForBooking({
data: {
eventTypeId: 1,
responses: {
email: booker.email,
name: booker.name,
location: { optionValue: "", value: "integrations:daily" },
},
},
});
const { req } = createMockNextJsRequest({
method: "POST",
body: mockBookingData,
});
const scenarioData = getScenarioData({
webhooks: [
{
userId: organizer.id,
eventTriggers: ["BOOKING_CREATED"],
subscriberUrl: "http://my-webhook.example.com",
active: true,
eventTypeId: 1,
appId: null,
},
],
eventTypes: [
{
id: 1,
slotInterval: 45,
requiresConfirmation: true,
length: 45,
users: [
{
id: 101,
},
],
},
],
organizer,
apps: [TestData.apps["google-calendar"], TestData.apps["daily-video"]],
});
mockSuccessfulVideoMeetingCreation({
metadataLookupKey: "dailyvideo",
});
mockCalendarToHaveNoBusySlots("googlecalendar");
createBookingScenario(scenarioData);
const createdBooking = await handleNewBooking(req);
expect(createdBooking.responses).toContain({
email: booker.email,
name: booker.name,
});
expect(createdBooking).toContain({
location: "integrations:daily",
});
expectBookingToBeInDatabase({
description: "",
eventType: {
connect: {
id: mockBookingData.eventTypeId,
},
},
status: BookingStatus.PENDING,
});
expectWorkflowToBeTriggered();
const testEmails = emails.get();
expect(testEmails[0]).toHaveEmail({
htmlToContain: "<title>event_awaiting_approval_subject</title>",
to: `${organizer.email}`,
});
expect(testEmails[1]).toHaveEmail({
htmlToContain: "<title>booking_submitted_subject</title>",
to: `${booker.email}`,
});
expectWebhookToHaveBeenCalledWith("http://my-webhook.example.com", {
triggerEvent: "BOOKING_REQUESTED",
payload: {
metadata: {
// In a Pending Booking Request, we don't send the video call url
videoCallUrl: undefined,
},
responses: {
name: { label: "your_name", value: "Booker" },
email: { label: "email_address", value: "booker@example.com" },
location: {
label: "location",
value: { optionValue: "", value: "integrations:daily" },
},
title: { label: "what_is_this_meeting_about" },
notes: { label: "additional_notes" },
guests: { label: "additional_guests" },
rescheduleReason: { label: "reason_for_reschedule" },
},
},
});
},
timeout
);
test(
`if booking with Cal Video(Daily Video) fails, booking creation fails with uncaught error`,
async ({}) => {
const handleNewBooking = (await import("@calcom/features/bookings/lib/handleNewBooking")).default;
const booker = getBooker({
email: "booker@example.org",
name: "Booker",
});
const organizer = TestData.users.example;
const { req } = createMockNextJsRequest({
method: "POST",
body: getMockRequestDataForBooking({
data: {
eventTypeId: 1,
responses: {
email: booker.email,
name: booker.name,
location: { optionValue: "", value: "integrations:daily" },
},
},
}),
});
const scenarioData = {
hosts: [],
eventTypes: [
{
id: 1,
slotInterval: 45,
length: 45,
users: [
{
id: 101,
},
],
},
],
users: [
{
...organizer,
id: 101,
schedules: [TestData.schedules.IstWorkHours],
credentials: [getGoogleCalendarCredential()],
selectedCalendars: [TestData.selectedCalendars.google],
},
],
apps: [TestData.apps["google-calendar"], TestData.apps["daily-video"]],
};
mockErrorOnVideoMeetingCreation({
metadataLookupKey: "dailyvideo",
});
mockCalendarToHaveNoBusySlots("googlecalendar");
createBookingScenario(scenarioData);
try {
await handleNewBooking(req);
} catch (e) {
expect(e).toBeInstanceOf(MockError);
expect((e as { message: string }).message).toBe("Error creating Video meeting");
}
},
timeout
);
test(
`should create a successful booking with Zoom if used`,
async ({ emails }) => {
const handleNewBooking = (await import("@calcom/features/bookings/lib/handleNewBooking")).default;
const booker = getBooker({
email: "booker@example.com",
name: "Booker",
});
const organizer = getOrganizer({
name: "Organizer",
email: "organizer@example.com",
id: 101,
schedules: [TestData.schedules.IstWorkHours],
credentials: [getZoomAppCredential()],
selectedCalendars: [TestData.selectedCalendars.google],
});
const { req } = createMockNextJsRequest({
method: "POST",
body: getMockRequestDataForBooking({
data: {
eventTypeId: 1,
responses: {
email: booker.email,
name: booker.name,
location: { optionValue: "", value: "integrations:zoom" },
},
},
}),
});
const bookingScenario = getScenarioData({
organizer,
eventTypes: [
{
id: 1,
slotInterval: 45,
length: 45,
users: [
{
id: 101,
},
],
},
],
apps: [TestData.apps["daily-video"]],
webhooks: [
{
userId: organizer.id,
eventTriggers: ["BOOKING_CREATED"],
subscriberUrl: "http://my-webhook.example.com",
active: true,
eventTypeId: 1,
appId: null,
},
],
});
createBookingScenario(bookingScenario);
mockSuccessfulVideoMeetingCreation({
metadataLookupKey: "zoomvideo",
});
await handleNewBooking(req);
const testEmails = emails.get();
expect(testEmails[0]).toHaveEmail({
htmlToContain: "<title>confirmed_event_type_subject</title>",
to: `${organizer.email}`,
});
expect(testEmails[1]).toHaveEmail({
htmlToContain: "<title>confirmed_event_type_subject</title>",
to: `${booker.name} <${booker.email}>`,
});
expectWebhookToHaveBeenCalledWith("http://my-webhook.example.com", {
triggerEvent: "BOOKING_CREATED",
payload: {
metadata: {
videoCallUrl: "http://mock-zoomvideo.example.com",
},
responses: {
name: { label: "your_name", value: "Booker" },
email: { label: "email_address", value: "booker@example.com" },
location: {
label: "location",
value: { optionValue: "", value: "integrations:zoom" },
},
title: { label: "what_is_this_meeting_about" },
notes: { label: "additional_notes" },
guests: { label: "additional_guests" },
rescheduleReason: { label: "reason_for_reschedule" },
},
},
});
},
timeout
);
});
});
function createMockNextJsRequest(...args: Parameters<typeof createMocks>) {
return createMocks<CustomNextApiRequest, CustomNextApiResponse>(...args);
}
function getBasicMockRequestDataForBooking() {
return {
start: `${getDate({ dateIncrement: 1 }).dateString}T04:00:00.000Z`,
end: `${getDate({ dateIncrement: 1 }).dateString}T04:30:00.000Z`,
eventTypeSlug: "no-confirmation",
timeZone: "Asia/Calcutta",
language: "en",
bookingUid: "bvCmP5rSquAazGSA7hz7ZP",
user: "teampro",
metadata: {},
hasHashedBookingLink: false,
hashedLink: null,
};
}
function getMockRequestDataForBooking({
data,
}: {
data: Partial<ReturnType<typeof getBasicMockRequestDataForBooking>> & {
eventTypeId: number;
responses: {
email: string;
name: string;
location: { optionValue: ""; value: string };
};
};
}) {
return {
...getBasicMockRequestDataForBooking(),
...data,
};
}
@@ -1756,6 +1756,7 @@ async function handler(
const webhookData = { const webhookData = {
...evt, ...evt,
...eventTypeInfo, ...eventTypeInfo,
uid: resultBooking?.uid || uid,
bookingId: booking?.id, bookingId: booking?.id,
rescheduleUid, rescheduleUid,
rescheduleStartTime: originalRescheduledBooking?.startTime rescheduleStartTime: originalRescheduledBooking?.startTime
+29 -39
View File
@@ -1,3 +1,4 @@
import { useEffect } from "react";
import { shallow } from "zustand/shallow"; import { shallow } from "zustand/shallow";
import type { Dayjs } from "@calcom/dayjs"; import type { Dayjs } from "@calcom/dayjs";
@@ -100,40 +101,6 @@ const NoAvailabilityOverlay = ({
); );
}; };
/**
* Takes care of selecting a valid date in the month if the selected date is not available in the month
*/
const useHandleInitialDateSelection = ({
daysToRenderForTheMonth,
selected,
onChange,
}: {
daysToRenderForTheMonth: { day: Dayjs | null; disabled: boolean }[];
selected: Dayjs | Dayjs[] | null | undefined;
onChange: (date: Dayjs | null) => void;
}) => {
// Let's not do something for now in case of multiple selected dates as behaviour is unclear and it's not needed at the moment
if (selected instanceof Array) {
return;
}
const firstAvailableDateOfTheMonth = daysToRenderForTheMonth.find((day) => !day.disabled)?.day;
const isSelectedDateAvailable = selected
? daysToRenderForTheMonth.some(({ day, disabled }) => {
if (day && yyyymmdd(day) === yyyymmdd(selected) && !disabled) return true;
})
: false;
if (!isSelectedDateAvailable && firstAvailableDateOfTheMonth) {
// If selected date not available in the month, select the first available date of the month
onChange(firstAvailableDateOfTheMonth);
}
if (!firstAvailableDateOfTheMonth) {
onChange(null);
}
};
const Days = ({ const Days = ({
minDate = dayjs.utc(), minDate = dayjs.utc(),
excludedDates = [], excludedDates = [],
@@ -218,11 +185,34 @@ const Days = ({
}; };
}); });
useHandleInitialDateSelection({ /**
daysToRenderForTheMonth, * Takes care of selecting a valid date in the month if the selected date is not available in the month
selected, */
onChange: props.onChange,
}); const useHandleInitialDateSelection = () => {
// Let's not do something for now in case of multiple selected dates as behaviour is unclear and it's not needed at the moment
if (selected instanceof Array) {
return;
}
const firstAvailableDateOfTheMonth = daysToRenderForTheMonth.find((day) => !day.disabled)?.day;
const isSelectedDateAvailable = selected
? daysToRenderForTheMonth.some(({ day, disabled }) => {
if (day && yyyymmdd(day) === yyyymmdd(selected) && !disabled) return true;
})
: false;
if (!isSelectedDateAvailable && firstAvailableDateOfTheMonth) {
// If selected date not available in the month, select the first available date of the month
props.onChange(firstAvailableDateOfTheMonth);
}
if (!firstAvailableDateOfTheMonth) {
props.onChange(null);
}
};
useEffect(useHandleInitialDateSelection);
return ( return (
<> <>
@@ -0,0 +1,31 @@
import classNames from "@calcom/lib/classNames";
import { Avatar } from "@calcom/ui";
import type { AvatarProps } from "@calcom/ui";
type OrganizationAvatarProps = AvatarProps & {
organizationSlug: string | null | undefined;
};
const OrganizationAvatar = ({ size, imageSrc, alt, organizationSlug, ...rest }: OrganizationAvatarProps) => {
return (
<Avatar
size={size}
imageSrc={imageSrc}
alt={alt}
indicator={
organizationSlug ? (
<div
className={classNames("absolute bottom-0 right-0 z-10", size === "lg" ? "h-3 w-3" : "h-10 w-10")}>
<img
src={`/org/${organizationSlug}/avatar.png`}
alt={alt}
className="flex h-full items-center justify-center rounded-full ring-2 ring-white"
/>
</div>
) : null
}
/>
);
};
export default OrganizationAvatar;
@@ -61,7 +61,9 @@ export default function WorkflowDetailsPage(props: Props) {
...options, ...options,
...group.eventTypes.map((eventType) => ({ ...group.eventTypes.map((eventType) => ({
value: String(eventType.id), value: String(eventType.id),
label: `${eventType.title} ${eventType.children.length ? `(+${eventType.children.length})` : ``}`, label: `${eventType.title} ${
eventType.children && eventType.children.length ? `(+${eventType.children.length})` : ``
}`,
})), })),
]; ];
}, [] as Option[]) || [], }, [] as Option[]) || [],
@@ -103,7 +103,7 @@ export function AvailabilitySliderTable() {
.padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`; .padStart(2, "0")}:${minutes.toString().padStart(2, "0")}`;
return ( return (
<div className="flex flex-col"> <div className="flex flex-col text-center">
<span className="text-default text-sm font-medium">{time}</span> <span className="text-default text-sm font-medium">{time}</span>
<span className="text-subtle text-xs leading-none">GMT {offsetFormatted}</span> <span className="text-subtle text-xs leading-none">GMT {offsetFormatted}</span>
</div> </div>
@@ -5,7 +5,7 @@ import { useOrgBranding } from "@calcom/ee/organizations/context/provider";
import { WEBAPP_URL } from "@calcom/lib/constants"; import { WEBAPP_URL } from "@calcom/lib/constants";
import { useLocale } from "@calcom/lib/hooks/useLocale"; import { useLocale } from "@calcom/lib/hooks/useLocale";
import { trpc } from "@calcom/trpc/react"; import { trpc } from "@calcom/trpc/react";
import { Sheet, SheetContent, SheetFooter, Avatar, Skeleton, Loader } from "@calcom/ui"; import { Sheet, SheetContent, SheetFooter, Avatar, Skeleton, Loader, Label } from "@calcom/ui";
import type { State, Action } from "../UserListTable"; import type { State, Action } from "../UserListTable";
import { DisplayInfo } from "./DisplayInfo"; import { DisplayInfo } from "./DisplayInfo";
@@ -69,14 +69,23 @@ export function EditUserSheet({ state, dispatch }: { state: State; dispatch: Dis
/> />
<DisplayInfo label={t("role")} value={loadedUser?.role ?? ""} asBadge badgeColor="blue" /> <DisplayInfo label={t("role")} value={loadedUser?.role ?? ""} asBadge badgeColor="blue" />
<DisplayInfo label={t("timezone")} value={loadedUser?.timeZone ?? ""} /> <DisplayInfo label={t("timezone")} value={loadedUser?.timeZone ?? ""} />
<DisplayInfo <div className="flex flex-col">
label={t("availability_schedules")} <Label className="text-subtle mb-1 text-xs font-semibold uppercase leading-none">
value={ {t("availability_schedules")}
schedulesNames && schedulesNames?.length === 0 </Label>
? [t("user_has_no_schedules")] <div className="flex flex-col">
: schedulesNames ?? "" // TS wtf {schedulesNames
} ? schedulesNames.map((scheduleName) => (
/> <span
key={scheduleName}
className="text-emphasis inline-flex items-center gap-1 text-sm font-normal leading-5">
{scheduleName}
</span>
))
: t("user_has_no_schedules")}
</div>
</div>
<DisplayInfo <DisplayInfo
label={t("teams")} label={t("teams")}
displayCount={teamNames?.length ?? 0} displayCount={teamNames?.length ?? 0}
@@ -18,7 +18,7 @@ export type EventTypeInfo = {
export type WebhookDataType = CalendarEvent & export type WebhookDataType = CalendarEvent &
EventTypeInfo & { EventTypeInfo & {
metadata?: { [key: string]: string }; metadata?: { [key: string]: string | number | boolean | null };
bookingId?: number; bookingId?: number;
status?: string; status?: string;
smsReminderNumber?: string; smsReminderNumber?: string;
@@ -28,6 +28,7 @@ export type WebhookDataType = CalendarEvent &
triggerEvent: string; triggerEvent: string;
createdAt: string; createdAt: string;
downloadLink?: string; downloadLink?: string;
paymentId?: number;
}; };
function getZapierPayload( function getZapierPayload(
+6 -8
View File
@@ -136,7 +136,6 @@ export async function getTeamWithMembers(args: {
// This should improve performance saving already app data found. // This should improve performance saving already app data found.
const appDataMap = new Map(); const appDataMap = new Map();
const members = team.members.map((obj) => { const members = team.members.map((obj) => {
return { return {
...obj.user, ...obj.user,
@@ -144,7 +143,7 @@ export async function getTeamWithMembers(args: {
accepted: obj.accepted, accepted: obj.accepted,
disableImpersonation: obj.disableImpersonation, disableImpersonation: obj.disableImpersonation,
avatar: `${WEBAPP_URL}/${obj.user.username}/avatar.png`, avatar: `${WEBAPP_URL}/${obj.user.username}/avatar.png`,
connectedApps: obj.user.credentials.map((cred) => { connectedApps: obj?.user?.credentials?.map((cred) => {
const appSlug = cred.app?.slug; const appSlug = cred.app?.slug;
let appData = appDataMap.get(appSlug); let appData = appDataMap.get(appSlug);
@@ -153,14 +152,13 @@ export async function getTeamWithMembers(args: {
appDataMap.set(appSlug, appData); appDataMap.set(appSlug, appData);
} }
const isCalendar = cred?.app?.categories.includes("calendar"); const isCalendar = cred?.app?.categories?.includes("calendar") ?? false;
const externalId = isCalendar ? cred.destinationCalendars[0]?.externalId : undefined; const externalId = isCalendar ? cred.destinationCalendars?.[0]?.externalId : null;
return { return {
name: appData?.name, name: appData?.name ?? null,
logo: appData?.logo, logo: appData?.logo ?? null,
app: cred.app, app: cred.app,
externalId, externalId: externalId ?? null,
}; };
}), }),
}; };
+18
View File
@@ -0,0 +1,18 @@
declare global {
// eslint-disable-next-line no-var
var testEmails: {
to: string;
from: string;
subject: string;
html: string;
}[];
}
export const setTestEmail = (email: (typeof globalThis.testEmails)[number]) => {
globalThis.testEmails = globalThis.testEmails || [];
globalThis.testEmails.push(email);
};
export const getTestEmails = () => {
return globalThis.testEmails;
};
+1
View File
@@ -56,6 +56,7 @@ model EventType {
position Int @default(0) position Int @default(0)
/// @zod.custom(imports.eventTypeLocations) /// @zod.custom(imports.eventTypeLocations)
locations Json? locations Json?
/// @zod.min(1)
length Int length Int
offsetStart Int @default(0) offsetStart Int @default(0)
hidden Boolean @default(false) hidden Boolean @default(false)
@@ -64,6 +64,7 @@ export async function getUserFromSession(ctx: TRPCContextInner, session: Maybe<S
id: true, id: true,
slug: true, slug: true,
metadata: true, metadata: true,
name: true,
members: { members: {
select: { userId: true }, select: { userId: true },
where: { where: {
@@ -14,7 +14,7 @@ import { updateWebUser as syncServicesUpdateWebUser } from "@calcom/lib/sync/Syn
import { validateBookerLayouts } from "@calcom/lib/validateBookerLayouts"; import { validateBookerLayouts } from "@calcom/lib/validateBookerLayouts";
import { prisma } from "@calcom/prisma"; import { prisma } from "@calcom/prisma";
import { IdentityProvider } from "@calcom/prisma/enums"; import { IdentityProvider } from "@calcom/prisma/enums";
import { userMetadata } from "@calcom/prisma/zod-utils"; import { userMetadata as userMetadataSchema } from "@calcom/prisma/zod-utils";
import type { TrpcSessionUser } from "@calcom/trpc/server/trpc"; import type { TrpcSessionUser } from "@calcom/trpc/server/trpc";
import { TRPCError } from "@trpc/server"; import { TRPCError } from "@trpc/server";
@@ -31,11 +31,10 @@ type UpdateProfileOptions = {
export const updateProfileHandler = async ({ ctx, input }: UpdateProfileOptions) => { export const updateProfileHandler = async ({ ctx, input }: UpdateProfileOptions) => {
const { user } = ctx; const { user } = ctx;
const { metadata: metadataFromInput } = input; const userMetadata = handleUserMetadata({ ctx, input });
const cleanMetadata = cleanMetadataAllowedUpdateKeys(metadataFromInput);
const data: Prisma.UserUpdateInput = { const data: Prisma.UserUpdateInput = {
...input, ...input,
metadata: cleanMetadata, metadata: userMetadata,
}; };
// some actions can invalidate a user session. // some actions can invalidate a user session.
@@ -65,26 +64,9 @@ export const updateProfileHandler = async ({ ctx, input }: UpdateProfileOptions)
data.avatar = await resizeBase64Image(input.avatar); data.avatar = await resizeBase64Image(input.avatar);
} }
const fetchUserCurrentMetadata = await prisma.user.findUnique({
where: {
id: user.id,
},
select: {
metadata: true,
},
});
const metadata = userMetadata.parse(fetchUserCurrentMetadata?.metadata);
// Required so we don't override and delete saved values
data.metadata = {
...metadata,
cleanMetadata,
};
const isPremium = metadata?.isPremium;
if (isPremiumUsername) { if (isPremiumUsername) {
const stripeCustomerId = metadata?.stripeCustomerId; const stripeCustomerId = userMetadata?.stripeCustomerId;
const isPremium = userMetadata?.isPremium;
if (!isPremium || !stripeCustomerId) { if (!isPremium || !stripeCustomerId) {
throw new TRPCError({ code: "BAD_REQUEST", message: "User is not premium" }); throw new TRPCError({ code: "BAD_REQUEST", message: "User is not premium" });
} }
@@ -199,12 +181,21 @@ export const updateProfileHandler = async ({ ctx, input }: UpdateProfileOptions)
const cleanMetadataAllowedUpdateKeys = (metadata: TUpdateProfileInputSchema["metadata"]) => { const cleanMetadataAllowedUpdateKeys = (metadata: TUpdateProfileInputSchema["metadata"]) => {
if (!metadata) { if (!metadata) {
return {} as Prisma.InputJsonValue; return {};
} }
const cleanedMetadata = updateUserMetadataAllowedKeys.safeParse(metadata); const cleanedMetadata = updateUserMetadataAllowedKeys.safeParse(metadata);
if (!cleanedMetadata.success) { if (!cleanedMetadata.success) {
logger.error("Error cleaning metadata", cleanedMetadata.error); logger.error("Error cleaning metadata", cleanedMetadata.error);
return {};
} }
return cleanedMetadata as Prisma.InputJsonValue; return cleanedMetadata.data;
};
const handleUserMetadata = ({ ctx, input }: UpdateProfileOptions) => {
const { user } = ctx;
const cleanMetadata = cleanMetadataAllowedUpdateKeys(input.metadata);
const userMetadata = userMetadataSchema.parse(user.metadata);
// Required so we don't override and delete saved values
return { ...userMetadata, ...cleanMetadata };
}; };
@@ -52,14 +52,6 @@ const userEventTypeSelect = Prisma.validator<Prisma.EventTypeSelect>()({
users: { users: {
select: userSelect, select: userSelect,
}, },
// Temporarily putting this back for testing
children: {
include: {
users: {
select: userSelect,
},
},
},
parentId: true, parentId: true,
hosts: { hosts: {
select: { select: {
@@ -74,13 +66,13 @@ const userEventTypeSelect = Prisma.validator<Prisma.EventTypeSelect>()({
const teamEventTypeSelect = Prisma.validator<Prisma.EventTypeSelect>()({ const teamEventTypeSelect = Prisma.validator<Prisma.EventTypeSelect>()({
...userEventTypeSelect, ...userEventTypeSelect,
// children: { children: {
// include: { include: {
// users: { users: {
// select: userSelect, select: userSelect,
// }, },
// }, },
// }, },
}); });
export const compareMembership = (mship1: MembershipRole, mship2: MembershipRole) => { export const compareMembership = (mship1: MembershipRole, mship2: MembershipRole) => {
@@ -167,11 +159,15 @@ export const getByViewerHandler = async ({ ctx, input }: GetByViewerOptions) =>
throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" }); throw new TRPCError({ code: "INTERNAL_SERVER_ERROR" });
} }
const mapEventType = (eventType: (typeof user.eventTypes)[number]) => ({ type UserEventTypes = (typeof user.eventTypes)[number];
type TeamEventTypeChildren = (typeof user.teams)[number]["team"]["eventTypes"][number];
const mapEventType = (eventType: UserEventTypes & Partial<TeamEventTypeChildren>) => ({
...eventType, ...eventType,
safeDescription: markdownToSafeHTML(eventType.description), safeDescription: eventType?.description ? markdownToSafeHTML(eventType.description) : undefined,
users: !!eventType.hosts?.length ? eventType.hosts.map((host) => host.user) : eventType.users, users: !!eventType?.hosts?.length ? eventType?.hosts.map((host) => host.user) : eventType.users,
metadata: eventType.metadata ? EventTypeMetaDataSchema.parse(eventType.metadata) : undefined, metadata: eventType.metadata ? EventTypeMetaDataSchema.parse(eventType.metadata) : undefined,
children: eventType.children,
}); });
const userEventTypes = user.eventTypes.map(mapEventType); const userEventTypes = user.eventTypes.map(mapEventType);
@@ -279,8 +275,7 @@ export const getByViewerHandler = async ({ ctx, input }: GetByViewerOptions) =>
const bookerUrl = await getBookerUrl(user); const bookerUrl = await getBookerUrl(user);
return { return {
// don't display event teams without event types, eventTypeGroups,
eventTypeGroups: eventTypeGroups.filter((groupBy) => groupBy.parentId || !!groupBy.eventTypes?.length),
// so we can show a dropdown when the user has teams // so we can show a dropdown when the user has teams
profiles: eventTypeGroups.map((group) => ({ profiles: eventTypeGroups.map((group) => ({
...group.profile, ...group.profile,
@@ -241,13 +241,13 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
} }
} }
if (input?.price || input.metadata?.apps?.stripe?.price) { if (input.metadata?.apps?.stripe?.price) {
data.price = input.price || input.metadata?.apps?.stripe?.price; data.price = input.metadata?.apps?.stripe?.price;
const paymentCredential = await ctx.prisma.credential.findFirst({ const paymentCredential = await ctx.prisma.credential.findFirst({
where: { where: {
userId: ctx.user.id, userId: ctx.user.id,
type: { type: {
contains: "_payment", equals: "stripe_payment",
}, },
}, },
select: { select: {
@@ -260,6 +260,22 @@ export const updateHandler = async ({ ctx, input }: UpdateOptions) => {
const { default_currency } = stripeDataSchema.parse(paymentCredential.key); const { default_currency } = stripeDataSchema.parse(paymentCredential.key);
data.currency = default_currency; data.currency = default_currency;
} }
}
if (input.metadata?.apps?.paypal?.price) {
data.price = input.metadata?.apps?.paypal?.price;
const paymentCredential = await ctx.prisma.credential.findFirst({
where: {
userId: ctx.user.id,
type: {
equals: "paypal_payment",
},
},
select: {
type: true,
key: true,
},
});
if (paymentCredential?.type === "paypal_payment" && input.metadata?.apps?.paypal?.currency) { if (paymentCredential?.type === "paypal_payment" && input.metadata?.apps?.paypal?.currency) {
data.currency = input.metadata?.apps?.paypal?.currency.toLowerCase(); data.currency = input.metadata?.apps?.paypal?.currency.toLowerCase();
} }
+5 -14
View File
@@ -7,7 +7,6 @@ import { AVATAR_FALLBACK } from "@calcom/lib/constants";
import type { Maybe } from "@trpc/server"; import type { Maybe } from "@trpc/server";
import { Check } from "../icon";
import { Tooltip } from "../tooltip"; import { Tooltip } from "../tooltip";
export type AvatarProps = { export type AvatarProps = {
@@ -20,6 +19,7 @@ export type AvatarProps = {
fallback?: React.ReactNode; fallback?: React.ReactNode;
accepted?: boolean; accepted?: boolean;
asChild?: boolean; // Added to ignore the outer span on the fallback component - messes up styling asChild?: boolean; // Added to ignore the outer span on the fallback component - messes up styling
indicator?: React.ReactNode;
}; };
const sizesPropsBySize = { const sizesPropsBySize = {
@@ -34,12 +34,13 @@ const sizesPropsBySize = {
} as const; } as const;
export function Avatar(props: AvatarProps) { export function Avatar(props: AvatarProps) {
const { imageSrc, size = "md", alt, title, href } = props; const { imageSrc, size = "md", alt, title, href, indicator } = props;
const rootClass = classNames("aspect-square rounded-full", sizesPropsBySize[size]); const rootClass = classNames("aspect-square rounded-full", sizesPropsBySize[size]);
let avatar = ( let avatar = (
<AvatarPrimitive.Root <AvatarPrimitive.Root
className={classNames( className={classNames(
"bg-emphasis item-center relative inline-flex aspect-square justify-center overflow-hidden rounded-full", "bg-emphasis item-center relative inline-flex aspect-square justify-center rounded-full",
indicator ? "overflow-visible" : "overflow-hidden",
props.className, props.className,
sizesPropsBySize[size] sizesPropsBySize[size]
)}> )}>
@@ -57,17 +58,7 @@ export function Avatar(props: AvatarProps) {
{props.fallback ? props.fallback : <img src={AVATAR_FALLBACK} alt={alt} className={rootClass} />} {props.fallback ? props.fallback : <img src={AVATAR_FALLBACK} alt={alt} className={rootClass} />}
</> </>
</AvatarPrimitive.Fallback> </AvatarPrimitive.Fallback>
{props.accepted && ( {indicator}
<div
className={classNames(
"text-inverted absolute bottom-0 right-0 block rounded-full bg-green-400 ring-2 ring-white",
size === "lg" ? "h-5 w-5" : "h-2 w-2"
)}>
<div className="flex h-full items-center justify-center p-[2px]">
{size === "lg" && <Check />}
</div>
</div>
)}
</> </>
</AvatarPrimitive.Root> </AvatarPrimitive.Root>
); );
@@ -11,7 +11,6 @@ export type AvatarGroupProps = {
href?: string; href?: string;
}[]; }[];
className?: string; className?: string;
accepted?: boolean;
truncateAfter?: number; truncateAfter?: number;
}; };
@@ -36,7 +35,6 @@ export const AvatarGroup = function AvatarGroup(props: AvatarGroupProps) {
imageSrc={item.image} imageSrc={item.image}
title={item.title} title={item.title}
alt={item.alt || ""} alt={item.alt || ""}
accepted={props.accepted}
size={props.size} size={props.size}
href={item.href} href={item.href}
/> />
+1 -1
View File
@@ -108,7 +108,7 @@ const CommandItem = React.forwardRef<
<CommandPrimitive.Item <CommandPrimitive.Item
ref={ref} ref={ref}
className={classNames( className={classNames(
"aria-selected:bg-subtle aria-selected:text-emphasis relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50", "aria-selected:bg-muted aria-selected:text-emphasis relative flex cursor-default select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
className className
)} )}
{...props} {...props}
@@ -14,20 +14,54 @@ import { DataTable } from "../";
import { columns, filterableItems } from "./columns"; import { columns, filterableItems } from "./columns";
import { dataTableDemousers, dataTableSelectionActions } from "./data"; import { dataTableDemousers, dataTableSelectionActions } from "./data";
<Meta title="UI/table/data-table" component={DataTable} /> <Meta title="UI/table/DataTable" component={DataTable} />
<Title title="Data-table" suffix="Brief" subtitle="Version 2.0 — Last Update: 06 Jan 2023" /> <Title title="DataTable" suffix="Brief" subtitle="Version 3.0 — Last Update: 28 Aug 2023" />
## Definition ## Definition
The `DataTable` component facilitates tabular data display with configurable columns, virtual scrolling, filtering, and interactive features for seamless dynamic table creation.
## Structure
The `DataTable` setup for tabular data, with columns, virtual scroll, sticky headers, and interactive features like filtering and row selection.
<CustomArgsTable of={DataTable} />
## Dialog Story
<Canvas> <Canvas>
<Story name="Datatable"> <Story
<DataTable name="DataTable"
columns={columns} args={{
data={dataTableDemousers} columns: columns,
filterableItems={filterableItems} data: dataTableDemousers,
searchKey="username" isLoading: false,
selectionOptions={dataTableSelectionActions} searchKey: "username",
/> filterableItems: filterableItems,
tableContainerRef: { current: null },
selectionOptions: dataTableSelectionActions,
}}
argTypes={{
tableContainerRef: { table: { disable: true } },
searchKey: {
control: {
type: "select",
options: ["username", "email"],
},
},
selectionOptions: { control: { type: "object" } },
onScroll: { table: { disable: true } },
tableOverlay: { table: { disable: true } },
CTA: { table: { disable: true } },
tableCTA: { table: { disable: true } },
}}>
{(args) => (
<VariantsTable titles={["Default"]} columnMinWidth={1000}>
<VariantRow>
<DataTable {...args} />
</VariantRow>
</VariantsTable>
)}
</Story> </Story>
</Canvas> </Canvas>
@@ -48,7 +48,13 @@ export function EmptyScreen({
</div> </div>
)} )}
<div className="flex max-w-[420px] flex-col items-center"> <div className="flex max-w-[420px] flex-col items-center">
<h2 className="text-semibold font-cal text-emphasis mt-6 text-center text-xl">{headline}</h2> <h2
className={classNames(
"text-semibold font-cal text-emphasis text-center text-xl",
Icon && "mt-6"
)}>
{headline}
</h2>
{description && ( {description && (
<div className="text-default mb-8 mt-3 text-center text-sm font-normal leading-6"> <div className="text-default mb-8 mt-3 text-center text-sm font-normal leading-6">
{description} {description}
@@ -0,0 +1,59 @@
import { Canvas, Meta, Story } from "@storybook/addon-docs";
import { useRouter } from "next/router";
import { CustomArgsTable, Title, VariantsTable, VariantRow } from "@calcom/storybook/components";
import WizardForm from "./WizardForm";
<Meta title="UI/Form/WizardForm" component={WizardForm} />
<Title title="WizardForm" subtitle="Version 1.0 — Last Update: 5 Sep 2023" />
## Definition
The `WizardForm` component provides a structure for creating multi-step forms or wizards.
## Structure
<CustomArgsTable of={WizardForm} />
## Note on Navigation
Please be aware that the steps navigation is managed internally within the `WizardForm` component. As such, when viewing this component in Storybook, clicking the "Next" button will not showcase the transition to the subsequent step.
To observe the actual step navigation behavior, please refer to the Storybook stories for the individual `Steps` component.
## WizardForm Story
<Canvas>
<Story
name="Basic"
args={{
href: "/wizard",
steps: [
{ title: "Step 1", description: "Description for Step 1" },
{ title: "Step 2", description: "Description for Step 2" },
{ title: "Step 3", description: "Description for Step 3" },
],
}}
argTypes={{
href: {
control: {
type: "text",
},
},
steps: {
control: {
type: "object",
},
},
}}>
{({ href, steps }) => (
<VariantsTable titles={["Basic Wizard Form"]} columnMinWidth={150}>
<VariantRow>
<WizardForm href={href} steps={steps} />
</VariantRow>
</VariantsTable>
)}
</Story>
</Canvas>
+1 -4
View File
@@ -36,10 +36,7 @@ const TableRow = React.forwardRef<HTMLTableRowElement, React.HTMLAttributes<HTML
({ className, ...props }, ref) => ( ({ className, ...props }, ref) => (
<tr <tr
ref={ref} ref={ref}
className={classNames( className={classNames("hover:muted data-[state=selected]:bg-muted border-subtle border-b", className)}
"hover:bg-subtle data-[state=selected]:bg-subtle border-subtle border-b",
className
)}
{...props} {...props}
/> />
) )
+7
View File
@@ -0,0 +1,7 @@
import { vi } from "vitest";
import createFetchMock from "vitest-fetch-mock";
const fetchMocker = createFetchMock(vi);
// sets globalThis.fetch and globalThis.fetchMock to our mocked version
fetchMocker.enableMocks();
+17
View File
@@ -0,0 +1,17 @@
import { beforeEach, vi } from "vitest";
import { mockReset, mockDeep } from "vitest-mock-extended";
import type * as appStore from "@calcom/app-store";
vi.mock("@calcom/app-store", () => appStoreMock);
beforeEach(() => {
mockReset(appStoreMock);
});
const appStoreMock = mockDeep<typeof appStore>({
fallbackMockImplementation: () => {
throw new Error("Unimplemented");
},
});
export default appStoreMock;
+13
View File
@@ -0,0 +1,13 @@
import { beforeEach, vi } from "vitest";
import { mockReset, mockDeep } from "vitest-mock-extended";
import type * as i18n from "@calcom/lib/server/i18n";
vi.mock("@calcom/lib/server/i18n", () => i18nMock);
beforeEach(() => {
mockReset(i18nMock);
});
const i18nMock = mockDeep<typeof i18n>();
export default i18nMock;
+1
View File
@@ -5,6 +5,7 @@ import type { PrismaClient } from "@calcom/prisma";
vi.mock("@calcom/prisma", () => ({ vi.mock("@calcom/prisma", () => ({
default: prisma, default: prisma,
prisma,
availabilityUserSelect: vi.fn(), availabilityUserSelect: vi.fn(),
userSelect: vi.fn(), userSelect: vi.fn(),
})); }));
+13
View File
@@ -0,0 +1,13 @@
import { beforeEach, vi } from "vitest";
import { mockReset, mockDeep } from "vitest-mock-extended";
import type * as reminderScheduler from "@calcom/features/ee/workflows/lib/reminders/reminderScheduler";
vi.mock("@calcom/features/ee/workflows/lib/reminders/reminderScheduler", () => reminderSchedulerMock);
beforeEach(() => {
mockReset(reminderSchedulerMock);
});
const reminderSchedulerMock = mockDeep<typeof reminderScheduler>();
export default reminderSchedulerMock;
+13
View File
@@ -0,0 +1,13 @@
import { beforeEach, vi } from "vitest";
import { mockReset, mockDeep } from "vitest-mock-extended";
import type * as videoClient from "@calcom/core/videoClient";
vi.mock("@calcom/core/videoClient", () => videoClientMock);
beforeEach(() => {
mockReset(videoClientMock);
});
const videoClientMock = mockDeep<typeof videoClient>();
export default videoClientMock;
+4 -1
View File
@@ -1,9 +1,12 @@
import { defineConfig } from "vitest/config"; import { defineConfig } from "vitest/config";
process.env.INTEGRATION_TEST_MODE = "true";
export default defineConfig({ export default defineConfig({
test: { test: {
coverage: { coverage: {
provider: "c8", provider: "v8",
}, },
testTimeout: 500000,
}, },
}); });
+1
View File
@@ -17,6 +17,7 @@ const workspaces = packagedEmbedTestsOnly
include: ["packages/**/*.{test,spec}.{ts,js}", "apps/**/*.{test,spec}.{ts,js}"], include: ["packages/**/*.{test,spec}.{ts,js}", "apps/**/*.{test,spec}.{ts,js}"],
// TODO: Ignore the api until tests are fixed // TODO: Ignore the api until tests are fixed
exclude: ["apps/api/**/*", "**/node_modules/**/*", "packages/embeds/**/*"], exclude: ["apps/api/**/*", "**/node_modules/**/*", "packages/embeds/**/*"],
setupFiles: ["setupVitest.ts"],
}, },
}, },
{ {
+152 -136
View File
@@ -3746,6 +3746,16 @@ __metadata:
languageName: unknown languageName: unknown
linkType: soft linkType: soft
"@calcom/make@workspace:packages/app-store/make":
version: 0.0.0-use.local
resolution: "@calcom/make@workspace:packages/app-store/make"
dependencies:
"@calcom/lib": "*"
"@calcom/types": "*"
"@types/node-schedule": ^2.1.0
languageName: unknown
linkType: soft
"@calcom/metapixel@workspace:packages/app-store/metapixel": "@calcom/metapixel@workspace:packages/app-store/metapixel":
version: 0.0.0-use.local version: 0.0.0-use.local
resolution: "@calcom/metapixel@workspace:packages/app-store/metapixel" resolution: "@calcom/metapixel@workspace:packages/app-store/metapixel"
@@ -6975,7 +6985,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@jridgewell/sourcemap-codec@npm:^1.4.13, @jridgewell/sourcemap-codec@npm:^1.4.14": "@jridgewell/sourcemap-codec@npm:^1.4.13, @jridgewell/sourcemap-codec@npm:^1.4.14, @jridgewell/sourcemap-codec@npm:^1.4.15":
version: 1.4.15 version: 1.4.15
resolution: "@jridgewell/sourcemap-codec@npm:1.4.15" resolution: "@jridgewell/sourcemap-codec@npm:1.4.15"
checksum: b881c7e503db3fc7f3c1f35a1dd2655a188cc51a3612d76efc8a6eb74728bef5606e6758ee77423e564092b4a518aba569bbb21c9bac5ab7a35b0c6ae7e344c8 checksum: b881c7e503db3fc7f3c1f35a1dd2655a188cc51a3612d76efc8a6eb74728bef5606e6758ee77423e564092b4a518aba569bbb21c9bac5ab7a35b0c6ae7e344c8
@@ -13205,57 +13215,56 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"@vitest/expect@npm:0.31.1": "@vitest/expect@npm:0.34.3":
version: 0.31.1 version: 0.34.3
resolution: "@vitest/expect@npm:0.31.1" resolution: "@vitest/expect@npm:0.34.3"
dependencies: dependencies:
"@vitest/spy": 0.31.1 "@vitest/spy": 0.34.3
"@vitest/utils": 0.31.1 "@vitest/utils": 0.34.3
chai: ^4.3.7 chai: ^4.3.7
checksum: 0d1e135ae753d913231eae830da00ee42afca53d354898fb43f97e82398dcf17298c02e9989dd6b19b9b2909989248ef76d203d63f6af6f9159dc96959ea654b checksum: 79afaa37d2efb7bb5503332caf389860b2261f198dbe61557e8061262b628d18658e59eb51d1808ecd35fc59f4bb4d04c0e0f97a27c7db02584ab5b424147b8d
languageName: node languageName: node
linkType: hard linkType: hard
"@vitest/runner@npm:0.31.1": "@vitest/runner@npm:0.34.3":
version: 0.31.1 version: 0.34.3
resolution: "@vitest/runner@npm:0.31.1" resolution: "@vitest/runner@npm:0.34.3"
dependencies: dependencies:
"@vitest/utils": 0.31.1 "@vitest/utils": 0.34.3
concordance: ^5.0.4
p-limit: ^4.0.0 p-limit: ^4.0.0
pathe: ^1.1.0 pathe: ^1.1.1
checksum: cc8702e21b799d5e941409cb2afe6d0e576b4f3ac99df4a1393a8cd11b57f6b0b06e756cc24e2739812d095fbfd0824e22e861dbd6a71769ca387d485ade6fb5 checksum: 945580eaa58e8edbe29a64059bc2a524a9e85117b6d600fdb457cfe84cbfb81bf6d7e98e1227e7cb4e7399992c8fe8d83d0791d0385ff005dc1a4d9da125443b
languageName: node languageName: node
linkType: hard linkType: hard
"@vitest/snapshot@npm:0.31.1": "@vitest/snapshot@npm:0.34.3":
version: 0.31.1 version: 0.34.3
resolution: "@vitest/snapshot@npm:0.31.1" resolution: "@vitest/snapshot@npm:0.34.3"
dependencies: dependencies:
magic-string: ^0.30.0 magic-string: ^0.30.1
pathe: ^1.1.0 pathe: ^1.1.1
pretty-format: ^27.5.1 pretty-format: ^29.5.0
checksum: de05fa9136864f26f0804baf3ae8068f67de28015f29047329c84e67fb33be7305c9e52661b016e834d30f4081c136b3b6d8d4054c024a5d52b22a7f90fc4be0 checksum: 234893e91a1efd4bdbbde047a68de40975e02ead8407724ce8ca4a24edf0fb2d725f8a3efceb104965388407b598faf22407aadfbf4164cc74b3cf1e0e9f4543
languageName: node languageName: node
linkType: hard linkType: hard
"@vitest/spy@npm:0.31.1": "@vitest/spy@npm:0.34.3":
version: 0.31.1 version: 0.34.3
resolution: "@vitest/spy@npm:0.31.1" resolution: "@vitest/spy@npm:0.34.3"
dependencies: dependencies:
tinyspy: ^2.1.0 tinyspy: ^2.1.1
checksum: 8b06cf25fcc028c16106ec82f4ceb84d6dfa04d06f651bca4738ce2b99796d1fc4e0c10319767240755eff8ede2bff9d31d5a901fe92828d319c65001581137b checksum: a2b64b9c357a56ad2f2340ecd225ffe787e61afba4ffb24a6670aad3fc90ea2606ed48daa188ed62b3ef67d55c0259fda6b101143d6c91b58c9ac4298d8be4f9
languageName: node languageName: node
linkType: hard linkType: hard
"@vitest/utils@npm:0.31.1": "@vitest/utils@npm:0.34.3":
version: 0.31.1 version: 0.34.3
resolution: "@vitest/utils@npm:0.31.1" resolution: "@vitest/utils@npm:0.34.3"
dependencies: dependencies:
concordance: ^5.0.4 diff-sequences: ^29.4.3
loupe: ^2.3.6 loupe: ^2.3.6
pretty-format: ^27.5.1 pretty-format: ^29.5.0
checksum: 58016c185455e3814632cb77e37368c846bde5e342f8b4a66fa229bde64f455ca39abebc9c12e2483696ee38bc17b3c4300379f7a3b18d1087f24f474448a8d8 checksum: aeb8ef7fd98b32cb6c403796880d0aa8f5411bbdb249bb23b3301a70e1b7d1ee025ddb204aae8c1db5756f6ac428c49ebbb8e2ed23ce185c8a659b67413efa85
languageName: node languageName: node
linkType: hard linkType: hard
@@ -13854,6 +13863,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"acorn@npm:^8.10.0, acorn@npm:^8.9.0":
version: 8.10.0
resolution: "acorn@npm:8.10.0"
bin:
acorn: bin/acorn
checksum: 538ba38af0cc9e5ef983aee196c4b8b4d87c0c94532334fa7e065b2c8a1f85863467bb774231aae91613fcda5e68740c15d97b1967ae3394d20faddddd8af61d
languageName: node
linkType: hard
"acorn@npm:^8.5.0": "acorn@npm:^8.5.0":
version: 8.7.1 version: 8.7.1
resolution: "acorn@npm:8.7.1" resolution: "acorn@npm:8.7.1"
@@ -15266,13 +15284,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"blueimp-md5@npm:^2.10.0":
version: 2.19.0
resolution: "blueimp-md5@npm:2.19.0"
checksum: 28095dcbd2c67152a2938006e8d7c74c3406ba6556071298f872505432feb2c13241b0476644160ee0a5220383ba94cb8ccdac0053b51f68d168728f9c382530
languageName: node
linkType: hard
"bmp-js@npm:^0.1.0": "bmp-js@npm:^0.1.0":
version: 0.1.0 version: 0.1.0
resolution: "bmp-js@npm:0.1.0" resolution: "bmp-js@npm:0.1.0"
@@ -15962,7 +15973,8 @@ __metadata:
tsc-absolute: ^1.0.0 tsc-absolute: ^1.0.0
turbo: ^1.10.1 turbo: ^1.10.1
typescript: ^4.9.4 typescript: ^4.9.4
vitest: ^0.31.1 vitest: ^0.34.3
vitest-fetch-mock: ^0.2.2
vitest-mock-extended: ^1.1.3 vitest-mock-extended: ^1.1.3
languageName: unknown languageName: unknown
linkType: soft linkType: soft
@@ -17068,22 +17080,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"concordance@npm:^5.0.4":
version: 5.0.4
resolution: "concordance@npm:5.0.4"
dependencies:
date-time: ^3.1.0
esutils: ^2.0.3
fast-diff: ^1.2.0
js-string-escape: ^1.0.1
lodash: ^4.17.15
md5-hex: ^3.0.1
semver: ^7.3.2
well-known-symbols: ^2.0.0
checksum: 749153ba711492feb7c3d2f5bb04c107157440b3e39509bd5dd19ee7b3ac751d1e4cd75796d9f702e0a713312dbc661421c68aa4a2c34d5f6d91f47e3a1c64a6
languageName: node
linkType: hard
"concurrently@npm:^7.6.0": "concurrently@npm:^7.6.0":
version: 7.6.0 version: 7.6.0
resolution: "concurrently@npm:7.6.0" resolution: "concurrently@npm:7.6.0"
@@ -17504,6 +17500,15 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"cross-fetch@npm:^3.0.6":
version: 3.1.8
resolution: "cross-fetch@npm:3.1.8"
dependencies:
node-fetch: ^2.6.12
checksum: 78f993fa099eaaa041122ab037fe9503ecbbcb9daef234d1d2e0b9230a983f64d645d088c464e21a247b825a08dc444a6e7064adfa93536d3a9454b4745b3632
languageName: node
linkType: hard
"cross-spawn@npm:7.0.3, cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3": "cross-spawn@npm:7.0.3, cross-spawn@npm:^7.0.0, cross-spawn@npm:^7.0.1, cross-spawn@npm:^7.0.2, cross-spawn@npm:^7.0.3":
version: 7.0.3 version: 7.0.3
resolution: "cross-spawn@npm:7.0.3" resolution: "cross-spawn@npm:7.0.3"
@@ -17926,15 +17931,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"date-time@npm:^3.1.0":
version: 3.1.0
resolution: "date-time@npm:3.1.0"
dependencies:
time-zone: ^1.0.0
checksum: f9cfcd1b15dfeabab15c0b9d18eb9e4e2d9d4371713564178d46a8f91ad577a290b5178b80050718d02d9c0cf646f8a875011e12d1ed05871e9f72c72c8a8fe6
languageName: node
linkType: hard
"datocms-listen@npm:^0.1.9": "datocms-listen@npm:^0.1.9":
version: 0.1.15 version: 0.1.15
resolution: "datocms-listen@npm:0.1.15" resolution: "datocms-listen@npm:0.1.15"
@@ -19936,7 +19932,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"esutils@npm:^2.0.2, esutils@npm:^2.0.3": "esutils@npm:^2.0.2":
version: 2.0.3 version: 2.0.3
resolution: "esutils@npm:2.0.3" resolution: "esutils@npm:2.0.3"
checksum: 22b5b08f74737379a840b8ed2036a5fb35826c709ab000683b092d9054e5c2a82c27818f12604bfc2a9a76b90b6834ef081edbc1c7ae30d1627012e067c6ec87 checksum: 22b5b08f74737379a840b8ed2036a5fb35826c709ab000683b092d9054e5c2a82c27818f12604bfc2a9a76b90b6834ef081edbc1c7ae30d1627012e067c6ec87
@@ -20391,13 +20387,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"fast-diff@npm:^1.2.0":
version: 1.3.0
resolution: "fast-diff@npm:1.3.0"
checksum: d22d371b994fdc8cce9ff510d7b8dc4da70ac327bcba20df607dd5b9cae9f908f4d1028f5fe467650f058d1e7270235ae0b8230809a262b4df587a3b3aa216c3
languageName: node
linkType: hard
"fast-equals@npm:^1.6.3": "fast-equals@npm:^1.6.3":
version: 1.6.3 version: 1.6.3
resolution: "fast-equals@npm:1.6.3" resolution: "fast-equals@npm:1.6.3"
@@ -26516,12 +26505,12 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"magic-string@npm:^0.30.0": "magic-string@npm:^0.30.1":
version: 0.30.0 version: 0.30.3
resolution: "magic-string@npm:0.30.0" resolution: "magic-string@npm:0.30.3"
dependencies: dependencies:
"@jridgewell/sourcemap-codec": ^1.4.13 "@jridgewell/sourcemap-codec": ^1.4.15
checksum: 7bdf22e27334d8a393858a16f5f840af63a7c05848c000fd714da5aa5eefa09a1bc01d8469362f25cc5c4a14ec01b46557b7fff8751365522acddf21e57c488d checksum: a5a9ddf9bd3bf49a2de1048bf358464f1bda7b3cc1311550f4a0ba8f81a4070e25445d53a5ee28850161336f1bff3cf28aa3320c6b4aeff45ce3e689f300b2f3
languageName: node languageName: node
linkType: hard linkType: hard
@@ -26715,15 +26704,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"md5-hex@npm:^3.0.1":
version: 3.0.1
resolution: "md5-hex@npm:3.0.1"
dependencies:
blueimp-md5: ^2.10.0
checksum: 6799a19e8bdd3e0c2861b94c1d4d858a89220488d7885c1fa236797e367d0c2e5f2b789e05309307083503f85be3603a9686a5915568a473137d6b4117419cc2
languageName: node
linkType: hard
"md5.js@npm:^1.3.4": "md5.js@npm:^1.3.4":
version: 1.3.5 version: 1.3.5
resolution: "md5.js@npm:1.3.5" resolution: "md5.js@npm:1.3.5"
@@ -27786,6 +27766,18 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"mlly@npm:^1.4.0":
version: 1.4.1
resolution: "mlly@npm:1.4.1"
dependencies:
acorn: ^8.10.0
pathe: ^1.1.1
pkg-types: ^1.0.3
ufo: ^1.3.0
checksum: b2b59ab3d70196127be4e54609d2a442bd252345727138940fb245672a238b2fbdd431e8c75ec5c741ff90410ce488c5fd6446d5d3e6476d21dbf4c3fa35d4a0
languageName: node
linkType: hard
"mock-fs@npm:^4.1.0": "mock-fs@npm:^4.1.0":
version: 4.14.0 version: 4.14.0
resolution: "mock-fs@npm:4.14.0" resolution: "mock-fs@npm:4.14.0"
@@ -28436,6 +28428,20 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"node-fetch@npm:^2.6.12":
version: 2.7.0
resolution: "node-fetch@npm:2.7.0"
dependencies:
whatwg-url: ^5.0.0
peerDependencies:
encoding: ^0.1.0
peerDependenciesMeta:
encoding:
optional: true
checksum: d76d2f5edb451a3f05b15115ec89fc6be39de37c6089f1b6368df03b91e1633fd379a7e01b7ab05089a25034b2023d959b47e59759cb38d88341b2459e89d6e5
languageName: node
linkType: hard
"node-forge@npm:1.3.1, node-forge@npm:^1.0.0": "node-forge@npm:1.3.1, node-forge@npm:^1.0.0":
version: 1.3.1 version: 1.3.1
resolution: "node-forge@npm:1.3.1" resolution: "node-forge@npm:1.3.1"
@@ -29879,6 +29885,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"pathe@npm:^1.1.1":
version: 1.1.1
resolution: "pathe@npm:1.1.1"
checksum: 34ab3da2e5aa832ebc6a330ffe3f73d7ba8aec6e899b53b8ec4f4018de08e40742802deb12cf5add9c73b7bf719b62c0778246bd376ca62b0fb23e0dde44b759
languageName: node
linkType: hard
"pathval@npm:^1.1.1": "pathval@npm:^1.1.1":
version: 1.1.1 version: 1.1.1
resolution: "pathval@npm:1.1.1" resolution: "pathval@npm:1.1.1"
@@ -30708,7 +30721,7 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"pretty-format@npm:^27.0.2, pretty-format@npm:^27.5.1": "pretty-format@npm:^27.0.2":
version: 27.5.1 version: 27.5.1
resolution: "pretty-format@npm:27.5.1" resolution: "pretty-format@npm:27.5.1"
dependencies: dependencies:
@@ -34498,10 +34511,10 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"std-env@npm:^3.3.2": "std-env@npm:^3.3.3":
version: 3.3.3 version: 3.4.3
resolution: "std-env@npm:3.3.3" resolution: "std-env@npm:3.4.3"
checksum: 6665f6d8bd63aae432d3eb9abbd7322847ad0d902603e6dce1e8051b4f42ceeb4f7f96a4faf70bb05ce65ceee2dc982502b701575c8a58b1bfad29f3dbb19f81 checksum: bef186fb2baddda31911234b1e58fa18f181eb6930616aaec3b54f6d5db65f2da5daaa5f3b326b98445a7d50ca81d6fe8809ab4ebab85ecbe4a802f1b40921bf
languageName: node languageName: node
linkType: hard linkType: hard
@@ -35801,13 +35814,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"time-zone@npm:^1.0.0":
version: 1.0.0
resolution: "time-zone@npm:1.0.0"
checksum: e46f5a69b8c236dcd8e91e29d40d4e7a3495ed4f59888c3f84ce1d9678e20461421a6ba41233509d47dd94bc18f1a4377764838b21b584663f942b3426dcbce8
languageName: node
linkType: hard
"timed-out@npm:^4.0.0, timed-out@npm:^4.0.1": "timed-out@npm:^4.0.0, timed-out@npm:^4.0.1":
version: 4.0.1 version: 4.0.1
resolution: "timed-out@npm:4.0.1" resolution: "timed-out@npm:4.0.1"
@@ -35893,17 +35899,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"tinypool@npm:^0.5.0": "tinypool@npm:^0.7.0":
version: 0.5.0 version: 0.7.0
resolution: "tinypool@npm:0.5.0" resolution: "tinypool@npm:0.7.0"
checksum: 4e0dfd8f28666d541c1d92304222edc4613f05d74fe2243c8520d466a2cc6596011a7072c1c41a7de7522351b82fda07e8038198e8f43673d8d69401c5903f8c checksum: fdcccd5c750574fce51f8801a877f8284e145d12b79cd5f2d72bfbddfe20c895e915555bc848e122bb6aa968098e7ac4fe1e8e88104904d518dc01cccd18a510
languageName: node languageName: node
linkType: hard linkType: hard
"tinyspy@npm:^2.1.0": "tinyspy@npm:^2.1.1":
version: 2.1.0 version: 2.1.1
resolution: "tinyspy@npm:2.1.0" resolution: "tinyspy@npm:2.1.1"
checksum: cb83c1f74a79dd5934018bad94f60a304a29d98a2d909ea45fc367f7b80b21b0a7d8135a2ce588deb2b3ba56c7c607258b2a03e6001d89e4d564f9a95cc6a81f checksum: cfe669803a7f11ca912742b84c18dcc4ceecaa7661c69bc5eb608a8a802d541c48aba220df8929f6c8cd09892ad37cb5ba5958ddbbb57940e91d04681d3cee73
languageName: node languageName: node
linkType: hard linkType: hard
@@ -36850,6 +36856,13 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"ufo@npm:^1.3.0":
version: 1.3.0
resolution: "ufo@npm:1.3.0"
checksum: 01f0be86cd5c205ad1b49ebea985e000a4542c503ee75398302b0f5e4b9a6d9cd8e77af2dc614ab7bea08805fdfd9a85191fb3b5ee3df383cb936cf65e9db30d
languageName: node
linkType: hard
"uglify-js@npm:^3.1.4": "uglify-js@npm:^3.1.4":
version: 3.15.3 version: 3.15.3
resolution: "uglify-js@npm:3.15.3" resolution: "uglify-js@npm:3.15.3"
@@ -37830,19 +37843,19 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vite-node@npm:0.31.1": "vite-node@npm:0.34.3":
version: 0.31.1 version: 0.34.3
resolution: "vite-node@npm:0.31.1" resolution: "vite-node@npm:0.34.3"
dependencies: dependencies:
cac: ^6.7.14 cac: ^6.7.14
debug: ^4.3.4 debug: ^4.3.4
mlly: ^1.2.0 mlly: ^1.4.0
pathe: ^1.1.0 pathe: ^1.1.1
picocolors: ^1.0.0 picocolors: ^1.0.0
vite: ^3.0.0 || ^4.0.0 vite: ^3.0.0 || ^4.0.0
bin: bin:
vite-node: vite-node.mjs vite-node: vite-node.mjs
checksum: f70ffa3f6dcb4937cdc99f59bf360d42de83c556ba9a19eb1c3504ef20db4c1d1afa644d9a8e63240e851c0c95773b64c526bdb3eb4794b5e941ddcd57124aa9 checksum: 366c4f3fb7c038e2180abc6b18cfbac3b8684cd878eaf7ebf1ffb07d95d2ea325713fc575a7949a13bb00cfe264acbc28c02e2836b8647e1f443fe631c17805a
languageName: node languageName: node
linkType: hard linkType: hard
@@ -37920,6 +37933,17 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vitest-fetch-mock@npm:^0.2.2":
version: 0.2.2
resolution: "vitest-fetch-mock@npm:0.2.2"
dependencies:
cross-fetch: ^3.0.6
peerDependencies:
vitest: ">=0.16.0"
checksum: fa160f301171cd45dbf7d782880b6b6063fc74b9dd1965ef9206545e812ca8696e6be76662afbac822c6bf850fbb66cf8fb066af646e0e159f5a87ab25c97a02
languageName: node
linkType: hard
"vitest-mock-extended@npm:^1.1.3": "vitest-mock-extended@npm:^1.1.3":
version: 1.1.3 version: 1.1.3
resolution: "vitest-mock-extended@npm:1.1.3" resolution: "vitest-mock-extended@npm:1.1.3"
@@ -37932,34 +37956,33 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"vitest@npm:^0.31.1": "vitest@npm:^0.34.3":
version: 0.31.1 version: 0.34.3
resolution: "vitest@npm:0.31.1" resolution: "vitest@npm:0.34.3"
dependencies: dependencies:
"@types/chai": ^4.3.5 "@types/chai": ^4.3.5
"@types/chai-subset": ^1.3.3 "@types/chai-subset": ^1.3.3
"@types/node": "*" "@types/node": "*"
"@vitest/expect": 0.31.1 "@vitest/expect": 0.34.3
"@vitest/runner": 0.31.1 "@vitest/runner": 0.34.3
"@vitest/snapshot": 0.31.1 "@vitest/snapshot": 0.34.3
"@vitest/spy": 0.31.1 "@vitest/spy": 0.34.3
"@vitest/utils": 0.31.1 "@vitest/utils": 0.34.3
acorn: ^8.8.2 acorn: ^8.9.0
acorn-walk: ^8.2.0 acorn-walk: ^8.2.0
cac: ^6.7.14 cac: ^6.7.14
chai: ^4.3.7 chai: ^4.3.7
concordance: ^5.0.4
debug: ^4.3.4 debug: ^4.3.4
local-pkg: ^0.4.3 local-pkg: ^0.4.3
magic-string: ^0.30.0 magic-string: ^0.30.1
pathe: ^1.1.0 pathe: ^1.1.1
picocolors: ^1.0.0 picocolors: ^1.0.0
std-env: ^3.3.2 std-env: ^3.3.3
strip-literal: ^1.0.1 strip-literal: ^1.0.1
tinybench: ^2.5.0 tinybench: ^2.5.0
tinypool: ^0.5.0 tinypool: ^0.7.0
vite: ^3.0.0 || ^4.0.0 vite: ^3.0.0 || ^4.0.0
vite-node: 0.31.1 vite-node: 0.34.3
why-is-node-running: ^2.2.2 why-is-node-running: ^2.2.2
peerDependencies: peerDependencies:
"@edge-runtime/vm": "*" "@edge-runtime/vm": "*"
@@ -37989,7 +38012,7 @@ __metadata:
optional: true optional: true
bin: bin:
vitest: vitest.mjs vitest: vitest.mjs
checksum: b3f64a36102edc5b8594c085da648c838c0d275c620bd3b780624f936903b9c06579d6ef137fe9859e468f16deb8f154a50f009093119f9adb8b60ff1b7597ee checksum: 4535d080feede94db5015eb60c6ed5f7b0d8cd67f12072de5ae1faded133cc640043c0c2646ef51ab9b61c2f885589da57458a65e82cf91a25cf954470018a40
languageName: node languageName: node
linkType: hard linkType: hard
@@ -38693,13 +38716,6 @@ __metadata:
languageName: node languageName: node
linkType: hard linkType: hard
"well-known-symbols@npm:^2.0.0":
version: 2.0.0
resolution: "well-known-symbols@npm:2.0.0"
checksum: 4f54bbc3012371cb4d228f436891b8e7536d34ac61a57541890257e96788608e096231e0121ac24d08ef2f908b3eb2dc0adba35023eaeb2a7df655da91415402
languageName: node
linkType: hard
"whatwg-encoding@npm:^2.0.0": "whatwg-encoding@npm:^2.0.0":
version: 2.0.0 version: 2.0.0
resolution: "whatwg-encoding@npm:2.0.0" resolution: "whatwg-encoding@npm:2.0.0"