-
Display Name
+
{t("display_name")}
-
Username
+
{t("username")}
setUser({ ...user, username: e.target.value })}
/>
-
- {emailEnabled ? (
+ {emailEnabled && (
-
Email
- {user.email !== account.email &&
- process.env.NEXT_PUBLIC_STRIPE === "true" ? (
-
- Updating this field will change your billing email as well
-
- ) : undefined}
+
{t("email")}
setUser({ ...user, email: e.target.value })}
/>
- ) : undefined}
+ )}
+
+
{t("language")}
+
{
+ setUser({ ...user, locale: e.target.value });
+ }}
+ className="select border border-neutral-content focus:outline-none focus:border-primary duration-100 w-full bg-base-200 rounded-[0.375rem] min-h-0 h-[2.625rem] leading-4 p-2"
+ >
+ {i18n.locales.map((locale) => (
+
+ {new Intl.DisplayNames(locale, { type: "language" }).of(
+ locale
+ ) || ""}
+
+ ))}
+ {t("more_coming_soon")}
+
+
-
Profile Photo
-
+
{t("profile_photo")}
+
- {user.image && (
-
- setUser({
- ...user,
- image: "",
- })
- }
- className="absolute top-1 left-1 btn btn-xs btn-circle btn-neutral btn-outline bg-base-100"
+
+
+
-
-
- )}
-
-
- Browse...
-
-
+
+ {t("edit")}
+
+
+
+
setUser({ ...user, isPrivate: !user.isPrivate })}
+ />
+
+ {t("profile_privacy_info")}
+
+ {user.isPrivate && (
+
+
{t("whitelisted_users")}
+
+ {t("whitelisted_users_info")}
+
+
+ )}
+
+
+
{
+ if (account.email !== user.email) {
+ setEmailChangeVerificationModal(true);
+ } else {
+ submit();
+ }
+ }}
+ loading={submitLoader}
+ label={t("save_changes")}
+ className="mt-2 w-full sm:w-fit"
+ />
+
- Import & Export
+ {t("import_export")}
@@ -241,27 +356,30 @@ export default function Account() {
-
Import your data from other platforms.
+
{t("import_data")}
-
-
+ {t("import_links")}
+
+
+
-
Download your data instantly.
+
{t("download_data")}
-
+
-
Export Data
+
{t("export_data")}
-
-
-
- Profile Visibility
-
-
-
-
-
-
setUser({ ...user, isPrivate: !user.isPrivate })}
- />
-
-
- This will limit who can find and add you to new Collections.
-
-
- {user.isPrivate && (
-
-
Whitelisted Users
-
- Please provide the Username of the users you wish to grant
- visibility to your profile. Separated by comma.
-
-
- )}
-
-
-
-
- Delete Account
+ {t("delete_account")}
- This will permanently delete ALL the Links, Collections, Tags, and
- archived data you own.{" "}
- {process.env.NEXT_PUBLIC_STRIPE
- ? "It will also cancel your subscription. "
- : undefined}{" "}
- You will be prompted to enter your password before the deletion
- process.
+ {t("delete_account_warning")}
+ {process.env.NEXT_PUBLIC_STRIPE &&
+ " " + t("cancel_subscription_notice")}
-
-
Delete Your Account
+
+ {t("account_deletion_page")}
+
+ {emailChangeVerificationModal && (
+ setEmailChangeVerificationModal(false)}
+ onSubmit={submit}
+ oldEmail={account.email || ""}
+ newEmail={user.email || ""}
+ />
+ )}
);
}
+
+export { getServerSideProps };
diff --git a/pages/settings/billing.tsx b/pages/settings/billing.tsx
index 139c74b..a5abb98 100644
--- a/pages/settings/billing.tsx
+++ b/pages/settings/billing.tsx
@@ -1,9 +1,12 @@
import SettingsLayout from "@/layouts/SettingsLayout";
import { useRouter } from "next/router";
import { useEffect } from "react";
+import { useTranslation } from "next-i18next";
+import getServerSideProps from "@/lib/client/getServerSideProps";
export default function Billing() {
const router = useRouter();
+ const { t } = useTranslation();
useEffect(() => {
if (!process.env.NEXT_PUBLIC_STRIPE) router.push("/settings/profile");
@@ -11,29 +14,28 @@ export default function Billing() {
return (
- Billing Settings
+
+ {t("billing_settings")}
+
- To manage/cancel your subscription, visit the{" "}
+ {t("manage_subscription_intro")}{" "}
- Billing Portal
+ {t("billing_portal")}
.
- If you still need help or encountered any issues, feel free to reach
- out to us at:{" "}
-
+ {t("help_contact_intro")}{" "}
+
support@linkwarden.app
@@ -41,3 +43,5 @@ export default function Billing() {
);
}
+
+export { getServerSideProps };
diff --git a/pages/settings/delete.tsx b/pages/settings/delete.tsx
index 0c78932..0d11b87 100644
--- a/pages/settings/delete.tsx
+++ b/pages/settings/delete.tsx
@@ -4,18 +4,17 @@ import TextInput from "@/components/TextInput";
import CenteredForm from "@/layouts/CenteredForm";
import { signOut, useSession } from "next-auth/react";
import Link from "next/link";
-
-const keycloakEnabled = process.env.NEXT_PUBLIC_KEYCLOAK_ENABLED === "true";
-const authentikEnabled = process.env.NEXT_PUBLIC_AUTHENTIK_ENABLED === "true";
+import Button from "@/components/ui/Button";
+import { useTranslation } from "next-i18next";
+import getServerSideProps from "@/lib/client/getServerSideProps";
export default function Delete() {
const [password, setPassword] = useState("");
const [comment, setComment] = useState
();
const [feedback, setFeedback] = useState();
-
const [submitLoader, setSubmitLoader] = useState(false);
-
const { data } = useSession();
+ const { t } = useTranslation();
const submit = async () => {
const body = {
@@ -26,13 +25,12 @@ export default function Delete() {
},
};
- if (!keycloakEnabled && !authentikEnabled && password == "") {
- return toast.error("Please fill the required fields.");
+ if (password === "") {
+ return toast.error(t("fill_required_fields"));
}
setSubmitLoader(true);
-
- const load = toast.loading("Deleting everything, please wait...");
+ const load = toast.loading(t("deleting_message"));
const response = await fetch(`/api/v1/users/${data?.user.id}`, {
method: "DELETE",
@@ -48,7 +46,9 @@ export default function Delete() {
if (response.ok) {
signOut();
- } else toast.error(message);
+ } else {
+ toast.error(message);
+ }
setSubmitLoader(false);
};
@@ -60,96 +60,82 @@ export default function Delete() {
href="/settings/account"
className="absolute top-4 left-4 btn btn-ghost btn-square btn-sm"
>
-
+
- Delete Account
+ {t("delete_account")}
-
- This will permanently delete all the Links, Collections, Tags, and
- archived data you own. It will also log you out
- {process.env.NEXT_PUBLIC_STRIPE
- ? " and cancel your subscription"
- : undefined}
- . This action is irreversible!
-
+ {t("delete_warning")}
- {process.env.NEXT_PUBLIC_KEYCLOAK_ENABLED !== "true" ? (
-
-
Confirm Your Password
+
+
{t("confirm_password")}
+
setPassword(e.target.value)}
+ placeholder="••••••••••••••"
+ className="bg-base-100"
+ type="password"
+ />
+
-
setPassword(e.target.value)}
- placeholder="••••••••••••••"
- className="bg-base-100"
- type="password"
- />
-
- ) : undefined}
-
- {process.env.NEXT_PUBLIC_STRIPE ? (
+ {process.env.NEXT_PUBLIC_STRIPE && (
- Optional {" "}
-
- (but it really helps us improve!)
-
+ {t("optional")} {t("feedback_help")}
- Reason for cancellation:
+ {t("reason_for_cancellation")}:
setFeedback(e.target.value)}
>
- Please specify
- Customer Service
- Low Quality
- Missing Features
- Switched Service
- Too Complex
- Too Expensive
- Unused
- Other
+ {t("please_specify")}
+
+ {t("customer_service")}
+
+ {t("low_quality")}
+
+ {t("missing_features")}
+
+
+ {t("switched_service")}
+
+ {t("too_complex")}
+ {t("too_expensive")}
+ {t("unused")}
+ {t("other")}
-
- More information (the more details, the more helpful it'd
- be)
-
+
{t("more_information")}
- ) : undefined}
+ )}
- {
- if (!submitLoader) {
- submit();
- }
- }}
+
- Delete Your Account
-
+ {t("delete_your_account")}
+
);
}
+
+export { getServerSideProps };
diff --git a/pages/settings/password.tsx b/pages/settings/password.tsx
index ee8af3b..808be7a 100644
--- a/pages/settings/password.tsx
+++ b/pages/settings/password.tsx
@@ -1,75 +1,82 @@
import SettingsLayout from "@/layouts/SettingsLayout";
import { useState } from "react";
-import useAccountStore from "@/store/account";
import SubmitButton from "@/components/SubmitButton";
import { toast } from "react-hot-toast";
import TextInput from "@/components/TextInput";
+import { useTranslation } from "next-i18next";
+import getServerSideProps from "@/lib/client/getServerSideProps";
+import { useUpdateUser, useUser } from "@/hooks/store/user";
export default function Password() {
- const [newPassword, setNewPassword1] = useState("");
- const [newPassword2, setNewPassword2] = useState("");
+ const { t } = useTranslation();
+ const [oldPassword, setOldPassword] = useState("");
+ const [newPassword, setNewPassword] = useState("");
const [submitLoader, setSubmitLoader] = useState(false);
-
- const { account, updateAccount } = useAccountStore();
+ const { data: account } = useUser();
+ const updateUser = useUpdateUser();
const submit = async () => {
- if (newPassword == "" || newPassword2 == "") {
- return toast.error("Please fill all the fields.");
+ if (newPassword === "" || oldPassword === "") {
+ return toast.error(t("fill_all_fields"));
}
-
- if (newPassword !== newPassword2)
- return toast.error("Passwords do not match.");
- else if (newPassword.length < 8)
- return toast.error("Passwords must be at least 8 characters.");
+ if (newPassword.length < 8) return toast.error(t("password_length_error"));
setSubmitLoader(true);
- const load = toast.loading("Applying...");
+ const load = toast.loading(t("applying_settings"));
- const response = await updateAccount({
- ...account,
- newPassword,
- });
+ await updateUser.mutateAsync(
+ {
+ ...account,
+ newPassword,
+ oldPassword,
+ },
+ {
+ onSettled: (data, error) => {
+ toast.dismiss(load);
- toast.dismiss(load);
+ if (error) {
+ toast.error(error.message);
+ } else {
+ setNewPassword("");
+ setOldPassword("");
- if (response.ok) {
- toast.success("Settings Applied!");
- setNewPassword1("");
- setNewPassword2("");
- } else toast.error(response.data as string);
+ toast.success(t("settings_applied"));
+ }
+ },
+ }
+ );
setSubmitLoader(false);
};
return (
- Change Password
+
+ {t("change_password")}
+
-
- To change your password, please fill out the following. Your password
- should be at least 8 characters.
-
+ {t("password_change_instructions")}
-
New Password
+
{t("old_password")}
setNewPassword1(e.target.value)}
+ onChange={(e) => setOldPassword(e.target.value)}
placeholder="••••••••••••••"
type="password"
/>
- Confirm New Password
+ {t("new_password")}
setNewPassword2(e.target.value)}
+ onChange={(e) => setNewPassword(e.target.value)}
placeholder="••••••••••••••"
type="password"
/>
@@ -77,10 +84,12 @@ export default function Password() {
);
}
+
+export { getServerSideProps };
diff --git a/pages/settings/preference.tsx b/pages/settings/preference.tsx
index 1d5a2e0..4d93d02 100644
--- a/pages/settings/preference.tsx
+++ b/pages/settings/preference.tsx
@@ -1,36 +1,46 @@
import SettingsLayout from "@/layouts/SettingsLayout";
import { useState, useEffect } from "react";
-import useAccountStore from "@/store/account";
-import { AccountSettings } from "@/types/global";
-import { toast } from "react-hot-toast";
-import React from "react";
-import useLocalSettingsStore from "@/store/localSettings";
-import Checkbox from "@/components/Checkbox";
import SubmitButton from "@/components/SubmitButton";
+import { toast } from "react-hot-toast";
+import Checkbox from "@/components/Checkbox";
+import useLocalSettingsStore from "@/store/localSettings";
+import { useTranslation } from "next-i18next";
+import getServerSideProps from "@/lib/client/getServerSideProps"; // Import getServerSideProps for server-side data fetching
import { LinksRouteTo } from "@prisma/client";
+import { useUpdateUser, useUser } from "@/hooks/store/user";
export default function Appearance() {
+ const { t } = useTranslation();
const { updateSettings } = useLocalSettingsStore();
-
const [submitLoader, setSubmitLoader] = useState(false);
- const { account, updateAccount } = useAccountStore();
- const [user, setUser] = useState(account);
+ const { data: account } = useUser();
+ const updateUser = useUpdateUser();
+ const [user, setUser] = useState(account);
- const [preventDuplicateLinks, setPreventDuplicateLinks] =
- useState(false);
- const [archiveAsScreenshot, setArchiveAsScreenshot] =
- useState(false);
- const [archiveAsPDF, setArchiveAsPDF] = useState(false);
- const [archiveAsWaybackMachine, setArchiveAsWaybackMachine] =
- useState(false);
- const [linksRouteTo, setLinksRouteTo] = useState(
- user.linksRouteTo
+ const [preventDuplicateLinks, setPreventDuplicateLinks] = useState(
+ account.preventDuplicateLinks
);
+ const [archiveAsScreenshot, setArchiveAsScreenshot] = useState(
+ account.archiveAsScreenshot
+ );
+ const [archiveAsPDF, setArchiveAsPDF] = useState(
+ account.archiveAsPDF
+ );
+
+ const [archiveAsMonolith, setArchiveAsMonolith] = useState(
+ account.archiveAsMonolith
+ );
+
+ const [archiveAsWaybackMachine, setArchiveAsWaybackMachine] =
+ useState(account.archiveAsWaybackMachine);
+
+ const [linksRouteTo, setLinksRouteTo] = useState(account.linksRouteTo);
useEffect(() => {
setUser({
...account,
archiveAsScreenshot,
+ archiveAsMonolith,
archiveAsPDF,
archiveAsWaybackMachine,
linksRouteTo,
@@ -39,6 +49,7 @@ export default function Appearance() {
}, [
account,
archiveAsScreenshot,
+ archiveAsMonolith,
archiveAsPDF,
archiveAsWaybackMachine,
linksRouteTo,
@@ -52,6 +63,7 @@ export default function Appearance() {
useEffect(() => {
if (!objectIsEmpty(account)) {
setArchiveAsScreenshot(account.archiveAsScreenshot);
+ setArchiveAsMonolith(account.archiveAsMonolith);
setArchiveAsPDF(account.archiveAsPDF);
setArchiveAsWaybackMachine(account.archiveAsWaybackMachine);
setLinksRouteTo(account.linksRouteTo);
@@ -62,29 +74,35 @@ export default function Appearance() {
const submit = async () => {
setSubmitLoader(true);
- const load = toast.loading("Applying...");
+ const load = toast.loading(t("applying_settings"));
- const response = await updateAccount({
- ...user,
- });
+ await updateUser.mutateAsync(
+ { ...user },
+ {
+ onSettled: (data, error) => {
+ toast.dismiss(load);
- toast.dismiss(load);
+ if (error) {
+ toast.error(error.message);
+ } else {
+ toast.success(t("settings_applied"));
+ }
+ },
+ }
+ );
- if (response.ok) {
- toast.success("Settings Applied!");
- } else toast.error(response.data as string);
setSubmitLoader(false);
};
return (
- Preference
+ {t("preference")}
-
Select Theme
+
{t("select_theme")}
updateSettings({ theme: "dark" })}
>
-
Dark
-
- {/*
*/}
+
{t("dark")}
updateSettings({ theme: "light" })}
>
-
Light
- {/*
*/}
+
{t("light")}
- Archive Settings
+ {t("archive_settings")}
-
-
-
Formats to Archive/Preserve webpages:
+
{t("formats_to_archive")}
setArchiveAsScreenshot(!archiveAsScreenshot)}
/>
setArchiveAsPDF(!archiveAsPDF)}
+ label={t("webpage")}
+ state={archiveAsMonolith}
+ onClick={() => setArchiveAsMonolith(!archiveAsMonolith)}
/>
setArchiveAsPDF(!archiveAsPDF)}
+ />
+
setArchiveAsWaybackMachine(!archiveAsWaybackMachine)
@@ -146,18 +164,18 @@ export default function Appearance() {
-
Link Settings
-
+
+ {t("link_settings")}
+
setPreventDuplicateLinks(!preventDuplicateLinks)}
/>
-
-
Clicking on Links should:
+
{t("clicking_on_links_should")}
setLinksRouteTo(LinksRouteTo.ORIGINAL)}
/>
- Open the original content
+ {t("open_original_content")}
setLinksRouteTo(LinksRouteTo.PDF)}
/>
- Open PDF, if available
+ {t("open_pdf_if_available")}
setLinksRouteTo(LinksRouteTo.READABLE)}
/>
- Open Readable, if available
+
+ {t("open_readable_if_available")}
+
+
+
+
+ setLinksRouteTo(LinksRouteTo.MONOLITH)}
+ />
+
+ {t("open_webpage_if_available")}
+
setLinksRouteTo(LinksRouteTo.SCREENSHOT)}
/>
- Open Screenshot, if available
+
+ {t("open_screenshot_if_available")}
+
@@ -228,10 +268,12 @@ export default function Appearance() {
);
}
+
+export { getServerSideProps };
diff --git a/pages/subscribe.tsx b/pages/subscribe.tsx
index 3663f24..555798c 100644
--- a/pages/subscribe.tsx
+++ b/pages/subscribe.tsx
@@ -1,12 +1,18 @@
import { signOut, useSession } from "next-auth/react";
-import { useState } from "react";
+import { useEffect, useState } from "react";
import { toast } from "react-hot-toast";
import { useRouter } from "next/router";
import CenteredForm from "@/layouts/CenteredForm";
import { Plan } from "@/types/global";
-import AccentSubmitButton from "@/components/AccentSubmitButton";
+import Button from "@/components/ui/Button";
+import getServerSideProps from "@/lib/client/getServerSideProps";
+import { Trans, useTranslation } from "next-i18next";
+import { useUser } from "@/hooks/store/user";
+
+const stripeEnabled = process.env.NEXT_PUBLIC_STRIPE === "true";
export default function Subscribe() {
+ const { t } = useTranslation();
const [submitLoader, setSubmitLoader] = useState(false);
const session = useSession();
@@ -14,10 +20,21 @@ export default function Subscribe() {
const router = useRouter();
+ const { data: user = {} } = useUser();
+
+ useEffect(() => {
+ const hasInactiveSubscription =
+ user.id && !user.subscription?.active && stripeEnabled;
+
+ if (session.status === "authenticated" && !hasInactiveSubscription) {
+ router.push("/dashboard");
+ }
+ }, [session.status]);
+
async function submit() {
setSubmitLoader(true);
- const redirectionToast = toast.loading("Redirecting to Stripe...");
+ const redirectionToast = toast.loading(t("redirecting_to_stripe"));
const res = await fetch("/api/v1/payment?plan=" + plan);
const data = await res.json();
@@ -33,18 +50,23 @@ export default function Subscribe() {
>
- Subscribe to Linkwarden!
+ {t("subscribe_title")}
- You will be redirected to Stripe, feel free to reach out to us at{" "}
-
- support@linkwarden.app
- {" "}
- in case of any issue.
+ ,
+ ]}
+ />
@@ -57,7 +79,7 @@ export default function Subscribe() {
: "hover:opacity-80"
}`}
>
-
Monthly
+
{t("monthly")}
- Yearly
+ {t("yearly")}
-
- 25% Off
+
+ {t("discount_percent", {
+ percent: 25,
+ })}
@@ -81,36 +105,47 @@ export default function Subscribe() {
/mo
- Billed {plan === Plan.monthly ? "Monthly" : "Yearly"}
+ {plan === Plan.monthly ? t("billed_monthly") : t("billed_yearly")}
- Total
+ {t("total")}
- {process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS}-day free trial, then $
- {plan === Plan.monthly ? "4 per month" : "36 annually"}
+ {plan === Plan.monthly
+ ? t("total_monthly_desc", {
+ count: Number(process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS),
+ monthlyPrice: "4",
+ })
+ : t("total_annual_desc", {
+ count: Number(process.env.NEXT_PUBLIC_TRIAL_PERIOD_DAYS),
+ annualPrice: "36",
+ })}
- + VAT if applicable
+ {t("plus_tax")}
-
+ >
+ {t("complete_subscription")}
+
signOut()}
className="w-fit mx-auto cursor-pointer text-neutral font-semibold "
>
- Sign Out
+ {t("sign_out")}
);
}
+
+export { getServerSideProps };
diff --git a/pages/tags/[id].tsx b/pages/tags/[id].tsx
index 34d172f..14196a1 100644
--- a/pages/tags/[id].tsx
+++ b/pages/tags/[id].tsx
@@ -1,29 +1,29 @@
-import useLinkStore from "@/store/links";
import { useRouter } from "next/router";
-import { FormEvent, use, useEffect, useState } from "react";
+import { FormEvent, useEffect, useState } from "react";
import MainLayout from "@/layouts/MainLayout";
-import useTagStore from "@/store/tags";
-import SortDropdown from "@/components/SortDropdown";
import { Sort, TagIncludingLinkCount, ViewMode } from "@/types/global";
-import useLinks from "@/hooks/useLinks";
-import { toast } from "react-hot-toast";
-import ViewDropdown from "@/components/ViewDropdown";
-import CardView from "@/components/LinkViews/Layouts/CardView";
-// import GridView from "@/components/LinkViews/Layouts/GridView";
-import ListView from "@/components/LinkViews/Layouts/ListView";
+import { useLinks } from "@/hooks/store/links";
import { dropdownTriggerer } from "@/lib/client/utils";
import BulkDeleteLinksModal from "@/components/ModalContent/BulkDeleteLinksModal";
import BulkEditLinksModal from "@/components/ModalContent/BulkEditLinksModal";
-import useCollectivePermissions from "@/hooks/useCollectivePermissions";
+import { useTranslation } from "next-i18next";
+import getServerSideProps from "@/lib/client/getServerSideProps";
+import LinkListOptions from "@/components/LinkListOptions";
+import { useRemoveTag, useTags, useUpdateTag } from "@/hooks/store/tags";
+import Links from "@/components/LinkViews/Links";
+import toast from "react-hot-toast";
export default function Index() {
+ const { t } = useTranslation();
const router = useRouter();
- const { links, selectedLinks, deleteLinksById, setSelectedLinks } =
- useLinkStore();
- const { tags, updateTag, removeTag } = useTagStore();
+ const { data: tags = [] } = useTags();
+ const updateTag = useUpdateTag();
+ const removeTag = useRemoveTag();
- const [sortBy, setSortBy] = useState(Sort.DateNewestFirst);
+ const [sortBy, setSortBy] = useState(
+ Number(localStorage.getItem("sortBy")) ?? Sort.DateNewestFirst
+ );
const [renameTag, setRenameTag] = useState(false);
const [newTagName, setNewTagName] = useState();
@@ -38,14 +38,13 @@ export default function Index() {
if (editMode) return setEditMode(false);
}, [router]);
- const collectivePermissions = useCollectivePermissions(
- selectedLinks.map((link) => link.collectionId as number)
- );
-
- useLinks({ tagId: Number(router.query.id), sort: sortBy });
+ const { links, data } = useLinks({
+ sort: sortBy,
+ tagId: Number(router.query.id),
+ });
useEffect(() => {
- const tag = tags.find((e) => e.id === Number(router.query.id));
+ const tag = tags.find((e: any) => e.id === Number(router.query.id));
if (tags.length > 0 && !tag?.id) {
router.push("/dashboard");
@@ -76,21 +75,28 @@ export default function Index() {
setSubmitLoader(true);
- const load = toast.loading("Applying...");
+ if (activeTag && newTagName) {
+ const load = toast.loading(t("applying_changes"));
- let response;
+ await updateTag.mutateAsync(
+ {
+ ...activeTag,
+ name: newTagName,
+ },
+ {
+ onSettled: (data, error) => {
+ toast.dismiss(load);
- if (activeTag && newTagName)
- response = await updateTag({
- ...activeTag,
- name: newTagName,
- });
+ if (error) {
+ toast.error(error.message);
+ } else {
+ toast.success(t("tag_renamed"));
+ }
+ },
+ }
+ );
+ }
- toast.dismiss(load);
-
- if (response?.ok) {
- toast.success("Tag Renamed!");
- } else toast.error(response?.data as string);
setSubmitLoader(false);
setRenameTag(false);
};
@@ -98,101 +104,74 @@ export default function Index() {
const remove = async () => {
setSubmitLoader(true);
- const load = toast.loading("Applying...");
+ if (activeTag?.id) {
+ const load = toast.loading(t("applying_changes"));
- let response;
+ await removeTag.mutateAsync(activeTag?.id, {
+ onSettled: (data, error) => {
+ toast.dismiss(load);
- if (activeTag?.id) response = await removeTag(activeTag?.id);
+ if (error) {
+ toast.error(error.message);
+ } else {
+ toast.success(t("tag_deleted"));
+ router.push("/links");
+ }
+ },
+ });
+ }
- toast.dismiss(load);
-
- if (response?.ok) {
- toast.success("Tag Removed.");
- router.push("/links");
- } else toast.error(response?.data as string);
setSubmitLoader(false);
setRenameTag(false);
};
- const handleSelectAll = () => {
- if (selectedLinks.length === links.length) {
- setSelectedLinks([]);
- } else {
- setSelectedLinks(links.map((link) => link));
- }
- };
-
- const bulkDeleteLinks = async () => {
- const load = toast.loading(
- `Deleting ${selectedLinks.length} Link${
- selectedLinks.length > 1 ? "s" : ""
- }...`
- );
-
- const response = await deleteLinksById(
- selectedLinks.map((link) => link.id as number)
- );
-
- toast.dismiss(load);
-
- response.ok &&
- toast.success(
- `Deleted ${selectedLinks.length} Link${
- selectedLinks.length > 1 ? "s" : ""
- }!`
- );
- };
-
- const [viewMode, setViewMode] = useState(
- localStorage.getItem("viewMode") || ViewMode.Card
+ const [viewMode, setViewMode] = useState(
+ (localStorage.getItem("viewMode") as ViewMode) || ViewMode.Card
);
- const linkView = {
- [ViewMode.Card]: CardView,
- // [ViewMode.Grid]: GridView,
- [ViewMode.List]: ListView,
- };
-
- // @ts-ignore
- const LinkComponent = linkView[viewMode];
-
return (
-
+
{renameTag ? (
- <>
-
- >
+
) : (
<>
-
+
{activeTag?.name}
@@ -213,7 +192,7 @@ export default function Index() {
className={"bi-three-dots text-neutral text-2xl"}
>
-
@@ -245,88 +226,14 @@ export default function Index() {
)}
+
-
-
{
- setEditMode(!editMode);
- setSelectedLinks([]);
- }}
- className={`btn btn-square btn-sm btn-ghost ${
- editMode
- ? "bg-primary/20 hover:bg-primary/20"
- : "hover:bg-neutral/20"
- }`}
- >
-
-
-
-
-
-
- {editMode && links.length > 0 && (
-
- {links.length > 0 && (
-
- handleSelectAll()}
- checked={
- selectedLinks.length === links.length && links.length > 0
- }
- />
- {selectedLinks.length > 0 ? (
-
- {selectedLinks.length}{" "}
- {selectedLinks.length === 1 ? "link" : "links"} selected
-
- ) : (
- Nothing selected
- )}
-
- )}
-
- setBulkEditLinksModal(true)}
- className="btn btn-sm btn-accent text-white w-fit ml-auto"
- disabled={
- selectedLinks.length === 0 ||
- !(
- collectivePermissions === true ||
- collectivePermissions?.canUpdate
- )
- }
- >
- Edit
-
- {
- (document?.activeElement as HTMLElement)?.blur();
- e.shiftKey
- ? bulkDeleteLinks()
- : setBulkDeleteLinksModal(true);
- }}
- className="btn btn-sm bg-red-400 border-red-400 hover:border-red-500 hover:bg-red-500 text-white w-fit ml-auto"
- disabled={
- selectedLinks.length === 0 ||
- !(
- collectivePermissions === true ||
- collectivePermissions?.canDelete
- )
- }
- >
- Delete
-
-
-
- )}
-
- e.tags.some((e) => e.id === Number(router.query.id))
- )}
+ links={links}
+ layout={viewMode}
+ placeholderCount={1}
+ useData={data}
/>
{bulkDeleteLinksModal && (
@@ -346,3 +253,5 @@ export default function Index() {
);
}
+
+export { getServerSideProps };
diff --git a/playwright.config.ts b/playwright.config.ts
index a2811c0..265a274 100644
--- a/playwright.config.ts
+++ b/playwright.config.ts
@@ -1,11 +1,8 @@
import { defineConfig, devices } from "@playwright/test";
+import path from "path";
+import "dotenv/config.js";
-/**
- * Read environment variables from file.
- * https://github.com/motdotla/dotenv
- */
-// require('dotenv').config();
-
+export const STORAGE_STATE = path.join(__dirname, "playwright/.auth/user.json");
/**
* See https://playwright.dev/docs/test-configuration.
*/
@@ -18,13 +15,13 @@ export default defineConfig({
/* Retry on CI only */
retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */
- workers: process.env.CI ? 1 : undefined,
+ workers: process.env.CI ? 1 : Number(process.env.MAX_WORKERS) || undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
reporter: "html",
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
use: {
/* Base URL to use in actions like `await page.goto('/')`. */
- // baseURL: 'http://127.0.0.1:3000',
+ baseURL: "http://127.0.0.1:3000",
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
trace: "on-first-retry",
@@ -33,10 +30,27 @@ export default defineConfig({
/* Configure projects for major browsers */
projects: [
{
- name: "chromium",
+ name: "setup dashboard",
+ testMatch: /global\/setup\.dashboard\.ts/,
+ },
+ {
+ name: "setup public",
+ testMatch: /global\/setup\.public\.ts/,
+ },
+ {
+ name: "chromium dashboard",
+ dependencies: ["setup dashboard"],
+ testMatch: "dashboard/*.spec.ts",
+ use: { ...devices["Desktop Chrome"], storageState: STORAGE_STATE },
+ },
+ {
+ name: "chromium public",
+ dependencies: ["setup public"],
+ testMatch: "public/*.spec.ts",
use: { ...devices["Desktop Chrome"] },
},
+ /*
{
name: "firefox",
use: { ...devices["Desktop Firefox"] },
@@ -46,6 +60,7 @@ export default defineConfig({
name: "webkit",
use: { ...devices["Desktop Safari"] },
},
+ */
/* Test against mobile viewports. */
// {
diff --git a/prisma/migrations/20240309180643_add_singlefile_archive_format/migration.sql b/prisma/migrations/20240309180643_add_singlefile_archive_format/migration.sql
new file mode 100644
index 0000000..07ad8a5
--- /dev/null
+++ b/prisma/migrations/20240309180643_add_singlefile_archive_format/migration.sql
@@ -0,0 +1,8 @@
+-- AlterEnum
+ALTER TYPE "LinksRouteTo" ADD VALUE 'SINGLEFILE';
+
+-- AlterTable
+ALTER TABLE "User" ADD COLUMN "archiveAsSinglefile" BOOLEAN NOT NULL DEFAULT false;
+
+-- AlterTable
+ALTER TABLE "Link" ADD COLUMN "singlefile" text;
diff --git a/prisma/migrations/20240515084924_add_unverified_new_email_field_to_user_table/migration.sql b/prisma/migrations/20240515084924_add_unverified_new_email_field_to_user_table/migration.sql
new file mode 100644
index 0000000..3f4b05f
--- /dev/null
+++ b/prisma/migrations/20240515084924_add_unverified_new_email_field_to_user_table/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "User" ADD COLUMN "unverifiedNewEmail" TEXT;
diff --git a/prisma/migrations/20240518161814_added_password_reset_token_table/migration.sql b/prisma/migrations/20240518161814_added_password_reset_token_table/migration.sql
new file mode 100644
index 0000000..80b7264
--- /dev/null
+++ b/prisma/migrations/20240518161814_added_password_reset_token_table/migration.sql
@@ -0,0 +1,11 @@
+-- CreateTable
+CREATE TABLE "PasswordResetToken" (
+ "identifier" TEXT NOT NULL,
+ "token" TEXT NOT NULL,
+ "expires" TIMESTAMP(3) NOT NULL,
+ "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP
+);
+
+-- CreateIndex
+CREATE UNIQUE INDEX "PasswordResetToken_token_key" ON "PasswordResetToken"("token");
diff --git a/prisma/migrations/20240525002215_add_default_value_to_link_name/migration.sql b/prisma/migrations/20240525002215_add_default_value_to_link_name/migration.sql
new file mode 100644
index 0000000..b91c845
--- /dev/null
+++ b/prisma/migrations/20240525002215_add_default_value_to_link_name/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "Link" ALTER COLUMN "name" SET DEFAULT '';
diff --git a/prisma/migrations/20240528194553_added_locale_field_for_users/migration.sql b/prisma/migrations/20240528194553_added_locale_field_for_users/migration.sql
new file mode 100644
index 0000000..6523faa
--- /dev/null
+++ b/prisma/migrations/20240528194553_added_locale_field_for_users/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "User" ADD COLUMN "locale" TEXT NOT NULL DEFAULT 'en';
diff --git a/prisma/migrations/20240626225737_add_new_field_to_access_tokens/migration.sql b/prisma/migrations/20240626225737_add_new_field_to_access_tokens/migration.sql
new file mode 100644
index 0000000..f502cb9
--- /dev/null
+++ b/prisma/migrations/20240626225737_add_new_field_to_access_tokens/migration.sql
@@ -0,0 +1,2 @@
+-- AlterTable
+ALTER TABLE "AccessToken" ADD COLUMN "isSession" BOOLEAN NOT NULL DEFAULT false;
diff --git a/prisma/migrations/20240628013747_rename_fields/migration.sql b/prisma/migrations/20240628013747_rename_fields/migration.sql
new file mode 100644
index 0000000..6c63edd
--- /dev/null
+++ b/prisma/migrations/20240628013747_rename_fields/migration.sql
@@ -0,0 +1,21 @@
+/*
+ Warnings:
+
+ - The values [SINGLEFILE] on the enum `LinksRouteTo` will be removed. If these variants are still used in the database, this will fail.
+ - You are about to drop the column `archiveAsSinglefile` on the `User` table. All the data in the column will be lost.
+
+*/
+-- AlterEnum
+BEGIN;
+CREATE TYPE "LinksRouteTo_new" AS ENUM ('ORIGINAL', 'PDF', 'READABLE', 'MONOLITH', 'SCREENSHOT');
+ALTER TABLE "User" ALTER COLUMN "linksRouteTo" DROP DEFAULT;
+ALTER TABLE "User" ALTER COLUMN "linksRouteTo" TYPE "LinksRouteTo_new" USING ("linksRouteTo"::text::"LinksRouteTo_new");
+ALTER TYPE "LinksRouteTo" RENAME TO "LinksRouteTo_old";
+ALTER TYPE "LinksRouteTo_new" RENAME TO "LinksRouteTo";
+DROP TYPE "LinksRouteTo_old";
+ALTER TABLE "User" ALTER COLUMN "linksRouteTo" SET DEFAULT 'ORIGINAL';
+COMMIT;
+
+-- AlterTable
+ALTER TABLE "User" DROP COLUMN "archiveAsSinglefile",
+ADD COLUMN "archiveAsMonolith" BOOLEAN NOT NULL DEFAULT true;
diff --git a/prisma/migrations/20240628014129_rename_field/migration.sql b/prisma/migrations/20240628014129_rename_field/migration.sql
new file mode 100644
index 0000000..d6336e8
--- /dev/null
+++ b/prisma/migrations/20240628014129_rename_field/migration.sql
@@ -0,0 +1,9 @@
+/*
+ Warnings:
+
+ - You are about to drop the column `singlefile` on the `Link` table. All the data in the column will be lost.
+
+*/
+-- AlterTable
+ALTER TABLE "Link" DROP COLUMN "singlefile",
+ADD COLUMN "monolith" TEXT;
diff --git a/prisma/migrations/20240819003838_add_icon_related_fields_to_link_and_collection_model/migration.sql b/prisma/migrations/20240819003838_add_icon_related_fields_to_link_and_collection_model/migration.sql
new file mode 100644
index 0000000..e208342
--- /dev/null
+++ b/prisma/migrations/20240819003838_add_icon_related_fields_to_link_and_collection_model/migration.sql
@@ -0,0 +1,8 @@
+-- AlterTable
+ALTER TABLE "Collection" ADD COLUMN "icon" TEXT,
+ADD COLUMN "iconWeight" TEXT;
+
+-- AlterTable
+ALTER TABLE "Link" ADD COLUMN "color" TEXT,
+ADD COLUMN "icon" TEXT,
+ADD COLUMN "iconWeight" TEXT;
diff --git a/prisma/migrations/20240819005010_remove_collection_model_default_color/migration.sql b/prisma/migrations/20240819005010_remove_collection_model_default_color/migration.sql
new file mode 100644
index 0000000..199e104
--- /dev/null
+++ b/prisma/migrations/20240819005010_remove_collection_model_default_color/migration.sql
@@ -0,0 +1,3 @@
+-- AlterTable
+ALTER TABLE "Collection" ALTER COLUMN "color" DROP NOT NULL,
+ALTER COLUMN "color" DROP DEFAULT;
diff --git a/prisma/migrations/20240820230618_add_default_value_for_collection_color/migration.sql b/prisma/migrations/20240820230618_add_default_value_for_collection_color/migration.sql
new file mode 100644
index 0000000..f634b68
--- /dev/null
+++ b/prisma/migrations/20240820230618_add_default_value_for_collection_color/migration.sql
@@ -0,0 +1,9 @@
+/*
+ Warnings:
+
+ - Made the column `color` on table `Collection` required. This step will fail if there are existing NULL values in that column.
+
+*/
+-- AlterTable
+ALTER TABLE "Collection" ALTER COLUMN "color" SET NOT NULL,
+ALTER COLUMN "color" SET DEFAULT '#0ea5e9';
diff --git a/prisma/schema.prisma b/prisma/schema.prisma
index 8dba77b..8bd89eb 100644
--- a/prisma/schema.prisma
+++ b/prisma/schema.prisma
@@ -31,20 +31,23 @@ model User {
username String? @unique
email String? @unique
emailVerified DateTime?
+ unverifiedNewEmail String?
image String?
- accounts Account[]
password String?
+ locale String @default("en")
+ accounts Account[]
collections Collection[]
tags Tag[]
pinnedLinks Link[]
collectionsJoined UsersAndCollections[]
- collectionOrder Int[] @default([])
+ collectionOrder Int[] @default([])
whitelistedUsers WhitelistedUser[]
accessTokens AccessToken[]
subscriptions Subscription?
linksRouteTo LinksRouteTo @default(ORIGINAL)
preventDuplicateLinks Boolean @default(false)
archiveAsScreenshot Boolean @default(true)
+ archiveAsMonolith Boolean @default(true)
archiveAsPDF Boolean @default(true)
archiveAsWaybackMachine Boolean @default(false)
isPrivate Boolean @default(false)
@@ -56,6 +59,7 @@ enum LinksRouteTo {
ORIGINAL
PDF
READABLE
+ MONOLITH
SCREENSHOT
}
@@ -78,10 +82,20 @@ model VerificationToken {
@@unique([identifier, token])
}
+model PasswordResetToken {
+ identifier String
+ token String @unique
+ expires DateTime
+ createdAt DateTime @default(now())
+ updatedAt DateTime @default(now()) @updatedAt
+}
+
model Collection {
id Int @id @default(autoincrement())
name String
description String @default("")
+ icon String?
+ iconWeight String?
color String @default("#0ea5e9")
parentId Int?
parent Collection? @relation("SubCollections", fields: [parentId], references: [id])
@@ -115,19 +129,23 @@ model UsersAndCollections {
model Link {
id Int @id @default(autoincrement())
- name String
+ name String @default("")
type String @default("url")
description String @default("")
pinnedBy User[]
collection Collection @relation(fields: [collectionId], references: [id])
collectionId Int
tags Tag[]
+ icon String?
+ iconWeight String?
+ color String?
url String?
textContent String?
preview String?
image String?
pdf String?
readable String?
+ monolith String?
lastPreserved DateTime?
importDate DateTime?
createdAt DateTime @default(now())
@@ -166,6 +184,7 @@ model AccessToken {
userId Int
token String @unique
revoked Boolean @default(false)
+ isSession Boolean @default(false)
expires DateTime
lastUsedAt DateTime?
createdAt DateTime @default(now())
diff --git a/public/locales/de/common.json b/public/locales/de/common.json
new file mode 100644
index 0000000..48ba585
--- /dev/null
+++ b/public/locales/de/common.json
@@ -0,0 +1,375 @@
+{
+ "user_administration": "Benutzer Administration",
+ "search_users": "Suche nach Benutzern",
+ "no_users_found": "Keine Benutzer gefunden.",
+ "no_user_found_in_search": "Keine Benutzer mit den angegebenen Suchparametern gefunden.",
+ "username": "Benutzername",
+ "email": "E-Mail",
+ "subscribed": "Abonniert",
+ "created_at": "Erstellt am",
+ "not_available": "N/A",
+ "check_your_email": "Bitte E-Mail prüfen.",
+ "authenticating": "Verifizieren...",
+ "verification_email_sent": "Verifizierungs E-Mail gesendet.",
+ "verification_email_sent_desc": "Ein Anmeldelink wurde per E-Mail versendet. Bitte auch den Spam-Ordner prüfen.",
+ "resend_email": "E-Mail erneut senden",
+ "invalid_credentials": "Ungültige Anmeldedaten.",
+ "fill_all_fields": "Bitte alle Felder ausfüllen.",
+ "enter_credentials": "Anmeldedaten eingeben",
+ "username_or_email": "Benutzername oder E-Mail",
+ "password": "Passwort",
+ "confirm_password": "Passwort bestätigen",
+ "forgot_password": "Passwort vergessen?",
+ "login": "Login",
+ "or_continue_with": "Oder fortfahren mit",
+ "new_here": "Neu hier?",
+ "sign_up": "Registrieren",
+ "sign_in_to_your_account": "Bei Ihrem Konto anmelden",
+ "dashboard_desc": "Ein kurzer Überblick über Ihre Daten",
+ "link": "Link",
+ "links": "Links",
+ "collection": "Sammlung",
+ "collections": "Sammlungen",
+ "tag": "Tag",
+ "tags": "Tags",
+ "recent": "Neueste",
+ "recent_links_desc": "Kürzlich hinzugefügte Links",
+ "view_all": "Alle anzeigen",
+ "view_added_links_here": "Sehen Sie hier Ihre kürzlich hinzugefügten Links!",
+ "view_added_links_here_desc": "In diesem Bereich werden Ihre zuletzt hinzugefügten Links in allen Sammlungen, auf die Sie Zugriff haben, angezeigt.",
+ "add_link": "Neuen Link hinzufügen",
+ "import_links": "Links importieren",
+ "from_linkwarden": "Von Linkwarden",
+ "from_html": "Von Lesezeichen HTML-Datei",
+ "from_wallabag": "Von Wallabag (JSON-Datei)",
+ "pinned": "Angepinnt",
+ "pinned_links_desc": "Deine angepinnten Links",
+ "pin_favorite_links_here": "Pin deine Favoriten-Links hier!",
+ "pin_favorite_links_here_desc": "Du kannst deine Lieblingslinks anheften, indem du auf die drei Punkte auf jedem Link klickst und dann auf An Dashboard anheften.",
+ "sending_password_link": "Link zur Wiederherstellung des Passworts senden...",
+ "password_email_prompt": "Gib deine E-Mail-Adresse ein, damit wir dir einen Link schicken können, um ein neues Passwort zu erstellen.",
+ "send_reset_link": "Link zum Zurücksetzen senden",
+ "reset_email_sent_desc": "Prüfe deine E-Mail auf einen Link zum Zurücksetzen deines Passworts. Wenn er nicht innerhalb weniger Minuten erscheint, prüfe deinen Spam-Ordner.",
+ "back_to_login": "Zurück zum Login",
+ "email_sent": "E-Mail gesendet!",
+ "passwords_mismatch": "Passwörter stimmen nicht überein.",
+ "password_too_short": "Passwort muss mindestens 8 Zeichen haben.",
+ "creating_account": "Erstelle Account...",
+ "account_created": "Account erstellt!",
+ "trial_offer_desc": "Schalte {{count}} Tage Premium Service kostenlos frei!",
+ "register_desc": "Neuen Account erstellen",
+ "registration_disabled_desc": "Die Registrierung ist für diese Instanz deaktiviert. Bei Problemen wende dich bitte an den Administrator.",
+ "enter_details": "Details eingeben",
+ "display_name": "Anzeigename",
+ "sign_up_agreement": "Mit der Anmeldung stimmst du unseren <0>Nutzungsbedingungen0> und <1>Datenschutzbedingungen1> zu.",
+ "need_help": "Hilfe benötigt?",
+ "get_in_touch": "Kontakt aufnehmen",
+ "already_registered": "Du hast bereits einen Account?",
+ "deleting_selections": "Lösche Auswahl...",
+ "links_deleted": "{{count}} Links gelöscht.",
+ "link_deleted": "1 Link gelöscht.",
+ "links_selected": "{{count}} Links ausgewählt",
+ "link_selected": "1 Link ausgewählt",
+ "nothing_selected": "Nichts ausgewählt",
+ "edit": "Bearbeiten",
+ "delete": "Löschen",
+ "nothing_found": "Nichts gefunden.",
+ "redirecting_to_stripe": "Weiterleitung zu Stripe...",
+ "subscribe_title": "Linkwarden abonnieren!",
+ "subscribe_desc": "Sie werden zu Stripe weitergeleitet, bei Problemen kontaktiere uns bitte unter <0>support@linkwarden.app0>.",
+ "monthly": "Monatlich",
+ "yearly": "Jährlich",
+ "discount_percent": "{{percent}}% Rabatt",
+ "billed_monthly": "Monatliche Abrechnung",
+ "billed_yearly": "Jährliche Abrechnung",
+ "total": "Gesamt",
+ "total_annual_desc": "{{count}}-Tage kostenlos testen, dann ${{annualPrice}} Jährlich",
+ "total_monthly_desc": "{{count}}-Tage kostenlos testen, dann ${{monthlyPrice}} monatlich",
+ "plus_tax": "+ Mehrwertsteuer, falls zutreffend",
+ "complete_subscription": "Abonnement abschließen",
+ "sign_out": "Abmelden",
+ "access_tokens": "Zugangstokens",
+ "access_tokens_description": "Zugangstoken können verwendet werden, um von anderen Anwendungen und Diensten aus auf Linkwarden zuzugreifen, ohne Benutzername und Passwort anzugeben.",
+ "new_token": "Neuer Zugangstoken",
+ "name": "Name",
+ "created_success": "Erstellt!",
+ "created": "Erstellt",
+ "expires": "Läuft ab",
+ "accountSettings": "Account Einstellungen",
+ "language": "Sprache",
+ "profile_photo": "Profilbild",
+ "upload_new_photo": "Neues Foto hochladen...",
+ "remove_photo": "Foto löschen",
+ "make_profile_private": "Profil privat machen",
+ "profile_privacy_info": "Hier wird eingeschränkt, wer dich finden und zu neuen Sammlungen hinzufügen kann.",
+ "whitelisted_users": "Benutzer auf der Whitelist",
+ "whitelisted_users_info": "Bitte gib den Benutzernamen der Benutzer an, denen du Sichtbarkeit für dein Profil gewähren möchtest. Getrennt durch Komma.",
+ "whitelisted_users_placeholder": "Dein Profil ist im Moment für alle versteckt...",
+ "save_changes": "Änderungen speichern",
+ "import_export": "Import & Export",
+ "import_data": "Importiere Deine Daten von anderen Plattformen.",
+ "download_data": "Lade deine Daten sofort herunter.",
+ "export_data": "Exportiere Daten",
+ "delete_account": "Account löschen",
+ "delete_account_warning": "Dadurch werden ALLE Links, Sammlungen, Tags und archivierten Daten, die Du besitzt, endgültig gelöscht.",
+ "cancel_subscription_notice": "Es wird auch dein Abonnement kündigen.",
+ "account_deletion_page": "Seite zur Account-Löschung",
+ "applying_settings": "Einstellungen übernehmen...",
+ "settings_applied": "Einstellungen übernommen!",
+ "email_change_request": "E-Mail-Änderungsanfrage gesendet. Bitte bestätige die neue E-Mail-Adresse.",
+ "image_upload_size_error": "Bitte wähle eine PNG- oder JPEG-Datei, die kleiner als 1 MB ist.",
+ "image_upload_format_error": "Ungültiges Dateiformat",
+ "importing_bookmarks": "Importiere Lesezeichen...",
+ "import_success": "Lesezeichen importiert! Seite neu laden...",
+ "more_coming_soon": "Demnächst mehr!",
+ "billing_settings": "Rechnungs-Einstellungen",
+ "manage_subscription_intro": "Um dein Abonnement zu verwalten/kündigen, besuche das",
+ "billing_portal": "Abrechnungsportal",
+ "help_contact_intro": "Wenn du noch Hilfe brauchst oder ein Problem hast, kannst du dich gerne an uns wenden:",
+ "fill_required_fields": "Bitte fülle die erforderlichen Felder aus.",
+ "deleting_message": "Alles löschen, bitte warten...",
+ "delete_warning": "Dadurch werden alle Links, Sammlungen, Tags und archivierten Daten, die du besitzt, dauerhaft gelöscht. Außerdem wirst du abgemeldet. Diese Aktion ist unwiderruflich!",
+ "optional": "Optional",
+ "feedback_help": "(aber es hilft uns wirklich, besser zu werden!)",
+ "reason_for_cancellation": "Grund für die Kündigung",
+ "please_specify": "Bitte angeben",
+ "customer_service": "Kundenservice",
+ "low_quality": "Geringe Qualität",
+ "missing_features": "Fehlende Funktionen",
+ "switched_service": "Anbieterwechsel",
+ "too_complex": "Zu kompliziert",
+ "too_expensive": "Zu teuer",
+ "unused": "Nicht benutzt",
+ "other": "Sonstiges",
+ "more_information": "Weitere Informationen (je mehr Details, desto hilfreicher wäre es)",
+ "feedback_placeholder": "Ich benötigte z. B. eine Funktion, die...",
+ "delete_your_account": "Dein Konto löschen",
+ "change_password": "Passwort wechseln",
+ "password_length_error": "Passwörter müssen mindestens 8 Zeichen lang sein.",
+ "applying_changes": "Übernehmen...",
+ "password_change_instructions": "Um das Passwort zu ändern, fülle bitte das folgende Formular aus. Das Passwort sollte mindestens 8 Zeichen lang sein.",
+ "old_password": "Altes Passwort",
+ "new_password": "Neues Passwort",
+ "preference": "Darstellung",
+ "select_theme": "Theme auswählen",
+ "dark": "Dunkel",
+ "light": "Hell",
+ "archive_settings": "Archiv Einstellungen",
+ "formats_to_archive": "Format zum Archivieren/Aufbewahren von Webseiten:",
+ "screenshot": "Screenshot",
+ "pdf": "PDF",
+ "archive_org_snapshot": "Archive.org Snapshot",
+ "link_settings": "Link Einstellungen",
+ "prevent_duplicate_links": "Doppelte Links verhindern",
+ "clicking_on_links_should": "Das Anklicken von Links soll:",
+ "open_original_content": "Den Original-Inhalt öffnen",
+ "open_pdf_if_available": "Das PDF öffnen, wenn verfügbar",
+ "open_readable_if_available": "Lesenansicht öffnen, falls verfügbar",
+ "open_screenshot_if_available": "Screenshot anzeigen, falls verfügbar",
+ "open_webpage_if_available": "Webseiten-Kopie öffnen, falls verfügbar",
+ "tag_renamed": "Tag umbenannt!",
+ "tag_deleted": "Tag gelöscht!",
+ "rename_tag": "Tag umbenennen",
+ "delete_tag": "Tag löschen",
+ "list_created_with_linkwarden": "Liste erstellt mit Linkwarden",
+ "by_author": "Von {{author}}.",
+ "by_author_and_other": "Von {{author}} und {{count}} anderem.",
+ "by_author_and_others": "Von {{author}} und {{count}} anderen.",
+ "search_count_link": "Durchsuche {{count}} Link",
+ "search_count_links": "Durchsuche {{count}} Links",
+ "collection_is_empty": "Diese Sammlung ist leer...",
+ "all_links": "Alle Links",
+ "all_links_desc": "Links aus allen Sammlungen",
+ "you_have_not_added_any_links": "Du hast noch keine Links erstellt",
+ "collections_you_own": "Deine Sammlungen",
+ "new_collection": "Neue Sammlung",
+ "other_collections": "Andere Sammlung",
+ "other_collections_desc": "Gemeinsame Sammlungen, bei denen du Mitglied bist",
+ "showing_count_results": "Zeige {{count}} Ergebnisse",
+ "showing_count_result": "Zeige {{count}} Ergebnis",
+ "edit_collection_info": "Sammlungsinformationen bearbeiten",
+ "share_and_collaborate": "Teilen und Zusammenarbeiten",
+ "view_team": "Team ansehen",
+ "team": "Team",
+ "create_subcollection": "Untersammlung erstellen",
+ "delete_collection": "Lösche Sammlung",
+ "leave_collection": "Verlasse Sammlung",
+ "email_verified_signing_out": "E-Mail verifiziert. Abmelden...",
+ "invalid_token": "Ungültiger Token.",
+ "sending_password_recovery_link": "Passwort-Wiederherstellungslink senden...",
+ "please_fill_all_fields": "Bitte alle Felder ausfüllen.",
+ "password_updated": "Passwort aktualisiert!",
+ "reset_password": "Passwort zurücksetzen",
+ "enter_email_for_new_password": "Bitte fülle deine E-Mail-Adresse aus, damit wir dir einen Link schicken können, um ein neues Passwort zu erstellen.",
+ "update_password": "Aktualisiere Passwort",
+ "password_successfully_updated": "Dein Passwort wurde erfolgreich aktualisiert.",
+ "user_already_member": "Benutzer existiert bereits.",
+ "you_are_already_collection_owner": "Du bist bereits der Eigentümer der Sammlung.",
+ "date_newest_first": "Datum (Neueste zuerst)",
+ "date_oldest_first": "Datum (Älteste zuerst)",
+ "name_az": "Name (A-Z)",
+ "name_za": "Name (Z-A)",
+ "description_az": "Beschreibung (A-Z)",
+ "description_za": "Beschreibung (Z-A)",
+ "all_rights_reserved": "© {{date}} <0>Linkwarden0>. Alle Rechte vorbehalten.",
+ "you_have_no_collections": "Du hast keine Sammlungen...",
+ "you_have_no_tags": "Du hast keine Tags...",
+ "cant_change_collection_you_dont_own": "Du kannst keine Änderungen an einer Sammlung vornehmen, die du nicht besitzt.",
+ "account": "Account",
+ "billing": "Abrechnung",
+ "linkwarden_version": "Linkwarden {{version}}",
+ "help": "Hilfe",
+ "github": "GitHub",
+ "twitter": "Twitter",
+ "mastodon": "Mastodon",
+ "link_preservation_in_queue": "Die Link- Konservierung ist derzeit in der Warteschlange",
+ "check_back_later": "Bitte überprüfen das Ergebnis zu einem späteren Zeitpunkt",
+ "there_are_more_formats": "Es gibt noch mehr konservierte Formate in der Warteschlange",
+ "settings": "Einstellungen",
+ "switch_to": "Wechsle zu {{theme}}",
+ "logout": "Abmelden",
+ "start_journey": "Starte deine Reise, indem du einen neuen Link anlegst!",
+ "create_new_link": "Neuen Link anlegen",
+ "new_link": "Neuer Link",
+ "create_new": "Neu anlegen...",
+ "pwa_install_prompt": "Installiere Linkwarden auf deinem Startbildschirm für einen schnelleren Zugriff und ein besseres Erlebnis. <0>Mehr erfahren0>",
+ "full_content": "Vollständiger Inhalt",
+ "slower": "Langsamer",
+ "new_version_announcement": "Schau, was neu ist in <0>Linkwarden {{Version}}!0>",
+ "creating": "Erstellen...",
+ "upload_file": "Datei hochladen",
+ "file": "Datei",
+ "file_types": "PDF, PNG, JPG (Maximalgröße {{size}} MB)",
+ "description": "Beschreibung",
+ "auto_generated": "Wird automatisch generiert, wenn nichts angegeben wird.",
+ "example_link": "z.B. Beispiel-Link",
+ "hide": "Verstecken",
+ "more": "Mehr",
+ "options": "Optionen",
+ "description_placeholder": "Notizen, Gedanken, usw.",
+ "deleting": "Lösche...",
+ "token_revoked": "Token widerrufen.",
+ "revoke_token": "Token widerrufen",
+ "revoke_confirmation": "Bist du sicher, dass du dieses Zugangs-Token widerrufen möchtest? Alle Anwendungen oder Dienste, die dieses Token verwenden, können dann nicht mehr auf Linkwarden zugreifen.",
+ "revoke": "Widerrufen",
+ "sending_request": "Anfrage senden...",
+ "link_being_archived": "Link wird archiviert...",
+ "preserved_formats": "Konservierte Formate",
+ "available_formats": "Die folgenden Formate sind für diesen Link verfügbar:",
+ "readable": "Leseansicht",
+ "preservation_in_queue": "Linkkonservierung ist in der Warteschlange",
+ "view_latest_snapshot": "Aktuellen Schnappschuss auf archive.org ansehen",
+ "refresh_preserved_formats": "Konservierte Formate aktualisieren",
+ "this_deletes_current_preservations": "Dies löscht die aktuellen Konservierungen",
+ "create_new_user": "Neuen Benutzer erstellen",
+ "placeholder_johnny": "Johnny",
+ "placeholder_email": "johnny@example.com",
+ "placeholder_john": "john",
+ "user_created": "Benutzer erstellt!",
+ "fill_all_fields_error": "Bitte alle Felder ausfüllen.",
+ "password_change_note": "<0>Hinweis:0> Bitte informiere den Benutzer, dass er sein Passwort ändern muss.",
+ "create_user": "Benutzer erstellen",
+ "creating_token": "Token anlegen...",
+ "token_created": "Token erstellt!",
+ "access_token_created": "Zugangstoken erstellt",
+ "token_creation_notice": "Der neue Token wurde erstellt. Bitte kopiere ihn und bewahre ihn an einem sicheren Ort auf. Er wird nicht mehr zu sehen sein.",
+ "copied_to_clipboard": "In die Zwischenablage kopiert!",
+ "copy_to_clipboard": "Kopieren in Zwischenablage",
+ "create_access_token": "Zugangs-Token erstellen",
+ "expires_in": "Läuft ab in",
+ "token_name_placeholder": "z. B. für die iOS-Verknüpfung",
+ "create_token": "Zugangs-Token erstellen",
+ "7_days": "7 Tage",
+ "30_days": "30 Tage",
+ "60_days": "60 Tage",
+ "90_days": "90 Tage",
+ "no_expiration": "Kein Ablaufdatum",
+ "creating_link": "Link anlegen...",
+ "link_created": "Link angelegt!",
+ "link_name_placeholder": "Wird automatisch generiert, wenn nicht angegeben.",
+ "link_url_placeholder": "z.B. http://example.com/",
+ "link_description_placeholder": "Notizen, Gedanken, usw.",
+ "more_options": "Mehr Optionen",
+ "hide_options": "Optionen ausblenden",
+ "create_link": "Link erstellen",
+ "new_sub_collection": "Neue Untersammlung",
+ "for_collection": "Für {{name}}",
+ "create_new_collection": "Neue Sammlung erstellen",
+ "color": "Farbe",
+ "reset": "Zurücksetzen",
+ "updating_collection": "Aktualisiere Sammlung...",
+ "collection_name_placeholder": "z.B. Beispiel Sammlung",
+ "collection_description_placeholder": "Zweck dieser Sammlung...",
+ "create_collection_button": "Sammlung erstellen",
+ "password_change_warning": "Bitte bestätige dein Passwort, bevor du deine E-Mail Adresse änderst.",
+ "stripe_update_note": " Wenn Du dieses Feld aktualisierst, wird auch Deine Rechnungs-E-Mail auf Stripe geändert.",
+ "sso_will_be_removed_warning": "Wenn Du deine E-Mail-Adresse änderst, werden alle bestehenden {{service}} SSO-Verbindungen entfernt werden.",
+ "old_email": "Alte E-Mail",
+ "new_email": "Neue E-Mail",
+ "confirm": "Bestätigen",
+ "edit_link": "Link bearbeiten",
+ "updating": "Aktualisiere...",
+ "updated": "Aktualisiert!",
+ "placeholder_example_link": "z.B. Beispiel-Link",
+ "make_collection_public": "Sammlung veröffentlichen",
+ "make_collection_public_checkbox": "Diese Sammlung öffentlich machen",
+ "make_collection_public_desc": "So kann jeder diese Sammlung und ihre Nutzer einsehen.",
+ "sharable_link_guide": "Link zum Teilen (Zum Kopieren anklicken)",
+ "copied": "Kopiert!",
+ "members": "Mitglieder",
+ "members_username_placeholder": "Benutzername (ohne '@')",
+ "owner": "Besitzer",
+ "admin": "Admin",
+ "contributor": "Mitwirkende",
+ "viewer": "Leser",
+ "viewer_desc": "Schreibgeschützter Zugriff",
+ "contributor_desc": "Kann Links anzeigen und erstellen",
+ "admin_desc": "Voller Zugriff auf alle Links",
+ "remove_member": "Mitglied entfernen",
+ "placeholder_example_collection": "z. B. Beispiel Sammlung",
+ "placeholder_collection_purpose": "Zweck dieser Sammlung...",
+ "deleting_user": "Lösche...",
+ "user_deleted": "Benutzer entfernt.",
+ "delete_user": "Benutzer entfernen",
+ "confirm_user_deletion": "Bist du sicher, dass du diesen Benutzer entfernen möchtest?",
+ "irreversible_action_warning": "Diese Maßnahme ist nicht umkehrbar!",
+ "delete_confirmation": "Löschen, ich weiß, was ich tue",
+ "delete_link": "Link entfernen",
+ "deleted": "Entfernt.",
+ "link_deletion_confirmation_message": "Bist du sicher, dass du diesen Link entfernen möchtest?",
+ "warning": "Warnung",
+ "irreversible_warning": "Diese Aktion ist nicht umkehrbar!",
+ "shift_key_tip": "Halte die Umschalttaste gedrückt, während du auf „Löschen“ klickst, um diese Bestätigung in Zukunft zu umgehen.",
+ "deleting_collection": "Lösche...",
+ "collection_deleted": "Sammlung gelöscht.",
+ "confirm_deletion_prompt": "Zur Bestätigung tippe „{{Name}}“ in das Feld unten:",
+ "type_name_placeholder": "Tippe „{{Name}}“ hier.",
+ "deletion_warning": "Wenn Du diese Sammlung löschst, wird ihr gesamter Inhalt unwiderruflich gelöscht und sie wird für jeden unzugänglich, auch für Mitglieder mit vorherigem Zugriff.",
+ "leave_prompt": "Klicke auf die Schaltfläche unten, um die aktuelle Sammlung zu verlassen.",
+ "leave": "Verlassen",
+ "edit_links": "Bearbeite {{count}} Links",
+ "move_to_collection": "Zur Sammlung verschieben",
+ "add_tags": "Tags hinzufügen",
+ "remove_previous_tags": "Vorherige Tags entfernen",
+ "delete_links": "Lösche {{count}} Links",
+ "links_deletion_confirmation_message": "Willst du wirklich {{count}} Links löschen? ",
+ "warning_irreversible": "Warnung: Diese Aktion ist unumkehrbar!",
+ "shift_key_instruction": "Halte die Umschalttaste gedrückt, während du auf „Löschen“ klickst, um diese Bestätigung in Zukunft zu umgehen.",
+ "link_selection_error": "Du hast nicht die Berechtigung, diesen Inhalt zu bearbeiten oder zu löschen.",
+ "no_description": "Keine Beschreibung vorhanden.",
+ "applying": "Übernehme...",
+ "unpin": "Abheften",
+ "pin_to_dashboard": "An das Dashboard anheften",
+ "show_link_details": "Linkdetails anzeigen",
+ "hide_link_details": "Linkdetails ausblenden",
+ "link_pinned": "Link angeheftet!",
+ "link_unpinned": "Link abhgeheftet!",
+ "webpage": "Webseite",
+ "server_administration": "Server-Verwaltung",
+ "all_collections": "Alle Sammlungen",
+ "dashboard": "Dashboard",
+ "demo_title": "Nur Demo",
+ "demo_desc": "Dies ist nur eine Demo-Instanz von Linkwarden und Uploads sind deaktiviert.",
+ "demo_desc_2": "Wenn Du die Vollversion ausprobieren möchtest, kannst Du Dich für eine kostenlose Testversion anmelden unter:",
+ "demo_button": "Login als Demo-Benutzer"
+}
\ No newline at end of file
diff --git a/public/locales/en/common.json b/public/locales/en/common.json
new file mode 100644
index 0000000..f717bf7
--- /dev/null
+++ b/public/locales/en/common.json
@@ -0,0 +1,400 @@
+{
+ "user_administration": "User Administration",
+ "search_users": "Search for Users",
+ "no_users_found": "No users found.",
+ "no_user_found_in_search": "No users found with the given search query.",
+ "username": "Username",
+ "email": "Email",
+ "subscribed": "Subscribed",
+ "created_at": "Created At",
+ "not_available": "N/A",
+ "check_your_email": "Please check your Email",
+ "authenticating": "Authenticating...",
+ "verification_email_sent": "Verification email sent.",
+ "verification_email_sent_desc": "A sign in link has been sent to your email address. If you don't see the email, check your spam folder.",
+ "resend_email": "Resend Email",
+ "invalid_credentials": "Invalid credentials.",
+ "fill_all_fields": "Please fill out all the fields.",
+ "enter_credentials": "Enter your credentials",
+ "username_or_email": "Username or Email",
+ "password": "Password",
+ "confirm_password": "Confirm Password",
+ "forgot_password": "Forgot Password?",
+ "login": "Login",
+ "or_continue_with": "Or continue with",
+ "new_here": "New here?",
+ "sign_up": "Sign Up",
+ "sign_in_to_your_account": "Sign in to your account",
+ "dashboard_desc": "A brief overview of your data",
+ "link": "Link",
+ "links": "Links",
+ "collection": "Collection",
+ "collections": "Collections",
+ "tag": "Tag",
+ "tags": "Tags",
+ "recent": "Recent",
+ "recent_links_desc": "Recently added Links",
+ "view_all": "View All",
+ "view_added_links_here": "View Your Recently Added Links Here!",
+ "view_added_links_here_desc": "This section will view your latest added Links across every Collections you have access to.",
+ "add_link": "Add New Link",
+ "import_links": "Import Links",
+ "from_linkwarden": "From Linkwarden",
+ "from_html": "From Bookmarks HTML file",
+ "from_wallabag": "From Wallabag (JSON file)",
+ "pinned": "Pinned",
+ "pinned_links_desc": "Your pinned Links",
+ "pin_favorite_links_here": "Pin Your Favorite Links Here!",
+ "pin_favorite_links_here_desc": "You can Pin your favorite Links by clicking on the three dots on each Link and clicking Pin to Dashboard.",
+ "sending_password_link": "Sending password recovery link...",
+ "password_email_prompt": "Enter your email so we can send you a link to create a new password.",
+ "send_reset_link": "Send Reset Link",
+ "reset_email_sent_desc": "Check your email for a link to reset your password. If it doesn’t appear within a few minutes, check your spam folder.",
+ "back_to_login": "Back to Login",
+ "email_sent": "Email Sent!",
+ "passwords_mismatch": "Passwords do not match.",
+ "password_too_short": "Passwords must be at least 8 characters.",
+ "creating_account": "Creating Account...",
+ "account_created": "Account Created!",
+ "trial_offer_desc": "Unlock {{count}} days of Premium Service at no cost!",
+ "register_desc": "Create a new account",
+ "registration_disabled_desc": "Registration is disabled for this instance, please contact the admin in case of any issues.",
+ "enter_details": "Enter your details",
+ "display_name": "Display Name",
+ "sign_up_agreement": "By signing up, you agree to our <0>Terms of Service0> and <1>Privacy Policy1>.",
+ "need_help": "Need help?",
+ "get_in_touch": "Get in touch",
+ "already_registered": "Already have an account?",
+ "deleting_selections": "Deleting selections...",
+ "links_deleted": "{{count}} Links deleted.",
+ "link_deleted": "1 Link deleted.",
+ "links_selected": "{{count}} Links selected",
+ "link_selected": "1 Link selected",
+ "nothing_selected": "Nothing selected",
+ "edit": "Edit",
+ "delete": "Delete",
+ "nothing_found": "Nothing found.",
+ "redirecting_to_stripe": "Redirecting to Stripe...",
+ "subscribe_title": "Subscribe to Linkwarden!",
+ "subscribe_desc": "You will be redirected to Stripe, feel free to reach out to us at <0>support@linkwarden.app0> in case of any issue.",
+ "monthly": "Monthly",
+ "yearly": "Yearly",
+ "discount_percent": "{{percent}}% Off",
+ "billed_monthly": "Billed Monthly",
+ "billed_yearly": "Billed Yearly",
+ "total": "Total",
+ "total_annual_desc": "{{count}}-day free trial, then ${{annualPrice}} annually",
+ "total_monthly_desc": "{{count}}-day free trial, then ${{monthlyPrice}} per month",
+ "plus_tax": "+ VAT if applicable",
+ "complete_subscription": "Complete Subscription",
+ "sign_out": "Sign Out",
+ "access_tokens": "Access Tokens",
+ "access_tokens_description": "Access Tokens can be used to access Linkwarden from other apps and services without giving away your Username and Password.",
+ "new_token": "New Access Token",
+ "name": "Name",
+ "created_success": "Created!",
+ "created": "Created",
+ "expires": "Expires",
+ "accountSettings": "Account Settings",
+ "language": "Language",
+ "profile_photo": "Profile Photo",
+ "upload_new_photo": "Upload a new photo...",
+ "remove_photo": "Remove Photo",
+ "make_profile_private": "Make profile private",
+ "profile_privacy_info": "This will limit who can find and add you to new Collections.",
+ "whitelisted_users": "Whitelisted Users",
+ "whitelisted_users_info": "Please provide the Username of the users you wish to grant visibility to your profile. Separated by comma.",
+ "whitelisted_users_placeholder": "Your profile is hidden from everyone right now...",
+ "save_changes": "Save Changes",
+ "import_export": "Import & Export",
+ "import_data": "Import your data from other platforms.",
+ "download_data": "Download your data instantly.",
+ "export_data": "Export Data",
+ "delete_account": "Delete Account",
+ "delete_account_warning": "This will permanently delete ALL the Links, Collections, Tags, and archived data you own.",
+ "cancel_subscription_notice": "It will also cancel your subscription.",
+ "account_deletion_page": "Account deletion page",
+ "applying_settings": "Applying settings...",
+ "settings_applied": "Settings Applied!",
+ "email_change_request": "Email change request sent. Please verify the new email address.",
+ "image_upload_no_file_error": "No file selected. Please choose an image to upload.",
+ "image_upload_size_error": "Please select a PNG or JPEG file that's less than 1MB.",
+ "image_upload_format_error": "Invalid file format.",
+ "importing_bookmarks": "Importing bookmarks...",
+ "import_success": "Imported the bookmarks! Reloading the page...",
+ "more_coming_soon": "More coming soon!",
+ "billing_settings": "Billing Settings",
+ "manage_subscription_intro": "To manage/cancel your subscription, visit the",
+ "billing_portal": "Billing Portal",
+ "help_contact_intro": "If you still need help or encountered any issues, feel free to reach out to us at:",
+ "fill_required_fields": "Please fill the required fields.",
+ "deleting_message": "Deleting everything, please wait...",
+ "delete_warning": "This will permanently delete all the Links, Collections, Tags, and archived data you own. It will also log you out. This action is irreversible!",
+ "optional": "Optional",
+ "feedback_help": "(but it really helps us improve!)",
+ "reason_for_cancellation": "Reason for cancellation",
+ "please_specify": "Please specify",
+ "customer_service": "Customer Service",
+ "low_quality": "Low Quality",
+ "missing_features": "Missing Features",
+ "switched_service": "Switched Service",
+ "too_complex": "Too Complex",
+ "too_expensive": "Too Expensive",
+ "unused": "Unused",
+ "other": "Other",
+ "more_information": "More information (the more details, the more helpful it'd be)",
+ "feedback_placeholder": "e.g. I needed a feature that...",
+ "delete_your_account": "Delete Your Account",
+ "change_password": "Change Password",
+ "password_length_error": "Passwords must be at least 8 characters.",
+ "applying_changes": "Applying...",
+ "password_change_instructions": "To change your password, please fill out the following. Your password should be at least 8 characters.",
+ "old_password": "Old Password",
+ "new_password": "New Password",
+ "preference": "Preference",
+ "select_theme": "Select Theme",
+ "dark": "Dark",
+ "light": "Light",
+ "archive_settings": "Archive Settings",
+ "formats_to_archive": "Formats to Archive/Preserve webpages:",
+ "screenshot": "Screenshot",
+ "pdf": "PDF",
+ "archive_org_snapshot": "Archive.org Snapshot",
+ "link_settings": "Link Settings",
+ "prevent_duplicate_links": "Prevent duplicate links",
+ "clicking_on_links_should": "Clicking on Links should:",
+ "open_original_content": "Open the original content",
+ "open_pdf_if_available": "Open PDF, if available",
+ "open_readable_if_available": "Open Readable, if available",
+ "open_screenshot_if_available": "Open Screenshot, if available",
+ "open_webpage_if_available": "Open Webpage copy, if available",
+ "tag_renamed": "Tag renamed!",
+ "tag_deleted": "Tag deleted!",
+ "rename_tag": "Rename Tag",
+ "delete_tag": "Delete Tag",
+ "list_created_with_linkwarden": "List created with Linkwarden",
+ "by_author": "By {{author}}.",
+ "by_author_and_other": "By {{author}} and {{count}} other.",
+ "by_author_and_others": "By {{author}} and {{count}} others.",
+ "search_count_link": "Search {{count}} Link",
+ "search_count_links": "Search {{count}} Links",
+ "collection_is_empty": "This Collection is empty...",
+ "all_links": "All Links",
+ "all_links_desc": "Links from every Collection",
+ "you_have_not_added_any_links": "You Haven't Created Any Links Yet",
+ "collections_you_own": "Collections you own",
+ "new_collection": "New Collection",
+ "other_collections": "Other Collections",
+ "other_collections_desc": "Shared collections you're a member of",
+ "showing_count_results": "Showing {{count}} results",
+ "showing_count_result": "Showing {{count}} result",
+ "edit_collection_info": "Edit Collection Info",
+ "share_and_collaborate": "Share and Collaborate",
+ "view_team": "View Team",
+ "team": "Team",
+ "create_subcollection": "Create Sub-Collection",
+ "delete_collection": "Delete Collection",
+ "leave_collection": "Leave Collection",
+ "email_verified_signing_out": "Email verified. Signing out...",
+ "invalid_token": "Invalid token.",
+ "sending_password_recovery_link": "Sending password recovery link...",
+ "please_fill_all_fields": "Please fill out all the fields.",
+ "password_updated": "Password Updated!",
+ "reset_password": "Reset Password",
+ "enter_email_for_new_password": "Enter your email so we can send you a link to create a new password.",
+ "update_password": "Update Password",
+ "password_successfully_updated": "Your password has been successfully updated.",
+ "user_already_member": "User already exists.",
+ "you_are_already_collection_owner": "You are already the collection owner.",
+ "date_newest_first": "Date (Newest First)",
+ "date_oldest_first": "Date (Oldest First)",
+ "name_az": "Name (A-Z)",
+ "name_za": "Name (Z-A)",
+ "description_az": "Description (A-Z)",
+ "description_za": "Description (Z-A)",
+ "all_rights_reserved": "© {{date}} <0>Linkwarden0>. All rights reserved.",
+ "you_have_no_collections": "You have no Collections...",
+ "you_have_no_tags": "You have no Tags...",
+ "cant_change_collection_you_dont_own": "You can't make changes to a collection you don't own.",
+ "account": "Account",
+ "billing": "Billing",
+ "linkwarden_version": "Linkwarden {{version}}",
+ "help": "Help",
+ "github": "GitHub",
+ "twitter": "Twitter",
+ "mastodon": "Mastodon",
+ "link_preservation_in_queue": "The Link preservation is currently in the queue",
+ "check_back_later": "Please check back later to see the result",
+ "there_are_more_formats": "There are more preserved formats in the queue",
+ "settings": "Settings",
+ "switch_to": "Switch to {{theme}}",
+ "logout": "Logout",
+ "start_journey": "Start your journey by creating a new Link!",
+ "create_new_link": "Create New Link",
+ "new_link": "New Link",
+ "create_new": "Create New...",
+ "pwa_install_prompt": "Install Linkwarden to your home screen for a faster access and enhanced experience. <0>Learn more0>",
+ "full_content": "Full Content",
+ "slower": "Slower",
+ "new_version_announcement": "See what's new in <0>Linkwarden {{version}}!0>",
+ "creating": "Creating...",
+ "upload_file": "Upload File",
+ "file": "File",
+ "file_types": "PDF, PNG, JPG (Up to {{size}} MB)",
+ "description": "Description",
+ "auto_generated": "Will be auto generated if nothing is provided.",
+ "example_link": "e.g. Example Link",
+ "hide": "Hide",
+ "more": "More",
+ "options": "Options",
+ "description_placeholder": "Notes, thoughts, etc.",
+ "deleting": "Deleting...",
+ "token_revoked": "Token Revoked.",
+ "revoke_token": "Revoke Token",
+ "revoke_confirmation": "Are you sure you want to revoke this Access Token? Any apps or services using this token will no longer be able to access Linkwarden using it.",
+ "revoke": "Revoke",
+ "sending_request": "Sending request...",
+ "link_being_archived": "Link is being archived...",
+ "preserved_formats": "Preserved Formats",
+ "available_formats": "The following formats are available for this link:",
+ "readable": "Readable",
+ "preservation_in_queue": "Link preservation is in the queue",
+ "view_latest_snapshot": "View latest snapshot on archive.org",
+ "refresh_preserved_formats": "Refresh Preserved Formats",
+ "this_deletes_current_preservations": "This deletes the current preservations",
+ "create_new_user": "Create New User",
+ "placeholder_johnny": "Johnny",
+ "placeholder_email": "johnny@example.com",
+ "placeholder_john": "john",
+ "user_created": "User Created!",
+ "fill_all_fields_error": "Please fill out all the fields.",
+ "password_change_note": "<0>Note:0> Please make sure you inform the user that they need to change their password.",
+ "create_user": "Create User",
+ "creating_token": "Creating Token...",
+ "token_created": "Token Created!",
+ "access_token_created": "Access Token Created",
+ "token_creation_notice": "Your new token has been created. Please copy it and store it somewhere safe. You will not be able to see it again.",
+ "copied_to_clipboard": "Copied to clipboard!",
+ "copy_to_clipboard": "Copy to Clipboard",
+ "create_access_token": "Create an Access Token",
+ "expires_in": "Expires in",
+ "token_name_placeholder": "e.g. For the iOS shortcut",
+ "create_token": "Create Access Token",
+ "7_days": "7 Days",
+ "30_days": "30 Days",
+ "60_days": "60 Days",
+ "90_days": "90 Days",
+ "no_expiration": "No Expiration",
+ "creating_link": "Creating link...",
+ "link_created": "Link created!",
+ "link_name_placeholder": "Will be auto generated if left empty.",
+ "link_url_placeholder": "e.g. http://example.com/",
+ "link_description_placeholder": "Notes, thoughts, etc.",
+ "more_options": "More Options",
+ "hide_options": "Hide Options",
+ "create_link": "Create Link",
+ "new_sub_collection": "New Sub-Collection",
+ "for_collection": "For {{name}}",
+ "create_new_collection": "Create a New Collection",
+ "color": "Color",
+ "reset_defaults": "Reset to Defaults",
+ "updating_collection": "Updating Collection...",
+ "collection_name_placeholder": "e.g. Example Collection",
+ "collection_description_placeholder": "The purpose of this Collection...",
+ "create_collection_button": "Create Collection",
+ "password_change_warning": "Please confirm your password before changing your email address.",
+ "stripe_update_note": " Updating this field will change your billing email on Stripe as well.",
+ "sso_will_be_removed_warning": "If you change your email address, any existing {{service}} SSO connections will be removed.",
+ "old_email": "Old Email",
+ "new_email": "New Email",
+ "confirm": "Confirm",
+ "edit_link": "Edit Link",
+ "updating": "Updating...",
+ "updated": "Updated!",
+ "placeholder_example_link": "e.g. Example Link",
+ "make_collection_public": "Make Collection Public",
+ "make_collection_public_checkbox": "Make this a public collection",
+ "make_collection_public_desc": "This will allow anyone to view this collection and it's users.",
+ "sharable_link": "Sharable Link",
+ "copied": "Copied!",
+ "members": "Members",
+ "members_username_placeholder": "Username (without the '@')",
+ "owner": "Owner",
+ "admin": "Admin",
+ "contributor": "Contributor",
+ "viewer": "Viewer",
+ "viewer_desc": "Read-only access",
+ "contributor_desc": "Can view and create Links",
+ "admin_desc": "Full access to all Links",
+ "remove_member": "Remove Member",
+ "placeholder_example_collection": "e.g. Example Collection",
+ "placeholder_collection_purpose": "The purpose of this Collection...",
+ "deleting_user": "Deleting...",
+ "user_deleted": "User Deleted.",
+ "delete_user": "Delete User",
+ "confirm_user_deletion": "Are you sure you want to remove this user?",
+ "irreversible_action_warning": "This action is irreversible!",
+ "delete_confirmation": "Delete, I know what I'm doing",
+ "delete_link": "Delete Link",
+ "deleted": "Deleted.",
+ "link_deletion_confirmation_message": "Are you sure you want to delete this Link?",
+ "warning": "Warning",
+ "irreversible_warning": "This action is irreversible!",
+ "shift_key_tip": "Hold the Shift key while clicking 'Delete' to bypass this confirmation in the future.",
+ "deleting_collection": "Deleting...",
+ "collection_deleted": "Collection Deleted.",
+ "confirm_deletion_prompt": "To confirm, type \"{{name}}\" in the box below:",
+ "type_name_placeholder": "Type \"{{name}}\" Here.",
+ "deletion_warning": "Deleting this collection will permanently erase all its contents, and it will become inaccessible to everyone, including members with previous access.",
+ "leave_prompt": "Click the button below to leave the current collection.",
+ "leave": "Leave",
+ "edit_links": "Edit {{count}} Links",
+ "move_to_collection": "Move to Collection",
+ "add_tags": "Add Tags",
+ "remove_previous_tags": "Remove previous tags",
+ "delete_links": "Delete {{count}} Links",
+ "links_deletion_confirmation_message": "Are you sure you want to delete {{count}} Links? ",
+ "warning_irreversible": "Warning: This action is irreversible!",
+ "shift_key_instruction": "Hold the 'Shift' key while clicking 'Delete' to bypass this confirmation in the future.",
+ "link_selection_error": "You don't have permission to edit or delete this item.",
+ "no_description": "No description provided.",
+ "applying": "Applying...",
+ "unpin": "Unpin",
+ "pin_to_dashboard": "Pin to Dashboard",
+ "show_link_details": "Show Link Details",
+ "link_pinned": "Link Pinned!",
+ "link_unpinned": "Link Unpinned!",
+ "webpage": "Webpage",
+ "server_administration": "Server Administration",
+ "all_collections": "All Collections",
+ "dashboard": "Dashboard",
+ "demo_title": "Demo Only",
+ "demo_desc": "This is only a demo instance of Linkwarden and uploads are disabled.",
+ "demo_desc_2": "If you want to try out the full version, you can sign up for a free trial at:",
+ "demo_button": "Login as demo user",
+ "regular": "Regular",
+ "thin": "Thin",
+ "bold": "Bold",
+ "fill": "Fill",
+ "duotone": "Duotone",
+ "light_icon": "Light",
+ "search": "Search",
+ "set_custom_icon": "Set Custom Icon",
+ "view": "View",
+ "show": "Show",
+ "image": "Image",
+ "icon": "Icon",
+ "date": "Date",
+ "preview_unavailable": "Preview Unavailable",
+ "saved": "Saved",
+ "untitled": "Untitled",
+ "no_tags": "No tags.",
+ "no_description_provided": "No description provided.",
+ "change_icon": "Change Icon",
+ "upload_preview_image": "Upload Preview Image",
+ "columns": "Columns",
+ "default": "Default",
+ "invalid_url_guide":"Please enter a valid Address for the Link. (It should start with http/https)",
+ "email_invalid": "Please enter a valid email address.",
+ "username_invalid_guide": "Username has to be at least 3 characters, no spaces and special characters are allowed."
+}
\ No newline at end of file
diff --git a/public/locales/es/common.json b/public/locales/es/common.json
new file mode 100644
index 0000000..320d3a5
--- /dev/null
+++ b/public/locales/es/common.json
@@ -0,0 +1,375 @@
+{
+ "user_administration": "Administración de usuarios",
+ "search_users": "Buscar usuarios",
+ "no_users_found": "No se ha encontrado el usuario.",
+ "no_user_found_in_search": "No se ha encontrado el usuario con esos parámetros de búsqueda.",
+ "username": "Nombre de Usuario",
+ "email": "Email",
+ "subscribed": "Suscrito",
+ "created_at": "Creado en",
+ "not_available": "N/D",
+ "check_your_email": "Por favor, comprueba tu correo electrónico",
+ "authenticating": "Autenticando...",
+ "verification_email_sent": "Email de verificación enviado.",
+ "verification_email_sent_desc": "Se ha enviado un enlace de inicio de sesión a tu correo electrónico. Si no ves el correo, revisa tu carpeta de spam.",
+ "resend_email": "Reenviar correo electrónico",
+ "invalid_credentials": "Credenciales inválidas.",
+ "fill_all_fields": "Por favor, rellena todos los campos.",
+ "enter_credentials": "Ingresa tus credenciales.",
+ "username_or_email": "Nombre de usuario o correo electrónico",
+ "password": "Contraseña",
+ "confirm_password": "Confirmar contraseña",
+ "forgot_password": "¿Has olvidado tu contraseña?",
+ "login": "Iniciar sesión",
+ "or_continue_with": "O continue con",
+ "new_here": "¿Nuevo por aquí?",
+ "sign_up": "Registrarse",
+ "sign_in_to_your_account": "Inicia sesión en tu cuenta.",
+ "dashboard_desc": "Un breve resumen de tus datos",
+ "link": "Enlace",
+ "links": "Enlaces",
+ "collection": "Colección",
+ "collections": "Colecciones",
+ "tag": "Etiqueta",
+ "tags": "Etiquetas",
+ "recent": "Reciente",
+ "recent_links_desc": "Enlaces añadidos recientemente",
+ "view_all": "Ver todo",
+ "view_added_links_here": "¡Mira todos tus enlaces añadidos recientemente aquí!",
+ "view_added_links_here_desc": "Esta sección mostrará tus enlaces añadidos más recientes en todas las colecciones a las que tengas acceso.",
+ "add_link": "Añade nuevos enlaces",
+ "import_links": "Importar enlaces",
+ "from_linkwarden": "Desde Linkwarden",
+ "from_html": "Desde un archivo HTML de marcadores",
+ "from_wallabag": "Desde Wallabag (archivo JSON)",
+ "pinned": "Anclado",
+ "pinned_links_desc": "Tus enlaces anclados",
+ "pin_favorite_links_here": "¡Ancla tus enlaces favoritos aquí!",
+ "pin_favorite_links_here_desc": "Puedes anclar tus enlaces favoritos haciendo clic en los tres puntos en cada enlace y seleccionando Anclar en el tablero.",
+ "sending_password_link": "Enviando enlace de recuperación de contraseña...",
+ "password_email_prompt": "Ingresa tu correo electrónico para que podamos enviarte un enlace para crear una nueva contraseña.",
+ "send_reset_link": "Enviar enlace de restablecimiento",
+ "reset_email_sent_desc": "Revisa tu correo electrónico para encontrar un enlace para restablecer tu contraseña. Si no aparece en unos minutos, revisa tu carpeta de spam.",
+ "back_to_login": "Volver al inicio de sesión",
+ "email_sent": "¡Email enviado!",
+ "passwords_mismatch": "Las contraseñas no coinciden.",
+ "password_too_short": "La contraseña deben tener al menos 8 caracteres.",
+ "creating_account": "Creando cuenta...",
+ "account_created": "¡Cuenta creada!",
+ "trial_offer_desc": "¡Desbloquea {{count}} días de servicio Premium gratis!",
+ "register_desc": "Crear una nueva cuenta",
+ "registration_disabled_desc": "El registro está deshabilitado para esta instancia. Por favor, contacta al administrador en caso de cualquier problema.",
+ "enter_details": "Ingresa tus datos",
+ "display_name": "Mostrar nombre",
+ "sign_up_agreement": "Al registrarte, aceptas nuestros <0>Términos de Servicio0> y nuestra <1>Política de Privacidad1>.",
+ "need_help": "¿Necesitas ayuda?",
+ "get_in_touch": "Contáctanos",
+ "already_registered": "¿Ya tienes una cuenta?",
+ "deleting_selections": "Eliminando seleccionados...",
+ "links_deleted": "{{count}} enlaces eliminados.",
+ "link_deleted": "1 enlace eliminado.",
+ "links_selected": "{{count}} enlaces seleccionados",
+ "link_selected": "1 enlace seleccionado",
+ "nothing_selected": "Nada seleccionado",
+ "edit": "Editar",
+ "delete": "Eliminar",
+ "nothing_found": "No se encontró nada.",
+ "redirecting_to_stripe": "Redirigiendo a Stripe...",
+ "subscribe_title": "¡Suscríbete a Linkwarden!",
+ "subscribe_desc": "Serás redirigido a Stripe. No dudes en ponerte en contacto con nosotros en <0>support@linkwarden.app0> en caso de cualquier problema.",
+ "monthly": "Mensual",
+ "yearly": "Anual",
+ "discount_percent": "{{percent}}% de descuento",
+ "billed_monthly": "Facturado mensualmente",
+ "billed_yearly": "Facturado anualmente",
+ "total": "Total",
+ "total_annual_desc": "Prueba gratuita de {{count}} días, luego ${{annualPrice}} al año",
+ "total_monthly_desc": "Prueba gratuita de {{count}} días, luego ${{annualPrice}} al mes",
+ "plus_tax": "+ IVA si corresponde",
+ "complete_subscription": "Completar suscripción",
+ "sign_out": "Cerrar sesión",
+ "access_tokens": "Tokens de acceso",
+ "access_tokens_description": "Los tokens de acceso se pueden usar para acceder a Linkwarden desde otras aplicaciones y servicios sin revelar tu nombre de usuario y contraseña.",
+ "new_token": "Nuevo token de acceso",
+ "name": "Nombre",
+ "created_success": "¡Creado!",
+ "created": "Creado",
+ "expires": "Expira",
+ "accountSettings": "Ajustes de la cuenta",
+ "language": "Idioma",
+ "profile_photo": "Foto de perfil",
+ "upload_new_photo": "Sube una foto nueva...",
+ "remove_photo": "Eliminar foto",
+ "make_profile_private": "Hacer perfil privado",
+ "profile_privacy_info": "Esto limitará quién puede encontrarte y agregarte a nuevas colecciones.",
+ "whitelisted_users": "Usuarios autorizados",
+ "whitelisted_users_info": "Por favor, proporciona el nombre de usuario de los usuarios a los que deseas conceder visibilidad de tu perfil, separados por comas.",
+ "whitelisted_users_placeholder": "Tu perfil está oculto para todos en este momento...",
+ "save_changes": "Guardar cambios",
+ "import_export": "Importar y exportar",
+ "import_data": "Importa tus datos desde otras plataformas.",
+ "download_data": "Descarga tus datos al instante.",
+ "export_data": "Exportar datos",
+ "delete_account": "Eliminar cuenta",
+ "delete_account_warning": "Esto eliminará permanentemente TODOS los enlaces, colecciones, etiquetas y datos archivados en tu cuenta.",
+ "cancel_subscription_notice": "También cancelará tu suscripción.",
+ "account_deletion_page": "Página de eliminación de cuenta",
+ "applying_settings": "Aplicando configuraciones...",
+ "settings_applied":"¡Configuraciones aplicadas!",
+ "email_change_request": "Solicitud de cambio de correo electrónico enviado. Por favor, verifica el nuevo correo electrónico.",
+ "image_upload_size_error": "Por favor, selecciona un archivo PNG o JPEG que sea menor de 1 MB.",
+ "image_upload_format_error": "Formato de archivo no válido.",
+ "importing_bookmarks": "Importando marcadores...",
+ "import_success": "¡Marcadores importados! Recargando la página...",
+ "more_coming_soon": "¡Más próximamente!",
+ "billing_settings": "Ajustes de facturación",
+ "manage_subscription_intro": "Para gestionar/cancelar tu suscripción, visita el",
+ "billing_portal": "Portal de facturación",
+ "help_contact_intro": "Si necesitas ayuda o has encontrado algún problema, no dudes en contactarnos en:",
+ "fill_required_fields": "Por favor, rellena los campos obligatorios.",
+ "deleting_message": "Eliminando todo, por favor espera...",
+ "delete_warning": "Esto eliminará permanentemente todos los enlaces, colecciones, etiquetas y datos archivados en tu cuenta. También cerrará la sesión. ¡Esta acción es irreversible!",
+ "optional": "Opcional",
+ "feedback_help": "(¡pero realmente nos ayuda a mejorar!)",
+ "reason_for_cancellation": "Motivos de la cancelación",
+ "please_specify": "Por favor, especifica",
+ "customer_service": "Servicio al usuario",
+ "low_quality": "Mala calidad",
+ "missing_features": "Le faltan utilidades",
+ "switched_service": "Cambio a otra plataforma",
+ "too_complex": "Muy complejo",
+ "too_expensive": "Muy caro",
+ "unused": "No lo uso",
+ "other": "Otro",
+ "more_information": "Más información (cuantos más detalles, más útil será)",
+ "feedback_placeholder": "ej. necesitaba una función que...",
+ "delete_your_account": "Elliminar tu cuenta",
+ "change_password": "Cambiar contraseña",
+ "password_length_error": "La contraseña debe tener al menos 8 caracteres.",
+ "applying_changes": "Aplicando...",
+ "password_change_instructions": "Para cambiar tu contraseña, por favor completa lo siguiente. Tu contraseña debe tener al menos 8 caracteres.",
+ "old_password": "Contraseña actual",
+ "new_password": "Nueva contraseña",
+ "preference": "Preferencias",
+ "select_theme": "Seleccionar tema",
+ "dark": "Oscuro",
+ "light": "Claro",
+ "archive_settings": "Ajustes de archivado",
+ "formats_to_archive": "Formatos para archivar/conservar páginas web:",
+ "screenshot": "Captura de pantalla",
+ "pdf": "PDF",
+ "archive_org_snapshot": "Captura en archive.org",
+ "link_settings": "Ajustes de enlaces",
+ "prevent_duplicate_links": "Prevenir enlaces duplicados",
+ "clicking_on_links_should": "Hacer click en enlaces debería:",
+ "open_original_content": "Abrir el contenido original",
+ "open_pdf_if_available": "Abrir PDF, si está disponible",
+ "open_readable_if_available": "Abrir versión lectura, si está disponible",
+ "open_screenshot_if_available": "Abrir la captura de pantalla, si está disponible",
+ "open_webpage_if_available": "Abrir copia local de la web, si está disponible",
+ "tag_renamed": "¡Etiqueta renombrada!",
+ "tag_deleted": "¡Etiqueta eliminada!",
+ "rename_tag": "Renombrar etiqueta",
+ "delete_tag": "Eliminar etiqueta",
+ "list_created_with_linkwarden": "Lista generada con Linkwarden",
+ "by_author": "Por {{author}}.",
+ "by_author_and_other": "Por {{author}} y {{count}} más.",
+ "by_author_and_others": "Por {{author}} y {{count}} más.",
+ "search_count_link": "Buscar {{count}} enlace",
+ "search_count_links": "Buscar {{count}} enlaces",
+ "collection_is_empty": "Esta colección está vacía...",
+ "all_links": "Todos los enlaces",
+ "all_links_desc": "Enlaces de todas las colecciones",
+ "you_have_not_added_any_links": "Aún no has creado ningún enlace",
+ "collections_you_own": "Colecciones que te pertenecen",
+ "new_collection": "Nueva colección",
+ "other_collections": "Otras colecciones",
+ "other_collections_desc": "Colecciones compartidas de las que eres miembro",
+ "showing_count_results": "Mostrando {{count}} resultados",
+ "showing_count_result": "Mostrando {{count}} resultado",
+ "edit_collection_info": "Editar información de la colección",
+ "share_and_collaborate": "Compartir y colaborar",
+ "view_team": "Ver grupo",
+ "team": "Grupo",
+ "create_subcollection": "Crear subcolección",
+ "delete_collection": "Eliminar colección",
+ "leave_collection": "Salir de la colección",
+ "email_verified_signing_out": "Correo electrónico verificado. Cerrando sesión...",
+ "invalid_token": "Token inválido.",
+ "sending_password_recovery_link": "Enviando enlace de recuperación de contraseña",
+ "please_fill_all_fields": "Por favor, rellena todos los campos.",
+ "password_updated": "¡Contraseña actualizada!",
+ "reset_password": "Restablecer contraseña",
+ "enter_email_for_new_password": "Ingresa tu correo electrónico para que podamos enviarte un enlace para crear una nueva contraseña.",
+ "update_password": "Actualizar contraseña",
+ "password_successfully_updated": "Tu contraseña ha sido actualizada correctamente.",
+ "user_already_member": "El usuario ya existe.",
+ "you_are_already_collection_owner": "Ya eres el dueño de esta colección.",
+ "date_newest_first": "Fecha (Nuevos primero)",
+ "date_oldest_first": "Fecha (Antiguos primero)",
+ "name_az": "Nombre (A-Z)",
+ "name_za": "Nombre (Z-A)",
+ "description_az": "Descripción (A-Z)",
+ "description_za": "Descripción (Z-A)",
+ "all_rights_reserved": "© {{date}} <0>Linkwarden0>. Todos los derechos reservados.",
+ "you_have_no_collections": "No tienes ninguna colección...",
+ "you_have_no_tags": "No tienes ninguna etiqueta...",
+ "cant_change_collection_you_dont_own": "No puedes hacer cambios en una colección que no te pertenece.",
+ "account": "Cuenta",
+ "billing": "Facturación",
+ "linkwarden_version": "Linkwarden {{version}}",
+ "help": "Ayuda",
+ "github": "GitHub",
+ "twitter": "Twitter",
+ "mastodon": "Mastodon",
+ "link_preservation_in_queue": "La conservación del enlace está actualmente en cola.",
+ "check_back_later": "Por favor, vuelve más tarde para ver el resultado.",
+ "there_are_more_formats": "Hay más formatos de conservación en cola.",
+ "settings": "Ajustes",
+ "switch_to": "Cambiar a {{theme}}",
+ "logout": "Cerrar sesión",
+ "start_journey": "¡Empieza tu experiencia creando un nuevo enlace!",
+ "create_new_link": "Crear un nuevo enlace",
+ "new_link": "Nuevo enlace",
+ "create_new": "Crear nuevo...",
+ "pwa_install_prompt": "Instala Linkwarden en la pantalla de inicio para un acceso más rápido y una experiencia mejorada. <0>Aprende más0>",
+ "full_content": "Contenido completo",
+ "slower": "Más despacio",
+ "new_version_announcement": "¡Descubre las novedades en <0>Linkwarden {{version}}!0>",
+ "creating": "Creando...",
+ "upload_file": "Subir archivo",
+ "file": "Archivo",
+ "file_types": "PDF, PNG, JPG (Hasta {{size}} MB)",
+ "description": "Descripción",
+ "auto_generated": "Será generado automáticamente si no se proporciona nada.",
+ "example_link": "ej. Enlace de ejemplo",
+ "hide": "Esconder",
+ "more": "Más",
+ "options": "Opciones",
+ "description_placeholder": "Notas, ideas, etc.",
+ "deleting": "Eliminando...",
+ "token_revoked": "Token anulado.",
+ "revoke_token": "Anular token",
+ "revoke_confirmation": "¿Estás seguro de que deseas anular este token de acceso? Cualquier aplicación o servicio que use este token ya no podrá acceder a Linkwarden con él.",
+ "revoke": "Anular",
+ "sending_request": "Enviando solicitud...",
+ "link_being_archived": "El enlace está siendo archivado...",
+ "preserved_formats": "Formatos conservados",
+ "available_formats": "Los siguientes formatos están disponibles para este enlace:",
+ "readable": "Versión lectura",
+ "preservation_in_queue": "La conservación del enlace está en la cola.",
+ "view_latest_snapshot": "Ver la última captura en archive.org",
+ "refresh_preserved_formats": "Actualizar formatos conservados",
+ "this_deletes_current_preservations": "Esto elimina las conservaciones actuales.",
+ "create_new_user": "Crear nuevo usuario",
+ "placeholder_johnny": "Johnny",
+ "placeholder_email": "johnny@ejemplo.com",
+ "placeholder_john": "john",
+ "user_created": "¡Usuario creado!",
+ "fill_all_fields_error": "Por favor, rellena todos los campos.",
+ "password_change_note": "<0>Nota:0> Por favor, asegúrate de informar al usuario que necesita cambiar su contraseña.",
+ "create_user": "Crear usuario",
+ "creating_token": "Creando token...",
+ "token_created": "¡Token creado!",
+ "access_token_created": "Token de acceso creado",
+ "token_creation_notice": "Tu nuevo token ha sido creado. Por favor, cópialo y guárdalo en un lugar seguro. No lo mostraremos de nuevo.",
+ "copied_to_clipboard": "¡Copiado al portapapeles!",
+ "copy_to_clipboard": "Copiar al portapapeles",
+ "create_access_token": "Crear un token de acceso",
+ "expires_in": "Caduca en",
+ "token_name_placeholder": "ej. Para el atajo de iOS",
+ "create_token": "Crear token de acceso",
+ "7_days": "7 días",
+ "30_days": "30 días",
+ "60_days": "60 días",
+ "90_days": "90 días",
+ "no_expiration": "Sin caducidad",
+ "creating_link": "Creando enlace...",
+ "link_created": "¡Enlace creado!",
+ "link_name_placeholder": "Se generará automáticamente si se deja en blanco.",
+ "link_url_placeholder": "ej. http://ejemplo.com/",
+ "link_description_placeholder": "Notas, ideas, etc.",
+ "more_options": "Más opciones",
+ "hide_options": "Ocultar opciones",
+ "create_link": "Crear enlace",
+ "new_sub_collection": "Nueva subcolección",
+ "for_collection": "Para {{name}}",
+ "create_new_collection": "Crear una nueva colección",
+ "color": "Color",
+ "reset": "Reestablecer",
+ "updating_collection": "Actualizando colección...",
+ "collection_name_placeholder": "ej. Colección de ejemplo",
+ "collection_description_placeholder": "El propósito de esta colección...",
+ "create_collection_button": "Crear colección",
+ "password_change_warning": "Por favor, confirma tu contraseña antes de cambiar tu email.",
+ "stripe_update_note": " Actualizar este campo cambiará también tu email de facturación en Stripe.",
+ "sso_will_be_removed_warning": "Si cambias tu correo electrónico, cualquier conexión SSO existente de {{service}} será eliminada.",
+ "old_email": "Correo electrónico actual",
+ "new_email": "Correo electrónico nuevo",
+ "confirm": "Confirmar",
+ "edit_link": "Editar enlace",
+ "updating": "Actualizando...",
+ "updated": "¡Actualizado!",
+ "placeholder_example_link": "Ej. Enlace de ejemplo",
+ "make_collection_public": "Hacer pública la colección",
+ "make_collection_public_checkbox": "Hacer pública esta colección",
+ "make_collection_public_desc": "Esto permitirá que cualquier persona vea esta colección y sus usuarios.",
+ "sharable_link_guide": "Enlace para compartir (haz clic para copiar)",
+ "copied": "¡Copiado!",
+ "members": "Participantes",
+ "members_username_placeholder": "Nombre de usuario (sin la '@')",
+ "owner": "Propietario",
+ "admin": "Administrador",
+ "contributor": "Colaborador",
+ "viewer": "Lector",
+ "viewer_desc": "Acceso de solo lectura",
+ "contributor_desc": "Puede ver y crear enlaces",
+ "admin_desc": "Acceso completo a todos los enlaces",
+ "remove_member": "Eliminar participante",
+ "placeholder_example_collection": "Ej. colección de ejemplo",
+ "placeholder_collection_purpose": "El propósito de esta colección...",
+ "deleting_user": "Eliminando...",
+ "user_deleted": "Usuario eliminado.",
+ "delete_user": "Eliminar usuario",
+ "confirm_user_deletion": "¿Estás seguro de que quieres eliminar este usuario?",
+ "irreversible_action_warning": "¡Esta acción es irreversible!",
+ "delete_confirmation": "Eliminar, sé lo que estoy haciendo",
+ "delete_link": "Eliminar enlace",
+ "deleted": "Eliminado.",
+ "link_deletion_confirmation_message": "¿Estás seguro de que quieres eliminar este enlace?",
+ "warning": "Advertencia",
+ "irreversible_warning": "¡Esta acción es irreversible!",
+ "shift_key_tip": "Mantén presionada la tecla 'Mayúscula' mientras haces clic en 'Eliminar' para omitir esta confirmación en el futuro.",
+ "deleting_collection": "Eliminando...",
+ "collection_deleted": "Colección eliminada.",
+ "confirm_deletion_prompt": "Para confirmar, escribe \"{{name}}\" en el campo a continuación:",
+ "type_name_placeholder": "Escribe \"{{name}}\" aquí.",
+ "deletion_warning": "Eliminar esta colección borrará permanentemente todo su contenido, y se volverá inaccesible para todos, incluidos los miembros con acceso previamente.",
+ "leave_prompt": "Haz clic en el botón de abajo para abandonar la colección actual.",
+ "leave": "Abandonar",
+ "edit_links": "Editar {{count}} enlaces",
+ "move_to_collection": "Mover a colección",
+ "add_tags": "Añadir etiquetas",
+ "remove_previous_tags": "Eliminar etiquetas anteriores",
+ "delete_links": "Eliminar {{count}} enlaces",
+ "links_deletion_confirmation_message": "¿Estás seguro de que deseas eliminar {{count}} enlaces? ",
+ "warning_irreversible": "Advertencia: ¡Esta acción es irreversible!",
+ "shift_key_instruction": "Mantén presionada la tecla 'Mayúscula' mientras haces clic en 'Eliminar' para omitir esta confirmación en el futuro.",
+ "link_selection_error": "No tienes permiso para editar o eliminar este item.",
+ "no_description": "No se ha proporcionado una descripción.",
+ "applying": "Aplicando...",
+ "unpin": "Desanclar",
+ "pin_to_dashboard": "Anclar al tablero",
+ "show_link_details": "Mostrar detalles del enlace",
+ "hide_link_details": "Ocultar detalles del enlace",
+ "link_pinned": "¡Enlace anclado!",
+ "link_unpinned": "¡Enlace desanclado!",
+ "webpage": "Página web",
+ "server_administration": "Administración del servidor",
+ "all_collections": "Todas las colecciones",
+ "dashboard": "Tablero",
+ "demo_title": "Solo para demostración",
+ "demo_desc": "Esta es solo una instancia de demostración de Linkwarden y las cargas están deshabilitadas.",
+ "demo_desc_2": "Si deseas probar la versión completa, puedes registrarte para una prueba gratuita en:",
+ "demo_button": "Iniciar sesión como usuario demo"
+}
\ No newline at end of file
diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json
new file mode 100644
index 0000000..eb789b0
--- /dev/null
+++ b/public/locales/fr/common.json
@@ -0,0 +1,374 @@
+{
+ "user_administration": "Administration des utilisateurs",
+ "search_users": "Rechercher des utilisateurs",
+ "no_users_found": "Aucun utilisateur trouvé.",
+ "no_user_found_in_search": "Aucun utilisateur trouvé avec la requête de recherche donnée.",
+ "username": "Nom d'utilisateur",
+ "email": "E-mail",
+ "subscribed": "Abonné(e)",
+ "created_at": "Créé le",
+ "not_available": "S/O",
+ "check_your_email": "Veuillez vérifier votre adresse e-mail",
+ "authenticating": "Authentification...",
+ "verification_email_sent": "Envoi de l'email de vérification.",
+ "verification_email_sent_desc": "Un lien de connexion a été envoyé à votre adresse électronique. Si vous ne voyez pas l'e-mail, vérifiez votre dossier de courrier indésirable.",
+ "resend_email": "Renvoyez l'e-mail",
+ "invalid_credentials": "Informations d'identification invalides.",
+ "fill_all_fields": "Veuillez remplir tous les champs.",
+ "enter_credentials": "Entrez vos données d'identification",
+ "username_or_email": "Nom d'utilisateur ou e-mail",
+ "password": "Mot de passe",
+ "confirm_password": "Confirmer le mot de passe",
+ "forgot_password": "Mot de passe oublié ?",
+ "login": "Se connecter",
+ "or_continue_with": "Ou continuer avec",
+ "new_here": "Vous êtes nouveau ?",
+ "sign_up": "S'inscrire",
+ "sign_in_to_your_account": "Connectez-vous à votre compte",
+ "dashboard_desc": "Un bref aperçu de vos données",
+ "link": "Lien",
+ "links": "Liens",
+ "collection": "Collection",
+ "collections": "Collections",
+ "tag": "Étiquette",
+ "tags": "Étiquettes",
+ "recent": "Récent",
+ "recent_links_desc": "Liens récemment ajoutés",
+ "view_all": "Tout voir",
+ "view_added_links_here": "Consultez vos liens récemment ajoutés ici !",
+ "view_added_links_here_desc": "Cette section affichera vos derniers liens ajoutés dans toutes les collections auxquelles vous avez accès.",
+ "add_link": "Ajouter un nouveau lien",
+ "import_links": "Importer des liens",
+ "from_linkwarden": "De Linkwarden",
+ "from_html": "À partir d'un fichier HTML de signets",
+ "from_wallabag": "À partir de Wallabag (fichier JSON)",
+ "pinned": "Épinglé",
+ "pinned_links_desc": "Vos liens épinglés",
+ "pin_favorite_links_here": "Épinglez vos liens favoris ici !",
+ "pin_favorite_links_here_desc": "Vous pouvez épingler vos liens préférés en cliquant sur les trois points sur chaque lien et en cliquant sur Épingler au tableau de bord.",
+ "sending_password_link": "Envoi du lien de récupération du mot de passe...",
+ "password_email_prompt": "Entrez votre e-mail afin que nous puissions vous envoyer un lien pour créer un nouveau mot de passe.",
+ "send_reset_link": "Envoyer le lien de réinitialisation",
+ "reset_email_sent_desc": "Vérifiez votre e-mail pour trouver un lien permettant de réinitialiser votre mot de passe. S'il n'apparaît pas au bout de quelques minutes, vérifiez votre dossier spam.",
+ "back_to_login": "Retour à la page de connexion",
+ "email_sent": "Email envoyé!",
+ "passwords_mismatch": "Les mots de passe ne correspondent pas.",
+ "password_too_short": "Les mots de passe doivent comporter au moins 8 caractères.",
+ "creating_account": "Création d'un compte...",
+ "account_created": "Compte créé!",
+ "trial_offer_desc": "Débloquez {{count}} jours de service Premium sans frais !",
+ "register_desc": "Créer un nouveau compte",
+ "registration_disabled_desc": "L'inscription est désactivée pour cette instance, veuillez contacter l'administrateur en cas de problème.",
+ "enter_details": "Entrez vos coordonnées",
+ "display_name": "Nom affiché",
+ "sign_up_agreement": "En vous inscrivant, vous acceptez nos <0>Conditions d'utilisation0> et notre <1>Politique de confidentialité1>.",
+ "need_help": "Besoin d'aide?",
+ "get_in_touch": "Prenez contact avec nous",
+ "already_registered": "Vous avez déjà un compte?",
+ "deleting_selections": "Suppression des sélections...",
+ "links_deleted": "{{count}} Liens supprimés.",
+ "link_deleted": "1 Lien supprimé.",
+ "links_selected": "{{count}} Liens sélectionnés",
+ "link_selected": "1 Lien sélectionné",
+ "nothing_selected": "Rien de sélectionné",
+ "edit": "Modifier",
+ "delete": "Supprimer",
+ "nothing_found": "Rien n'a été trouvé.",
+ "redirecting_to_stripe": "Redirection vers Stripe...",
+ "subscribe_title": "Abonnez-vous à Linkwarden!",
+ "subscribe_desc": "Vous serez redirigé vers Stripe, n'hésitez pas à nous contacter à <0>support@linkwarden.app0> en cas de problème.",
+ "monthly": "Mensuel",
+ "yearly": "Annuel",
+ "discount_percent": "{{percent}}% de réduction",
+ "billed_monthly": "Facturé mensuellement",
+ "billed_yearly": "Facturé annuellement",
+ "total": "Total",
+ "total_annual_desc": "{{count}}-jour d'essai gratuit, puis ${{annualPrice}} annuellement",
+ "total_monthly_desc": "{{count}}-jour d'essai gratuit, puis ${{monthlyPrice}} par mois",
+ "plus_tax": "+ TVA si applicable",
+ "complete_subscription": "Abonnement complet",
+ "sign_out": "Se déconnecter",
+ "access_tokens": "Jetons d'accès",
+ "access_tokens_description": "Les jetons d'accès peuvent être utilisés pour accéder à Linkwarden à partir d'autres applications et services sans divulguer votre nom d'utilisateur et votre mot de passe.",
+ "new_token": "Nouveau jeton d'accès",
+ "name": "Nom",
+ "created_success": "Créé!",
+ "created": "Créé",
+ "expires": "Expire",
+ "accountSettings": "Paramètres du compte",
+ "language": "Langue",
+ "profile_photo": "Photo de profil",
+ "upload_new_photo": "Envoyer une nouvelle photo...",
+ "remove_photo": "Supprimer la photo",
+ "make_profile_private": "Rendre le profil privé",
+ "profile_privacy_info": "Cela limitera le nombre de personnes pouvant vous trouver et vous ajouter à de nouvelles collections..",
+ "whitelisted_users": "Utilisateurs sur liste blanche",
+ "whitelisted_users_info": "Veuillez fournir le nom d'utilisateur des utilisateurs auxquels vous souhaitez accorder de la visibilité à votre profil. Séparé par une virgule.",
+ "whitelisted_users_placeholder": "Votre profil est actuellement caché à tout le monde...",
+ "save_changes": "Sauvegarder les modifications",
+ "import_export": "Importer & Exporter",
+ "import_data": "Importez vos données depuis d'autres plateformes.",
+ "download_data": "Téléchargez vos données instantanément.",
+ "export_data": "Exporter des données",
+ "delete_account": "Supprimer le compte",
+ "delete_account_warning": "Cela supprimera définitivement TOUS les liens, collections, balises et données archivées que vous possédez.",
+ "cancel_subscription_notice": "Cela annulera également votre abonnement.",
+ "account_deletion_page": "Page de suppression de compte",
+ "applying_settings": "Application des paramètres...",
+ "settings_applied": "Paramètres appliqués !",
+ "email_change_request": "Demande de modification par e-mail envoyée. Veuillez vérifier la nouvelle adresse e-mail.",
+ "image_upload_size_error": "Veuillez sélectionner un fichier PNG ou JPEG de moins de 1 Mo.",
+ "image_upload_format_error": "Format de fichier invalide.",
+ "importing_bookmarks": "Importer des favoris...",
+ "import_success": "Importation des signets ! Rechargement de la page...",
+ "more_coming_soon": "Plus à venir bientôt!",
+ "billing_settings": "Paramètres de facturation",
+ "manage_subscription_intro": "Pour gérer/annuler votre abonnement, visitez le",
+ "billing_portal": "Portail de facturation",
+ "help_contact_intro": "Si vous avez encore besoin d'aide ou rencontrez des problèmes, n'hésitez pas à nous contacter à l'adresse suivante :",
+ "fill_required_fields": "Veuillez remplir les champs requis.",
+ "deleting_message": "Tout supprimer, veuillez patienter...",
+ "delete_warning": "Cela supprimera définitivement tous les liens, collections, balises et données archivées que vous possédez. Cela vous déconnectera également. Cette action est irréversible !",
+ "optional": "Facultatif",
+ "feedback_help": "(mais ça nous aide vraiment à nous améliorer !)",
+ "reason_for_cancellation": "Raison pour l'annulation",
+ "please_specify": "Veuillez préciser",
+ "customer_service": "Service client",
+ "low_quality": "Qualité médiocre",
+ "missing_features": "Fonctionnalités manquantes",
+ "switched_service": "Service commuté",
+ "too_complex": "Trop compliqué",
+ "too_expensive": "Trop cher",
+ "unused": "Inutilisé",
+ "other": "Autre",
+ "more_information": "Plus d'informations (plus il y a de détails, plus cela serait utile)",
+ "feedback_placeholder": "Par exemple: J'avais besoin d'une fonctionnalité qui...",
+ "delete_your_account": "Supprimer votre compte",
+ "change_password": "Changer le mot de passe",
+ "password_length_error": "Les mots de passe doivent comporter au moins 8 caractères.",
+ "applying_changes": "Appliquer...",
+ "password_change_instructions": "Pour modifier votre mot de passe, veuillez remplir ce qui suit. Votre mot de passe doit comporter au moins 8 caractères.",
+ "old_password": "Ancien mot de passe",
+ "new_password": "Nouveau mot de passe",
+ "preference": "Préférence",
+ "select_theme": "Sélectionner un thème",
+ "dark": "Sombre",
+ "light": "Clair",
+ "archive_settings": "Paramètres d'archivage",
+ "formats_to_archive": "Formats pour archiver/préserver les pages Web:",
+ "screenshot": "Capture d'écran",
+ "pdf": "PDF",
+ "archive_org_snapshot": "Instantané d'Archive.org",
+ "link_settings": "Paramètres du lien",
+ "prevent_duplicate_links": "Empêcher les liens en double",
+ "clicking_on_links_should": "Cliquer sur les liens devrait:",
+ "open_original_content": "Ouvrir le contenu original",
+ "open_pdf_if_available": "Ouvrir le PDF, si disponible",
+ "open_readable_if_available": "Ouvrir Readable, si disponible",
+ "open_screenshot_if_available": "Ouvrez la capture d'écran, si disponible",
+ "open_webpage_if_available": "Ouvrir la copie de la page Web, si disponible",
+ "tag_renamed": "L'étiquette a été renommée !",
+ "tag_deleted": "Étiquette supprimée!",
+ "rename_tag": "Renommer l'étiquette",
+ "delete_tag": "Supprimer l'étiquette",
+ "list_created_with_linkwarden": "Liste créée avec Linkwarden",
+ "by_author": "Par {{author}}.",
+ "by_author_and_other": "Par {{author}} et {{count}} autre.",
+ "by_author_and_others": "Par {{author}} et {{count}} autres.",
+ "search_count_link": "Recherche {{count}} Lien",
+ "search_count_links": "Recherche {{count}} Liens",
+ "collection_is_empty": "Cette collection est vide...",
+ "all_links": "Tous les liens",
+ "all_links_desc": "Liens de chaque collection",
+ "you_have_not_added_any_links": "Vous n'avez pas encore créé de liens",
+ "collections_you_own": "Collections que vous possédez",
+ "new_collection": "Nouvelle collection",
+ "other_collections": "Autres collections",
+ "other_collections_desc": "Collections partagées dont vous êtes membre",
+ "showing_count_results": "Afficher {{count}} résultats",
+ "showing_count_result": "Afficher {{count}} résultat",
+ "edit_collection_info": "Modifier les informations sur la collection",
+ "share_and_collaborate": "Partager et collaborer",
+ "view_team": "Voir l'équipe",
+ "team": "L'équipe",
+ "create_subcollection": "Créer une sous-collection",
+ "delete_collection": "Supprimer la collection",
+ "leave_collection": "Quitter la collection",
+ "email_verified_signing_out": "Courriel vérifié. Déconnexion...",
+ "invalid_token": "Jeton non valide.",
+ "sending_password_recovery_link": "Envoi du lien de récupération du mot de passe...",
+ "please_fill_all_fields": "Veuillez remplir tous les champs.",
+ "password_updated": "Mot de passe mis à jour!",
+ "reset_password": "Réinitialiser le mot de passe",
+ "enter_email_for_new_password": "Saisissez votre adresse électronique afin que nous puissions vous envoyer un lien pour créer un nouveau mot de passe.",
+ "update_password": "Mise à jour du mot de passe",
+ "password_successfully_updated": "Votre mot de passe a été mis à jour avec succès.",
+ "user_already_member": "L'utilisateur existe déjà.",
+ "you_are_already_collection_owner": "Vous êtes déjà le propriétaire de la collection.",
+ "date_newest_first": "Date (la plus récente en premier)",
+ "date_oldest_first": "Date (la plus ancienne en premier)",
+ "name_az": "Nom (A-Z)",
+ "name_za": "Nom (Z-A)",
+ "description_az": "Description (A-Z)",
+ "description_za": "Description (Z-A)",
+ "all_rights_reserved": "© {{date}} <0>Linkwarden0>. Tous droits réservés.",
+ "you_have_no_collections": "Vous n'avez pas de Collections...",
+ "you_have_no_tags": "Vous n’avez pas d’étiquettes...",
+ "cant_change_collection_you_dont_own": "Vous ne pouvez pas modifier une collection dont vous n'êtes pas propriétaire.",
+ "account": "Compte",
+ "billing": "Facturation",
+ "linkwarden_version": "Linkwarden {{version}}",
+ "help": "Aide",
+ "github": "GitHub",
+ "twitter": "Twitter",
+ "mastodon": "Mastodon",
+ "link_preservation_in_queue": "La préservation du lien est actuellement dans la file d'attente",
+ "check_back_later": "Revenez plus tard pour voir le résultat",
+ "there_are_more_formats": "Il y a plus de formats conservés dans la file d'attente",
+ "settings": "Paramètres",
+ "switch_to": "Basculer vers {{theme}}",
+ "logout": "Déconnexion",
+ "start_journey": "Commencez votre voyage en créant un nouveau lien!",
+ "create_new_link": "Créer un nouveau lien",
+ "new_link": "Nouveau lien",
+ "create_new": "Créer nouveau...",
+ "pwa_install_prompt": "Installez Linkwarden sur votre écran d'accueil pour un accès plus rapide et une expérience améliorée. <0>En savoir plus0>",
+ "full_content": "Contenu complet",
+ "slower": "Plus lent",
+ "new_version_announcement": "Voir ce qu'il y a de nouveau dans <0>Linkwarden {{version}}!0>",
+ "creating": "Création...",
+ "upload_file": "Envoyer fichier",
+ "file": "Ficher",
+ "file_types": "PDF, PNG, JPG (Jusqu'à {{size}} MB)",
+ "description": "Description",
+ "auto_generated": "Sera généré automatiquement si rien n'est fourni.",
+ "example_link": "Par exemple: Exemple de lien",
+ "hide": "Cacher",
+ "more": "Plus",
+ "options": "Options",
+ "description_placeholder": "Notes, réflexions, etc.",
+ "deleting": "Suppression...",
+ "token_revoked": "Jeton révoqué.",
+ "revoke_token": "Révoquer le jeton",
+ "revoke_confirmation": "Êtes-vous sûr de vouloir révoquer ce jeton d'accès ? Les applications ou services utilisant ce jeton ne pourront plus accéder à Linkwarden en l'utilisant.",
+ "revoke": "Révoquer",
+ "sending_request": "Envoi de la demande...",
+ "link_being_archived": "Le lien est en cours d'archivage...",
+ "preserved_formats": "Formats conservés",
+ "available_formats": "Les formats suivants sont disponibles pour ce lien:",
+ "readable": "Lisible",
+ "preservation_in_queue": "La préservation du lien est dans la file d'attente",
+ "view_latest_snapshot": "Voir le dernier instantané sur archive.org",
+ "refresh_preserved_formats": "Rafraîchir les formats conservés",
+ "this_deletes_current_preservations": "Cette opération supprime les conservations en cours",
+ "create_new_user": "Créer un nouvel utilisateur",
+ "placeholder_johnny": "Johnny",
+ "placeholder_email": "johnny@exemple.com",
+ "placeholder_john": "john",
+ "user_created": "Utilisateur créé!",
+ "fill_all_fields_error": "Veuillez remplir tous les champs.",
+ "password_change_note": "<0>Note:0> Veillez à informer l'utilisateur qu'il doit modifier son mot de passe..",
+ "create_user": "Créer un utilisateur",
+ "creating_token": "Création d'un jeton...",
+ "token_created": "Jeton créé!",
+ "access_token_created": "Jeton d'accès créé",
+ "token_creation_notice": "Votre nouveau jeton a été créé. Veuillez le copier et le conserver en lieu sûr. Vous ne pourrez plus le voir.",
+ "copied_to_clipboard": "Copié dans le presse-papiers !",
+ "copy_to_clipboard": "Copier dans le presse-papiers",
+ "create_access_token": "Créer un jeton d'accès",
+ "expires_in": "Expire dans",
+ "token_name_placeholder": "Par exemple: Pour le raccourci iOS",
+ "create_token": "Créer un jeton d'accès",
+ "7_days": "7 jous",
+ "30_days": "30 jours",
+ "60_days": "60 jours",
+ "90_days": "90 jous",
+ "no_expiration": "Pas d'expiration",
+ "creating_link": "Création d'un lien...",
+ "link_created": "Lien créé!",
+ "link_name_placeholder": "Sera généré automatiquement s'il n'est pas renseigné.",
+ "link_url_placeholder": "Par exemple: http://exemple.com/",
+ "link_description_placeholder": "Notes, réflexions, etc.",
+ "more_options": "Plus d'options",
+ "hide_options": "Cacher les options",
+ "create_link": "Créer un lien",
+ "new_sub_collection": "Nouvelle sous-collection",
+ "for_collection": "Pour {{name}}",
+ "create_new_collection": "Créer une nouvelle collection",
+ "color": "Couleur",
+ "reset": "Réinitialiser",
+ "collection_name_placeholder": "Par exemple: Exemple de collection",
+ "collection_description_placeholder": "L'objectif de cette collection...",
+ "create_collection_button": "Créer une collection",
+ "password_change_warning": "Veuillez confirmer votre mot de passe avant de modifier votre adresse électronique.",
+ "stripe_update_note": " La mise à jour de ce champ modifiera également votre email de facturation sur Stripe.",
+ "sso_will_be_removed_warning": "Si vous changez d'adresse électronique, toutes les connexions SSO {{service}} existantes seront supprimées.",
+ "old_email": "Ancien e-mail",
+ "new_email": "Nouvel e-mail",
+ "confirm": "Confirmer",
+ "edit_link": "Modifier le lien",
+ "updating": "Mise à jour...",
+ "updated": "Mis à jour!",
+ "placeholder_example_link": "Par exemple: Lien d'exemple",
+ "make_collection_public": "Rendre la collection publique",
+ "make_collection_public_checkbox": "Faire de cette collection une collection publique",
+ "make_collection_public_desc": "Cela permettra à n'importe qui de consulter cette collection et ses utilisateurs.",
+ "sharable_link_guide": "Lien partageable (Cliquez pour copier)",
+ "copied": "Copié!",
+ "members": "Membres",
+ "members_username_placeholder": "Nom d'utilisateur (sans le '@')",
+ "owner": "Propriétaire",
+ "admin": "Administrateur",
+ "contributor": "Contributeur",
+ "viewer": "Visualiseur",
+ "viewer_desc": "Accès en lecture seule",
+ "contributor_desc": "Peut consulter et créer des liens",
+ "admin_desc": "Accès complet à tous les liens",
+ "remove_member": "Supprimer le membre",
+ "placeholder_example_collection": "Par exemple: Exemple de collection",
+ "placeholder_collection_purpose": "L'objectif de cette collection...",
+ "deleting_user": "Suppression...",
+ "user_deleted": "Utilisateur supprimé.",
+ "delete_user": "Supprimer l'utilisateur",
+ "confirm_user_deletion": "Êtes-vous sûr de vouloir supprimer cet utilisateur ?",
+ "irreversible_action_warning": "Cette action est irréversible !",
+ "delete_confirmation": "Supprimer, je sais ce que je fais",
+ "delete_link": "Supprimer le lien",
+ "deleted": "Supprimé.",
+ "link_deletion_confirmation_message": "Êtes-vous sûr de vouloir supprimer ce lien ?",
+ "warning": "Attention",
+ "irreversible_warning": "Cette action est irréversible !",
+ "shift_key_tip": "Maintenez la touche Majuscule enfoncée tout en cliquant sur « Supprimer » pour éviter cette confirmation à l'avenir.",
+ "deleting_collection": "Suppression...",
+ "collection_deleted": "Collection supprimée.",
+ "confirm_deletion_prompt": "Pour confirmer, tapez \"{{name}}\" dans le champ ci-dessous:",
+ "type_name_placeholder": "Tapez \"{{name}}\" ici.",
+ "deletion_warning": "La suppression de cette collection effacera définitivement tout son contenu et deviendra inaccessible à tous, y compris aux membres qui y ont déjà eu accès.",
+ "leave_prompt": "Cliquez sur le bouton ci-dessous pour quitter la collection actuelle.",
+ "leave": "Quitter",
+ "edit_links": "Éditer {{count}} liens",
+ "move_to_collection": "Déplacer vers la collection",
+ "add_tags": "Ajouter des étiquettes",
+ "remove_previous_tags": "Supprimer les étiquettes précédentes",
+ "delete_links": "Supprimer {{count}} liens",
+ "links_deletion_confirmation_message": "Êtes-vous sûr de vouloir supprimer {{count}} liens ? ",
+ "warning_irreversible": "Avertissement : Cette action est irréversible !",
+ "shift_key_instruction": "Maintenez la touche « Shift » enfoncée tout en cliquant sur « Supprimer » pour éviter cette confirmation à l'avenir.",
+ "link_selection_error": "Vous n'avez pas l'autorisation de modifier ou de supprimer cet élément.",
+ "no_description": "Aucune description n'est fournie.",
+ "applying": "Appliquer...",
+ "unpin": "Épingler",
+ "pin_to_dashboard": "Épingler au tableau de bord",
+ "show_link_details": "Afficher les détails du lien",
+ "hide_link_details": "Cacher les détails du lien",
+ "link_pinned": "Lien épinglé !",
+ "link_unpinned": "Lien désépinglé !",
+ "webpage": "Page web",
+ "server_administration": "Administration du serveur",
+ "all_collections": "Toutes les collections",
+ "dashboard": "Tableau de bord",
+ "demo_title": "Démonstration uniquement",
+ "demo_desc": "Il s'agit d'une instance de démonstration de Linkwarden et les téléchargements sont désactivés.",
+ "demo_desc_2": "Si vous souhaitez tester la version complète, vous pouvez vous inscrire pour un essai gratuit à l'adresse suivante:",
+ "demo_button": "Se connecter en tant qu'utilisateur de démonstration"
+}
diff --git a/public/locales/it/common.json b/public/locales/it/common.json
new file mode 100644
index 0000000..e3ae533
--- /dev/null
+++ b/public/locales/it/common.json
@@ -0,0 +1,371 @@
+{
+ "user_administration": "Amministrazione Utenti",
+ "search_users": "Cerca Utenti",
+ "no_users_found": "Nessun utente trovato.",
+ "no_user_found_in_search": "Nessun utente trovato con la query di ricerca specificata.",
+ "username": "Nome utente",
+ "email": "Email",
+ "subscribed": "Iscritto",
+ "created_at": "Creato il",
+ "not_available": "N/D",
+ "check_your_email": "Per favore controlla la tua email",
+ "authenticating": "Autenticazione in corso...",
+ "verification_email_sent": "Email di verifica inviata.",
+ "verification_email_sent_desc": "Un link di accesso è stato inviato al tuo indirizzo email. Se non vedi l'email, controlla la cartella dello spam.",
+ "resend_email": "Reinvia Email",
+ "invalid_credentials": "Credenziali non valide.",
+ "fill_all_fields": "Per favore compila tutti i campi.",
+ "enter_credentials": "Inserisci le tue credenziali",
+ "username_or_email": "Nome utente o Email",
+ "password": "Password",
+ "confirm_password": "Conferma Password",
+ "forgot_password": "Password dimenticata?",
+ "login": "Accedi",
+ "or_continue_with": "O continua con",
+ "new_here": "Nuovo qui?",
+ "sign_up": "Registrati",
+ "sign_in_to_your_account": "Accedi al tuo account",
+ "dashboard_desc": "Una breve panoramica dei tuoi dati",
+ "link": "Link",
+ "links": "Links",
+ "collection": "Collezione",
+ "collections": "Collezioni",
+ "tag": "Tag",
+ "tags": "Tags",
+ "recent": "Recenti",
+ "recent_links_desc": "Link aggiunti di recente",
+ "view_all": "Vedi tutti",
+ "view_added_links_here": "Visualizza i tuoi Link aggiunti di recente qui!",
+ "view_added_links_here_desc": "Questa sezione mostrerà i tuoi ultimi Link aggiunti in tutte le Collezioni a cui hai accesso.",
+ "add_link": "Aggiungi Nuovo Link",
+ "import_links": "Importa Links",
+ "from_linkwarden": "Da Linkwarden",
+ "from_html": "Da file HTML dei segnalibri",
+ "from_wallabag": "Da Wallabag (file JSON)",
+ "pinned": "Fissati",
+ "pinned_links_desc": "I tuoi Link fissati",
+ "pin_favorite_links_here": "Fissa i tuoi Link preferiti qui!",
+ "pin_favorite_links_here_desc": "Puoi fissare i tuoi Link preferiti cliccando sui tre puntini su ogni Link e selezionando Fissa alla Dashboard.",
+ "sending_password_link": "Invio del link per il recupero della password...",
+ "password_email_prompt": "Inserisci la tua email per inviarti un link per creare una nuova password.",
+ "send_reset_link": "Invia Link di Reset",
+ "reset_email_sent_desc": "Controlla la tua email per un link per reimpostare la password. Se non appare entro pochi minuti, controlla la cartella dello spam.",
+ "back_to_login": "Torna al Login",
+ "email_sent": "Email Inviata!",
+ "passwords_mismatch": "Le password non corrispondono.",
+ "password_too_short": "Le password devono essere di almeno 8 caratteri.",
+ "creating_account": "Creazione dell'Account in corso...",
+ "account_created": "Account Creato!",
+ "trial_offer_desc": "Sblocca {{count}} giorni di Servizio Premium gratuitamente!",
+ "register_desc": "Crea un nuovo account",
+ "registration_disabled_desc": "La registrazione è disabilitata per questa istanza, contatta l'amministratore in caso di problemi.",
+ "enter_details": "Inserisci i tuoi dettagli",
+ "display_name": "Nome visualizzato",
+ "sign_up_agreement": "Registrandoti, accetti i nostri <0>Termini di Servizio0> e la <1>Privacy Policy1>.",
+ "need_help": "Hai bisogno di aiuto?",
+ "get_in_touch": "Contattaci",
+ "already_registered": "Hai già un account?",
+ "deleting_selections": "Eliminazione delle selezioni in corso...",
+ "links_deleted": "{{count}} Link eliminati.",
+ "link_deleted": "1 Link eliminato.",
+ "links_selected": "{{count}} Link selezionati",
+ "link_selected": "1 Link selezionato",
+ "nothing_selected": "Nessuna selezione",
+ "edit": "Modifica",
+ "delete": "Elimina",
+ "nothing_found": "Nessun risultato trovato.",
+ "redirecting_to_stripe": "Reindirizzamento a Stripe...",
+ "subscribe_title": "Abbonati a Linkwarden!",
+ "subscribe_desc": "Sarai reindirizzato a Stripe, non esitare a contattarci a <0>support@linkwarden.app0> in caso di problemi.",
+ "monthly": "Mensile",
+ "yearly": "Annuale",
+ "discount_percent": "{{percent}}% di sconto",
+ "billed_monthly": "Fatturato mensilmente",
+ "billed_yearly": "Fatturato annualmente",
+ "total": "Totale",
+ "total_annual_desc": "Prova gratuita di {{count}} giorni, poi ${{annualPrice}} all'anno",
+ "total_monthly_desc": "Prova gratuita di {{count}} giorni, poi ${{monthlyPrice}} al mese",
+ "plus_tax": "+ IVA se applicabile",
+ "complete_subscription": "Completa Abbonamento",
+ "sign_out": "Esci",
+ "access_tokens": "Token di Accesso",
+ "access_tokens_description": "I Token di Accesso possono essere utilizzati per accedere a Linkwarden da altre app e servizi senza dover fornire il tuo Nome utente e Password.",
+ "new_token": "Nuovo Token di Accesso",
+ "name": "Nome",
+ "created_success": "Creato con successo!",
+ "created": "Creato",
+ "expires": "Scade",
+ "accountSettings": "Impostazioni Account",
+ "language": "Lingua",
+ "profile_photo": "Foto Profilo",
+ "upload_new_photo": "Carica una nuova foto...",
+ "remove_photo": "Rimuovi Foto",
+ "make_profile_private": "Rendi il profilo privato",
+ "profile_privacy_info": "Questo limiterà chi può trovarti e aggiungerti a nuove Collezioni.",
+ "whitelisted_users": "Utenti nella lista bianca",
+ "whitelisted_users_info": "Per favore fornisci il Nome utente degli utenti a cui desideri concedere la visibilità del tuo profilo. Separati da virgola.",
+ "whitelisted_users_placeholder": "Il tuo profilo è nascosto a tutti in questo momento...",
+ "save_changes": "Salva Modifiche",
+ "import_export": "Importa & Esporta",
+ "import_data": "Importa i tuoi dati da altre piattaforme.",
+ "download_data": "Scarica i tuoi dati istantaneamente.",
+ "export_data": "Esporta Dati",
+ "delete_account": "Elimina Account",
+ "delete_account_warning": "Questo eliminerà permanentemente TUTTI i Link, le Collezioni, i Tag e i dati archiviati di tua proprietà.",
+ "cancel_subscription_notice": "Cancellerà anche il tuo abbonamento.",
+ "account_deletion_page": "Pagina di eliminazione dell'account",
+ "applying_settings": "Applicazione delle impostazioni in corso...",
+ "settings_applied": "Impostazioni Applicate!",
+ "email_change_request": "Richiesta di cambio email inviata. Per favore verifica il nuovo indirizzo email.",
+ "image_upload_no_file_error": "Nessun file selezionato. Scegli un'immagine da caricare.",
+ "image_upload_size_error": "Per favore seleziona un file PNG o JPEG di dimensioni inferiori a 1MB.",
+ "image_upload_format_error": "Formato file non valido.",
+ "importing_bookmarks": "Importazione dei segnalibri in corso...",
+ "import_success": "Segnalibri importati! Ricaricamento della pagina...",
+ "more_coming_soon": "Altro in arrivo presto!",
+ "billing_settings": "Impostazioni di Fatturazione",
+ "manage_subscription_intro": "Per gestire/cancellare il tuo abbonamento, visita il",
+ "billing_portal": "Portale di Fatturazione",
+ "help_contact_intro": "Se hai ancora bisogno di aiuto o hai riscontrato problemi, non esitare a contattarci a:",
+ "fill_required_fields": "Per favore compila i campi obbligatori.",
+ "deleting_message": "Eliminazione di tutto in corso, attendere prego...",
+ "delete_warning": "Questo eliminerà permanentemente tutti i Link, le Collezioni, i Tag e i dati archiviati di tua proprietà. Ti disconnetterà anche. Questa azione è irreversibile!",
+ "optional": "Opzionale",
+ "feedback_help": "(ma ci aiuta davvero a migliorare!)",
+ "reason_for_cancellation": "Motivo della cancellazione",
+ "please_specify": "Per favore specifica",
+ "customer_service": "Servizio Clienti",
+ "low_quality": "Bassa Qualità",
+ "missing_features": "Funzionalità Mancanti",
+ "switched_service": "Cambiato Servizio",
+ "too_complex": "Troppo Complesso",
+ "too_expensive": "Troppo Costoso",
+ "unused": "Non Utilizzato",
+ "other": "Altro",
+ "more_information": "Ulteriori informazioni (più dettagli fornisci, più utile sarà)",
+ "feedback_placeholder": "es. Avevo bisogno di una funzionalità che...",
+ "delete_your_account": "Elimina il Tuo Account",
+ "change_password": "Cambia Password",
+ "password_length_error": "Le password devono essere di almeno 8 caratteri.",
+ "applying_changes": "Applicazione in corso...",
+ "password_change_instructions": "Per cambiare la tua password, compila quanto segue. La tua password dovrebbe essere di almeno 8 caratteri.",
+ "old_password": "Vecchia Password",
+ "new_password": "Nuova Password",
+ "preference": "Preferenza",
+ "select_theme": "Seleziona Tema",
+ "dark": "Scuro",
+ "light": "Chiaro",
+ "archive_settings": "Impostazioni di Archiviazione",
+ "formats_to_archive": "Formati per archiviare/preservare le pagine web:",
+ "screenshot": "Screenshot",
+ "pdf": "PDF",
+ "archive_org_snapshot": "Snapshot di Archive.org",
+ "link_settings": "Impostazioni Link",
+ "prevent_duplicate_links": "Previeni link duplicati",
+ "clicking_on_links_should": "Cliccando sui Link si dovrebbe:",
+ "open_original_content": "Aprire il contenuto originale",
+ "open_pdf_if_available": "Aprire PDF, se disponibile",
+ "open_readable_if_available": "Aprire versione leggibile, se disponibile",
+ "open_screenshot_if_available": "Aprire Screenshot, se disponibile",
+ "open_webpage_if_available": "Aprire copia della pagina web, se disponibile",
+ "tag_renamed": "Tag rinominato!",
+ "tag_deleted": "Tag eliminato!",
+ "rename_tag": "Rinomina Tag",
+ "delete_tag": "Elimina Tag",
+ "list_created_with_linkwarden": "Lista creata con Linkwarden",
+ "by_author": "Di {{author}}.",
+ "by_author_and_other": "Di {{author}} e {{count}} altro.",
+ "by_author_and_others": "Di {{author}} e {{count}} altri.",
+ "search_count_link": "Cerca {{count}} Link",
+ "search_count_links": "Cerca {{count}} Links",
+ "collection_is_empty": "Questa Collezione è vuota...",
+ "all_links": "Tutti i Link",
+ "all_links_desc": "Link da ogni Collezione",
+ "you_have_not_added_any_links": "Non hai ancora creato alcun Link",
+ "collections_you_own": "Collezioni di tua proprietà",
+ "new_collection": "Nuova Collezione",
+ "other_collections": "Altre Collezioni",
+ "other_collections_desc": "Collezioni condivise di cui sei membro",
+ "showing_count_results": "Mostrati {{count}} risultati",
+ "showing_count_result": "Mostrato {{count}} risultato",
+ "edit_collection_info": "Modifica Info Collezione",
+ "share_and_collaborate": "Condividi e Collabora",
+ "view_team": "Visualizza Team",
+ "team": "Team",
+ "create_subcollection": "Crea Sotto-Collezione",
+ "delete_collection": "Elimina Collezione",
+ "leave_collection": "Lascia Collezione",
+ "email_verified_signing_out": "Email verificata. Disconnessione in corso...",
+ "invalid_token": "Token non valido.",
+ "sending_password_recovery_link": "Invio del link per il recupero della password in corso...",
+ "please_fill_all_fields": "Per favore compila tutti i campi.",
+ "password_updated": "Password Aggiornata!",
+ "reset_password": "Reimposta Password",
+ "enter_email_for_new_password": "Inserisci la tua email per inviarti un link per creare una nuova password.",
+ "update_password": "Aggiorna Password",
+ "password_successfully_updated": "La tua password è stata aggiornata con successo.",
+ "user_already_member": "L'utente esiste già.",
+ "you_are_already_collection_owner": "Sei già il proprietario della collezione.",
+ "date_newest_first": "Data (Più recente prima)",
+ "date_oldest_first": "Data (Più vecchio prima)",
+ "name_az": "Nome (A-Z)",
+ "name_za": "Nome (Z-A)",
+ "description_az": "Descrizione (A-Z)",
+ "description_za": "Descrizione (Z-A)",
+ "all_rights_reserved": "© {{date}} <0>Linkwarden0>. Tutti i diritti riservati.",
+ "you_have_no_collections": "Non hai Collezioni...",
+ "you_have_no_tags": "Non hai Tag...",
+ "cant_change_collection_you_dont_own": "Non puoi apportare modifiche a una collezione di cui non sei proprietario.",
+ "account": "Account",
+ "billing": "Fatturazione",
+ "linkwarden_version": "Linkwarden {{version}}",
+ "help": "Aiuto",
+ "github": "GitHub",
+ "twitter": "Twitter",
+ "mastodon": "Mastodon",
+ "link_preservation_in_queue": "La preservazione del Link è attualmente in coda",
+ "check_back_later": "Per favore controlla più tardi per vedere il risultato",
+ "there_are_more_formats": "Ci sono altri formati preservati in coda",
+ "settings": "Impostazioni",
+ "switch_to": "Passa a {{theme}}",
+ "logout": "Esci",
+ "start_journey": "Inizia il tuo viaggio creando un nuovo Link!",
+ "create_new_link": "Crea Nuovo Link",
+ "new_link": "Nuovo Link",
+ "create_new": "Crea Nuovo...",
+ "pwa_install_prompt": "Installa Linkwarden sulla tua schermata iniziale per un accesso più rapido e un'esperienza migliore. <0>Scopri di più0>",
+ "full_content": "Contenuto Completo",
+ "slower": "Più lento",
+ "new_version_announcement": "Scopri le novità in <0>Linkwarden {{version}}!0>",
+ "creating": "Creazione in corso...",
+ "upload_file": "Carica File",
+ "file": "File",
+ "file_types": "PDF, PNG, JPG (Fino a {{size}} MB)",
+ "description": "Descrizione",
+ "auto_generated": "Sarà generato automaticamente se non viene fornito nulla.",
+ "example_link": "es. Link di Esempio",
+ "hide": "Nascondi",
+ "more": "Altro",
+ "options": "Opzioni",
+ "description_placeholder": "Note, pensieri, ecc.",
+ "deleting": "Eliminazione in corso...",
+ "token_revoked": "Token Revocato.",
+ "revoke_token": "Revoca Token",
+ "revoke_confirmation": "Sei sicuro di voler revocare questo Token di Accesso? Qualsiasi app o servizio che utilizza questo token non sarà più in grado di accedere a Linkwarden utilizzandolo.",
+ "revoke": "Revoca",
+ "sending_request": "Invio richiesta...",
+ "link_being_archived": "Il Link è in fase di archiviazione...",
+ "preserved_formats": "Formati Preservati",
+ "available_formats": "I seguenti formati sono disponibili per questo link:",
+ "readable": "Leggibile",
+ "preservation_in_queue": "La preservazione del Link è in coda",
+ "view_latest_snapshot": "Visualizza l'ultimo snapshot su archive.org",
+ "refresh_preserved_formats": "Aggiorna Formati Preservati",
+ "this_deletes_current_preservations": "Questo elimina le preservazioni attuali",
+ "create_new_user": "Crea Nuovo Utente",
+ "placeholder_johnny": "Johnny",
+ "placeholder_email": "johnny@esempio.com",
+ "placeholder_john": "john",
+ "user_created": "Utente Creato!",
+ "fill_all_fields_error": "Per favore compila tutti i campi.",
+ "password_change_note": "<0>Nota:0> Assicurati di informare l'utente che deve cambiare la propria password.",
+ "create_user": "Crea Utente",
+ "creating_token": "Creazione Token in corso...",
+ "token_created": "Token Creato!",
+ "access_token_created": "Token di Accesso Creato",
+ "token_creation_notice": "Il tuo nuovo token è stato creato. Per favore copialo e conservalo in un luogo sicuro. Non sarai in grado di vederlo di nuovo.",
+ "copied_to_clipboard": "Copiato negli appunti!",
+ "copy_to_clipboard": "Copia negli Appunti",
+ "create_access_token": "Crea un Token di Accesso",
+ "expires_in": "Scade tra",
+ "token_name_placeholder": "es. Per la scorciatoia iOS",
+ "create_token": "Crea Token di Accesso",
+ "7_days": "7 Giorni",
+ "30_days": "30 Giorni",
+ "60_days": "60 Giorni",
+ "90_days": "90 Giorni",
+ "no_expiration": "Nessuna Scadenza",
+ "creating_link": "Creazione link in corso...",
+ "link_created": "Link creato!",
+ "link_name_placeholder": "Sarà generato automaticamente se lasciato vuoto.",
+ "link_url_placeholder": "es. http://esempio.com/",
+ "link_description_placeholder": "Note, pensieri, ecc.",
+ "more_options": "Più Opzioni",
+ "hide_options": "Nascondi Opzioni",
+ "create_link": "Crea Link",
+ "new_sub_collection": "Nuova Sotto-Collezione",
+ "for_collection": "Per {{name}}",
+ "create_new_collection": "Crea una Nuova Collezione",
+ "color": "Colore",
+ "reset": "Ripristina",
+ "collection_name_placeholder": "es. Collezione di Esempio",
+ "collection_description_placeholder": "Lo scopo di questa Collezione...",
+ "create_collection_button": "Crea Collezione",
+ "password_change_warning": "Per favore conferma la tua password prima di cambiare il tuo indirizzo email.",
+ "stripe_update_note": "L'aggiornamento di questo campo cambierà anche la tua email di fatturazione su Stripe.",
+ "sso_will_be_removed_warning": "Se cambi il tuo indirizzo email, tutte le connessioni SSO {{service}} esistenti verranno rimosse.",
+ "old_email": "Vecchia Email",
+ "new_email": "Nuova Email",
+ "confirm": "Conferma",
+ "edit_link": "Modifica Link",
+ "updating": "Aggiornamento in corso...",
+ "updated": "Aggiornato!",
+ "placeholder_example_link": "es. Link di Esempio",
+ "make_collection_public": "Rendi la Collezione Pubblica",
+ "make_collection_public_checkbox": "Rendi questa una collezione pubblica",
+ "make_collection_public_desc": "Questo permetterà a chiunque di visualizzare questa collezione e i suoi utenti.",
+ "sharable_link_guide": "Link Condivisibile (Clicca per copiare)",
+ "copied": "Copiato!",
+ "members": "Membri",
+ "members_username_placeholder": "Nome utente (senza '@')",
+ "owner": "Proprietario",
+ "admin": "Amministratore",
+ "contributor": "Collaboratore",
+ "viewer": "Visualizzatore",
+ "viewer_desc": "Accesso in sola lettura",
+ "contributor_desc": "Può visualizzare e creare Link",
+ "admin_desc": "Accesso completo a tutti i Link",
+ "remove_member": "Rimuovi Membro",
+ "placeholder_example_collection": "es. Collezione di Esempio",
+ "placeholder_collection_purpose": "Lo scopo di questa Collezione...",
+ "deleting_user": "Eliminazione in corso...",
+ "user_deleted": "Utente Eliminato.",
+ "delete_user": "Elimina Utente",
+ "confirm_user_deletion": "Sei sicuro di voler rimuovere questo utente?",
+ "irreversible_action_warning": "Questa azione è irreversibile!",
+ "delete_confirmation": "Elimina, so cosa sto facendo",
+ "delete_link": "Elimina Link",
+ "deleted": "Eliminato.",
+ "link_deletion_confirmation_message": "Sei sicuro di voler eliminare questo Link?",
+ "warning": "Attenzione",
+ "irreversible_warning": "Questa azione è irreversibile!",
+ "shift_key_tip": "Tieni premuto il tasto Shift mentre clicchi su 'Elimina' per evitare questa conferma in futuro.",
+ "deleting_collection": "Eliminazione in corso...",
+ "collection_deleted": "Collezione Eliminata.",
+ "confirm_deletion_prompt": "Per confermare, digita \"{{name}}\" nella casella sottostante:",
+ "type_name_placeholder": "Digita \"{{name}}\" Qui.",
+ "deletion_warning": "L'eliminazione di questa collezione cancellerà permanentemente tutti i suoi contenuti e diventerà inaccessibile a tutti, inclusi i membri con accesso precedente.",
+ "leave_prompt": "Clicca il pulsante sottostante per lasciare la collezione corrente.",
+ "leave": "Lascia",
+ "edit_links": "Modifica {{count}} Link",
+ "move_to_collection": "Sposta nella Collezione",
+ "add_tags": "Aggiungi Tag",
+ "remove_previous_tags": "Rimuovi tag precedenti",
+ "delete_links": "Elimina {{count}} Link",
+ "links_deletion_confirmation_message": "Sei sicuro di voler eliminare {{count}} Link? ",
+ "warning_irreversible": "Attenzione: Questa azione è irreversibile!",
+ "shift_key_instruction": "Tieni premuto il tasto 'Shift' mentre clicchi su 'Elimina' per evitare questa conferma in futuro.",
+ "link_selection_error": "Non hai il permesso di modificare o eliminare questo elemento.",
+ "no_description": "Nessuna descrizione fornita.",
+ "applying": "Applicazione in corso...",
+ "unpin": "Rimuovi fissaggio",
+ "pin_to_dashboard": "Fissa alla Dashboard",
+ "show_link_details": "Mostra Dettagli Link",
+ "hide_link_details": "Nascondi Dettagli Link",
+ "link_pinned": "Link Fissato!",
+ "link_unpinned": "Fissaggio Link Rimosso!",
+ "webpage": "Pagina web",
+ "server_administration": "Amministrazione Server",
+ "all_collections": "Tutte le Collezioni",
+ "dashboard": "Dashboard"
+}
\ No newline at end of file
diff --git a/public/locales/ja/common.json b/public/locales/ja/common.json
new file mode 100644
index 0000000..dfc8c33
--- /dev/null
+++ b/public/locales/ja/common.json
@@ -0,0 +1,397 @@
+{
+ "user_administration": "ユーザー管理",
+ "search_users": "ユーザーを検索",
+ "no_users_found": "ユーザーが見つかりません",
+ "no_user_found_in_search": "指定された検索クエリでユーザーが見つかりませんでした。",
+ "username": "ユーザー名",
+ "email": "メール",
+ "subscribed": "登録済",
+ "created_at": "作成日",
+ "not_available": "N/A",
+ "check_your_email": "メールを確認してください",
+ "authenticating": "認証中...",
+ "verification_email_sent": "確認メールが送信されました。",
+ "verification_email_sent_desc": "サインインリンクがあなたのメールアドレスに送信されました。メールが見つからない場合は、迷惑メールフォルダを確認してください。",
+ "resend_email": "メールを再送",
+ "invalid_credentials": "無効な資格情報です。",
+ "fill_all_fields": "すべての項目を入力してください",
+ "enter_credentials": "資格情報を入力してください",
+ "username_or_email": "ユーザー名またはメール",
+ "password": "パスワード",
+ "confirm_password": "パスワードを確認",
+ "forgot_password": "パスワードをお忘れですか?",
+ "login": "ログイン",
+ "or_continue_with": "または次で続行",
+ "new_here": "初めてですか?",
+ "sign_up": "サインアップ",
+ "sign_in_to_your_account": "アカウントにサインイン",
+ "dashboard_desc": "データの概要",
+ "link": "リンク",
+ "links": "リンク",
+ "collection": "コレクション",
+ "collections": "コレクション",
+ "tag": "タグ",
+ "tags": "タグ",
+ "recent": "最近",
+ "recent_links_desc": "最近追加されたリンク",
+ "view_all": "すべて表示",
+ "view_added_links_here": "ここで最近追加されたリンクを表示!",
+ "view_added_links_here_desc": "このセクションでは、アクセス可能なすべてのコレクションにわたって最近追加されたリンクが表示されます。",
+ "add_link": "新しいリンクを追加",
+ "import_links": "リンクをインポート",
+ "from_linkwarden": "Linkwardenから",
+ "from_html": "ブックマークHTMLファイルから",
+ "from_wallabag": "Wallabag (JSON file)から",
+ "pinned": "ピン留め",
+ "pinned_links_desc": "ピン留めされたリンク",
+ "pin_favorite_links_here": "お気に入りのリンクをここにピン留め!",
+ "pin_favorite_links_here_desc": "各リンクの三点リーダーをクリックして、[ダッシュボードにピン留め]をクリックすることで、お気に入りのリンクをピン留めできます。",
+ "sending_password_link": "パスワード回復リンクを送信中...",
+ "password_email_prompt": "新しいパスワードを作成するためのリンクを送信できるように、メールを入力してください。",
+ "send_reset_link": "リセットリンクを送信",
+ "reset_email_sent_desc": "パスワードをリセットするためのリンクがメールに送信されました。数分以内に表示されない場合は、迷惑メールフォルダを確認してください。",
+ "back_to_login": "ログインに戻る",
+ "email_sent": "メール送信済み!",
+ "passwords_mismatch": "パスワードが一致しません。",
+ "password_too_short": "パスワードは8文字以上でなければなりません。",
+ "creating_account": "アカウントを作成中...",
+ "account_created": "アカウントが作成されました!",
+ "trial_offer_desc": "{{count}} 日間のプレミアムサービスを無料でご利用いただけます!",
+ "register_desc": "新しいアカウントを作成",
+ "registration_disabled_desc": "このインスタンスでは登録が無効になっています。問題がある場合は、管理者にお問い合わせください。",
+ "enter_details": "詳細を入力してください",
+ "display_name": "表示名",
+ "sign_up_agreement": "サインアップすることにより、 <0>利用規約0> 及び <1>プライバシーポリシー1> に同意したものとします。",
+ "need_help": "ヘルプが必要ですか?",
+ "get_in_touch": "お問い合わせ",
+ "already_registered": "すでにアカウントをお持ちですか?",
+ "deleting_selections": "選択を削除中...",
+ "links_deleted": "{{count}} 個のリンクが削除されました。",
+ "link_deleted": "1個のリンクが削除されました。",
+ "links_selected": "{{count}} 個のリンクが選択されました",
+ "link_selected": "1個のリンクが選択されました",
+ "nothing_selected": "選択されていません",
+ "edit": "編集",
+ "delete": "削除",
+ "nothing_found": "見つかりませんでした。",
+ "redirecting_to_stripe": "Stripeにリダイレクトしています...",
+ "subscribe_title": "Linkwardenに登録!",
+ "subscribe_desc": "Stripeにリダイレクトされます。問題がある場合は、 <0>support@linkwarden.app0> までお問い合わせください。",
+ "monthly": "月額",
+ "yearly": "年額",
+ "discount_percent": "{{percent}}% Off",
+ "billed_monthly": "月額請求",
+ "billed_yearly": "年額請求",
+ "total": "合計",
+ "total_annual_desc": "{{count}} 日間の無料トライアル後、年間 {{annualPrice}}ドル が請求されます",
+ "total_monthly_desc": "{{count}} 日間の無料トライアル後、月額 {{monthlyPrice}}ドル が請求されます",
+ "plus_tax": "該当する場合は+税",
+ "complete_subscription": "サブスクリプションを完了",
+ "sign_out": "サインアウト",
+ "access_tokens": "アクセス トークン",
+ "access_tokens_description": "アクセス トークンは、ユーザー名とパスワードを公開することなく、他のアプリやサービスからLinkwardenにアクセスするために使用できます。",
+ "new_token": "新しいアクセス トークン",
+ "name": "名前",
+ "created_success": "作成完了!",
+ "created": "作成日",
+ "expires": "有効期限",
+ "accountSettings": "アカウント設定",
+ "language": "言語",
+ "profile_photo": "プロフィール写真",
+ "upload_new_photo": "新しい写真をアップロード...",
+ "remove_photo": "写真を削除",
+ "make_profile_private": "プロフィールを非公開にする",
+ "profile_privacy_info": "これにより、新しいコレクションを見つけたり、新しいコレクションに追加できる人が制限されます。",
+ "whitelisted_users": "ホワイトリストに登録されたユーザー",
+ "whitelisted_users_info": "あなたのプロフィールの表示を許可するユーザー名を入力してください。コンマで区切ってください。",
+ "whitelisted_users_placeholder": "現在、あなたのプロフィールはすべてのユーザーに非表示です...",
+ "save_changes": "変更を保存",
+ "import_export": "インポート&エクスポート",
+ "import_data": "他のプラットフォームからデータをインポート。",
+ "download_data": "データを即座にダウンロード。",
+ "export_data": "データをエクスポート",
+ "delete_account": "アカウントを削除",
+ "delete_account_warning": "これにより、所有しているすべてのリンク、コレクション、タグ、およびアーカイブデータが完全に削除されます。",
+ "cancel_subscription_notice": "また、サブスクリプションもキャンセルされます。",
+ "account_deletion_page": "アカウント削除ページ",
+ "applying_settings": "設定を適用中...",
+ "settings_applied": "設定が適用されました!",
+ "email_change_request": "メール変更リクエストが送信されました。新しいメールアドレスを確認してください。",
+ "image_upload_no_file_error": "ファイルが選択されていません。アップロードする画像を選んでください。",
+ "image_upload_size_error": "1MB未満のPNGまたはJPEGファイルを選択してください。",
+ "image_upload_format_error": "無効なファイル形式です。",
+ "importing_bookmarks": "ブックマークをインポート中...",
+ "import_success": "ブックマークがインポートされました!ページを再読み込み中...",
+ "more_coming_soon": "今後さらに追加予定!",
+ "billing_settings": "請求設定",
+ "manage_subscription_intro": "サブスクリプションの管理/キャンセルについては、こちらに訪問してください ",
+ "billing_portal": "請求ポータル",
+ "help_contact_intro": "まだ助けが必要な場合や問題が発生した場合は、こちらのアドレスまでお気軽にお問い合わせください:",
+ "fill_required_fields": "必須項目を入力してください",
+ "deleting_message": "すべてを削除中、お待ちください...",
+ "delete_warning": "これにより、所有しているすべてのリンク、コレクション、タグ、およびアーカイブデータが完全に削除され、ログアウトされます。この操作は取り消せません!",
+ "optional": "任意",
+ "feedback_help": "(しかし、これは私たちの改善に非常に役立ちます!)",
+ "reason_for_cancellation": "キャンセルの理由",
+ "please_specify": "具体的に記載してください",
+ "customer_service": "カスタマーサービス",
+ "low_quality": "低品質",
+ "missing_features": "機能不足",
+ "switched_service": "サービスを変更した",
+ "too_complex": "複雑すぎる",
+ "too_expensive": "高すぎる",
+ "unused": "未使用",
+ "other": "その他",
+ "more_information": "詳細情報 (詳細が多いほど役立ちます)",
+ "feedback_placeholder": "例: 私が必要だった機能は...",
+ "delete_your_account": "アカウントを削除",
+ "change_password": "パスワードを変更",
+ "password_length_error": "パスワードは8文字以上でなければなりません。",
+ "applying_changes": "適用中...",
+ "password_change_instructions": "パスワードを変更するには、以下の項目を入力してください。パスワードは少なくとも8文字以上である必要があります。",
+ "old_password": "古いパスワード",
+ "new_password": "新しいパスワード",
+ "preference": "設定",
+ "select_theme": "テーマを選択",
+ "dark": "ダーク",
+ "light": "ライト",
+ "archive_settings": "アーカイブ設定",
+ "formats_to_archive": "ウェブページをアーカイブ/保存する形式:",
+ "screenshot": "スクリーンショット",
+ "pdf": "PDF",
+ "archive_org_snapshot": "Archive.org スナップショット",
+ "link_settings": "リンク設定",
+ "prevent_duplicate_links": "重複リンクを防ぐ",
+ "clicking_on_links_should": "リンクをクリックしたときの動作:",
+ "open_original_content": "オリジナルコンテンツを開く",
+ "open_pdf_if_available": "可能な場合はPDFを開く",
+ "open_readable_if_available": "可能な場合はリーダブルを開く",
+ "open_screenshot_if_available": "可能な場合はスクリーンショットを開く",
+ "open_webpage_if_available": "可能な場合はウェブページのコピーを開く",
+ "tag_renamed": "タグがリネームされました!",
+ "tag_deleted": "タグが削除されました!",
+ "rename_tag": "タグをリネーム",
+ "delete_tag": "タグを削除",
+ "list_created_with_linkwarden": "Linkwardenで作成されたリスト",
+ "by_author": "{{author}} による。",
+ "by_author_and_other": "{{author}} と他 {{count}} 人による。",
+ "by_author_and_others": "{{author}} と他 {{count}} 人による。",
+ "search_count_link": "{{count}} リンクを検索",
+ "search_count_links": "{{count}} リンクを検索",
+ "collection_is_empty": "このコレクションは空です...",
+ "all_links": "すべてのリンク",
+ "all_links_desc": "各コレクションからのリンク",
+ "you_have_not_added_any_links": "まだリンクを作成していません",
+ "collections_you_own": "あなたが所有しているコレクション",
+ "new_collection": "新しいコレクション",
+ "other_collections": "他のコレクション",
+ "other_collections_desc": "あなたがメンバーである共有コレクション",
+ "showing_count_results": "{{count}} 件の結果を表示",
+ "showing_count_result": "{{count}} 件の結果を表示",
+ "edit_collection_info": "コレクション情報を編集",
+ "share_and_collaborate": "共有とコラボレーション",
+ "view_team": "チームを表示",
+ "team": "チーム",
+ "create_subcollection": "サブコレクションを作成",
+ "delete_collection": "コレクションを削除",
+ "leave_collection": "コレクションを離れる",
+ "email_verified_signing_out": "メールが確認されました。サインアウトします...",
+ "invalid_token": "無効なトークンです。",
+ "sending_password_recovery_link": "パスワード回復リンクを送信中...",
+ "please_fill_all_fields": "すべての項目に入力してください。",
+ "password_updated": "パスワードが更新されました!",
+ "reset_password": "パスワードをリセット",
+ "enter_email_for_new_password": "新しいパスワードを作成するためのリンクを送信するために、メールアドレスを入力してください。",
+ "update_password": "パスワードを更新",
+ "password_successfully_updated": "パスワードが正常に更新されました。",
+ "user_already_member": "ユーザーは既に存在します。",
+ "you_are_already_collection_owner": "あなたは既にコレクションの所有者です。",
+ "date_newest_first": "日付 (新しい順)",
+ "date_oldest_first": "日付 (古い順)",
+ "name_az": "名前 (A-Z)",
+ "name_za": "名前 (Z-A)",
+ "description_az": "説明 (A-Z)",
+ "description_za": "説明 (Z-A)",
+ "all_rights_reserved": "© {{date}} <0>Linkwarden0>. All rights reserved.",
+ "you_have_no_collections": "コレクションがありません...",
+ "you_have_no_tags": "タグがありません...",
+ "cant_change_collection_you_dont_own": "所有していないコレクションに変更を加えることはできません。",
+ "account": "アカウント",
+ "billing": "請求",
+ "linkwarden_version": "Linkwarden {{version}}",
+ "help": "ヘルプ",
+ "github": "GitHub",
+ "twitter": "Twitter",
+ "mastodon": "Mastodon",
+ "link_preservation_in_queue": "リンク保存がキューに追加されています",
+ "check_back_later": "後で結果を確認してください",
+ "there_are_more_formats": "さらに保存されている形式がキューにあります",
+ "settings": "設定",
+ "switch_to": "{{theme}} に切り替える",
+ "logout": "ログアウト",
+ "start_journey": "新しいリンクを作成して、旅を始めましょう!",
+ "create_new_link": "新しいリンクを作成",
+ "new_link": "新しいリンク",
+ "create_new": "新しく作成...",
+ "pwa_install_prompt": "ホーム画面にLinkwardenをインストールして、より高速で快適な体験を。 <0>詳しくはこちら0>",
+ "full_content": "全コンテンツ",
+ "slower": "遅い",
+ "new_version_announcement": "新しいバージョンの <0>Linkwarden {{version}}0> をご覧ください!",
+ "creating": "作成中...",
+ "upload_file": "ファイルをアップロード",
+ "file": "ファイル",
+ "file_types": "PDF, PNG, JPG (最大 {{size}} MB)",
+ "description": "説明",
+ "auto_generated": "何も入力されない場合、自動生成されます。",
+ "example_link": "例: サンプルリンク",
+ "hide": "隠す",
+ "more": "詳細",
+ "options": "オプション",
+ "description_placeholder": "メモ、考えなど",
+ "deleting": "削除中...",
+ "token_revoked": "トークンが無効化されました。",
+ "revoke_token": "トークンを無効化",
+ "revoke_confirmation": "このアクセス トークンを無効化してもよろしいですか?このトークンを使用しているアプリやサービスは、Linkwardenにアクセスできなくなります。",
+ "revoke": "無効化",
+ "sending_request": "リクエストを送信中...",
+ "link_being_archived": "リンクがアーカイブされています...",
+ "preserved_formats": "保存された形式",
+ "available_formats": "このリンクには以下の形式が利用可能です:",
+ "readable": "リーダブル",
+ "preservation_in_queue": "リンクの保存がキューに追加されています",
+ "view_latest_snapshot": "archive.org で最新のスナップショットを見る",
+ "refresh_preserved_formats": "保存形式を更新",
+ "this_deletes_current_preservations": "これにより現在の保存データが削除されます",
+ "create_new_user": "新しいユーザーを作成",
+ "placeholder_johnny": "ジョニー",
+ "placeholder_email": "johnny@example.com",
+ "placeholder_john": "ジョン",
+ "user_created": "ユーザーが作成されました!",
+ "fill_all_fields_error": "すべての項目に入力してください。",
+ "password_change_note": "<0>注意:0> パスワードを変更する必要があることをユーザーに知らせてください。",
+ "create_user": "ユーザーを作成",
+ "creating_token": "トークンを作成中...",
+ "token_created": "トークンが作成されました!",
+ "access_token_created": "アクセス トークンが作成されました",
+ "token_creation_notice": "新しいトークンが作成されました。コピーして安全な場所に保管してください。再度表示することはできません。",
+ "copied_to_clipboard": "クリップボードにコピーされました!",
+ "copy_to_clipboard": "クリップボードにコピー",
+ "create_access_token": "アクセス トークンを作成",
+ "expires_in": "有効期限",
+ "token_name_placeholder": "例: iOSショートカット用",
+ "create_token": "アクセス トークンを作成",
+ "7_days": "7 日間",
+ "30_days": "30 日間",
+ "60_days": "60 日間",
+ "90_days": "90 日間",
+ "no_expiration": "有効期限なし",
+ "creating_link": "リンクを作成中...",
+ "link_created": "リンクが作成されました!",
+ "link_name_placeholder": "空白のままにすると自動生成されます。",
+ "link_url_placeholder": "例: http://example.com/",
+ "link_description_placeholder": "メモ、考えなど",
+ "more_options": "詳細オプション",
+ "hide_options": "オプションを隠す",
+ "create_link": "リンクを作成",
+ "new_sub_collection": "新しいサブコレクション",
+ "for_collection": "{{name}} 用",
+ "create_new_collection": "新しいコレクションを作成",
+ "color": "カラー",
+ "reset_defaults": "デフォルトにリセット",
+ "updating_collection": "コレクションを更新中...",
+ "collection_name_placeholder": "例: サンプルコレクション",
+ "collection_description_placeholder": "このコレクションの目的...",
+ "create_collection_button": "コレクションを作成",
+ "password_change_warning": "メールアドレスを変更する前にパスワードを確認してください。",
+ "stripe_update_note": " このフィールドを更新すると、Stripe上の請求先メールも変更されます。",
+ "sso_will_be_removed_warning": "メールアドレスを変更すると、既存の {{service}} SSO接続が解除されます。",
+ "old_email": "旧メールアドレス",
+ "new_email": "新しいメールアドレス",
+ "confirm": "確認",
+ "edit_link": "リンクを編集",
+ "updating": "更新中...",
+ "updated": "更新されました!",
+ "placeholder_example_link": "例: サンプルリンク",
+ "make_collection_public": "コレクションを公開",
+ "make_collection_public_checkbox": "このコレクションを公開する",
+ "make_collection_public_desc": "これにより、誰でもこのコレクションとそのユーザーを閲覧できるようになります。",
+ "sharable_link_guide": "共有リンク (クリックしてコピー)",
+ "copied": "コピーされました!",
+ "members": "メンバー",
+ "members_username_placeholder": "ユーザー名 ('@' を含まない)",
+ "owner": "所有者",
+ "admin": "管理者",
+ "contributor": "コントリビューター",
+ "viewer": "閲覧者",
+ "viewer_desc": "読み取り専用アクセス",
+ "contributor_desc": "リンクを閲覧および作成可能",
+ "admin_desc": "すべてのリンクにフルアクセス",
+ "remove_member": "メンバーを削除",
+ "placeholder_example_collection": "例: サンプルコレクション",
+ "placeholder_collection_purpose": "このコレクションの目的...",
+ "deleting_user": "削除中...",
+ "user_deleted": "ユーザーが削除されました。",
+ "delete_user": "ユーザーを削除",
+ "confirm_user_deletion": "このユーザーを削除してもよろしいですか?",
+ "irreversible_action_warning": "この操作は取り消せません!",
+ "delete_confirmation": "削除する、私はこの操作を理解しています",
+ "delete_link": "リンクを削除",
+ "deleted": "削除されました。",
+ "link_deletion_confirmation_message": "このリンクを削除してもよろしいですか?",
+ "warning": "警告",
+ "irreversible_warning": "この操作は取り消せません!",
+ "shift_key_tip": "Shiftキーを押しながら「削除」をクリックすると、今後この確認をスキップできます。",
+ "deleting_collection": "削除中...",
+ "collection_deleted": "コレクションが削除されました。",
+ "confirm_deletion_prompt": "確認のため、以下のボックスに \"{{name}}\" と入力してください:",
+ "type_name_placeholder": "ここに \"{{name}}\" を入力してください。",
+ "deletion_warning": "このコレクションを削除すると、そのすべての内容が永久に消去され、以前アクセス可能だったメンバーを含め、誰もアクセスできなくなります。",
+ "leave_prompt": "現在のコレクションから離れるには、以下のボタンをクリックしてください。",
+ "leave": "離れる",
+ "edit_links": "{{count}} リンクを編集",
+ "move_to_collection": "コレクションに移動",
+ "add_tags": "タグを追加",
+ "remove_previous_tags": "以前のタグを削除",
+ "delete_links": "{{count}} リンクを削除",
+ "links_deletion_confirmation_message": "{{count}} リンクを削除してもよろしいですか? ",
+ "warning_irreversible": "警告:この操作は取り消せません!",
+ "shift_key_instruction": "Shiftキーを押しながら「削除」をクリックすると、今後この確認をスキップできます。",
+ "link_selection_error": "この項目を編集または削除する権限がありません。",
+ "no_description": "説明が提供されていません。",
+ "applying": "適用中...",
+ "unpin": "ピンを外す",
+ "pin_to_dashboard": "ダッシュボードにピン留め",
+ "show_link_details": "リンクの詳細を表示",
+ "link_pinned": "リンクがピン留めされました!",
+ "link_unpinned": "リンクのピンが外れました!",
+ "webpage": "ウェブページ",
+ "server_administration": "サーバー管理",
+ "all_collections": "すべてのコレクション",
+ "dashboard": "ダッシュボード",
+ "demo_title": "デモ専用",
+ "demo_desc": "これはLinkwardenのデモインスタンスであり、アップロードは無効になっています。",
+ "demo_desc_2": "完全版を試したい場合は、以下で無料トライアルにサインアップできます:",
+ "demo_button": "デモユーザーとしてログイン",
+ "regular": "通常",
+ "thin": "細字",
+ "bold": "太字",
+ "fill": "塗りつぶし",
+ "duotone": "デュオトーン(2色)",
+ "light_icon": "軽量",
+ "search": "検索",
+ "set_custom_icon": "カスタムアイコンを設定",
+ "view": "閲覧",
+ "show": "表示",
+ "image": "画像",
+ "icon": "アイコン",
+ "date": "日付",
+ "preview_unavailable": "プレビューが利用できません",
+ "saved": "保存済み",
+ "untitled": "無題",
+ "no_tags": "タグなし",
+ "no_description_provided": "説明が提供されていません",
+ "change_icon": "アイコンを変更",
+ "upload_preview_image": "プレビュー画像をアップロード",
+ "columns": "列",
+ "default": "デフォルト"
+}
\ No newline at end of file
diff --git a/public/locales/nl/common.json b/public/locales/nl/common.json
new file mode 100644
index 0000000..a1d3800
--- /dev/null
+++ b/public/locales/nl/common.json
@@ -0,0 +1,375 @@
+{
+ "user_administration": "Gebruikersbeheer",
+ "search_users": "Zoeken naar Gebruikers",
+ "no_users_found": "Geen gebruikers gevonden.",
+ "no_user_found_in_search": "Geen gebruikers gevonden met de gegeven zoekopdracht.",
+ "username": "Gebruikersnaam",
+ "email": "E-mail",
+ "subscribed": "Geabonneerd",
+ "created_at": "Aangemaakt Op",
+ "not_available": "N.V.T.",
+ "check_your_email": "Controleer uw E-mail",
+ "authenticating": "Authenticatie...",
+ "verification_email_sent": "Verificatie-e-mail verzonden.",
+ "verification_email_sent_desc": "Een inloglink is naar uw e-mailadres verzonden. Als u de e-mail niet ziet, controleer dan uw spammap.",
+ "resend_email": "E-mail Opnieuw Verzenden",
+ "invalid_credentials": "Ongeldige inloggegevens.",
+ "fill_all_fields": "Vul alle velden in.",
+ "enter_credentials": "Voer uw inloggegevens in",
+ "username_or_email": "Gebruikersnaam of E-mail",
+ "password": "Wachtwoord",
+ "confirm_password": "Bevestig Wachtwoord",
+ "forgot_password": "Wachtwoord Vergeten?",
+ "login": "Inloggen",
+ "or_continue_with": "Of ga verder met",
+ "new_here": "Nieuw hier?",
+ "sign_up": "Aanmelden",
+ "sign_in_to_your_account": "Log in op uw account",
+ "dashboard_desc": "Een kort overzicht van uw gegevens",
+ "link": "Link",
+ "links": "Links",
+ "collection": "Collectie",
+ "collections": "Collecties",
+ "tag": "Tag",
+ "tags": "Tags",
+ "recent": "Recent",
+ "recent_links_desc": "Recent Toegevoegde Links",
+ "view_all": "Bekijk Alles",
+ "view_added_links_here": "Bekijk Hier Uw Recent Toegevoegde Links!",
+ "view_added_links_here_desc": "Deze sectie toont uw laatste toegevoegde links in alle collecties waartoe u toegang hebt.",
+ "add_link": "Nieuwe Link Toevoegen",
+ "import_links": "Links Importeren",
+ "from_linkwarden": "Van Linkwarden",
+ "from_html": "Van Bladwijzers HTML-bestand",
+ "from_wallabag": "Van Wallabag (JSON-bestand)",
+ "pinned": "Vastgemaakt",
+ "pinned_links_desc": "Uw Vastgemaakte Links",
+ "pin_favorite_links_here": "Maak Hier Uw Favoriete Links Vast!",
+ "pin_favorite_links_here_desc": "U kunt uw favoriete links vastmaken door op de drie stippen op elke link te klikken en Vastmaken aan Dashboard te selecteren.",
+ "sending_password_link": "Wachtwoordherstel link verzenden...",
+ "password_email_prompt": "Voer uw e-mailadres in zodat we u een link kunnen sturen om een nieuw wachtwoord aan te maken.",
+ "send_reset_link": "Herstel Link Versturen",
+ "reset_email_sent_desc": "Controleer uw e-mail voor een link om uw wachtwoord te resetten. Als u de e-mail niet binnen enkele minuten ontvangt, controleer dan uw spammap.",
+ "back_to_login": "Terug naar Inloggen",
+ "email_sent": "E-mail Verzonden!",
+ "passwords_mismatch": "Wachtwoorden komen niet overeen.",
+ "password_too_short": "Wachtwoorden moeten minstens 8 tekens bevatten.",
+ "creating_account": "Account Aanmaken...",
+ "account_created": "Account Aangemaakt!",
+ "trial_offer_desc": "Ontgrendel {{count}} dagen Premium Service zonder kosten!",
+ "register_desc": "Maak een nieuw account aan",
+ "registration_disabled_desc": "Registratie is uitgeschakeld voor deze instantie, neem contact op met de beheerder in geval van problemen.",
+ "enter_details": "Voer uw gegevens in",
+ "display_name": "Weergavenaam",
+ "sign_up_agreement": "Door u aan te melden, gaat u akkoord met onze <0>Gebruiksvoorwaarden0> en <1>Privacybeleid1>.",
+ "need_help": "Hulp nodig?",
+ "get_in_touch": "Neem contact op",
+ "already_registered": "Heeft u al een account?",
+ "deleting_selections": "Selecties Verwijderen...",
+ "links_deleted": "{{count}} Links verwijderd.",
+ "link_deleted": "1 Link verwijderd.",
+ "links_selected": "{{count}} Links geselecteerd",
+ "link_selected": "1 Link geselecteerd",
+ "nothing_selected": "Niets geselecteerd",
+ "edit": "Bewerken",
+ "delete": "Verwijderen",
+ "nothing_found": "Niets gevonden.",
+ "redirecting_to_stripe": "Doorverwijzen naar Stripe...",
+ "subscribe_title": "Abonneer u op Linkwarden!",
+ "subscribe_desc": "U wordt doorgestuurd naar Stripe, neem gerust contact met ons op via <0>support@linkwarden.app0> in geval van problemen.",
+ "monthly": "Maandelijks",
+ "yearly": "Jaarlijks",
+ "discount_percent": "{{percent}}% Korting",
+ "billed_monthly": "Maandelijks Gefactureerd",
+ "billed_yearly": "Jaarlijks Gefactureerd",
+ "total": "Totaal",
+ "total_annual_desc": "{{count}}-dagen gratis proefperiode, daarna ${{annualPrice}} per jaar",
+ "total_monthly_desc": "{{count}}-dagen gratis proefperiode, daarna ${{monthlyPrice}} per maand",
+ "plus_tax": "+ BTW indien van toepassing",
+ "complete_subscription": "Abonnement Afronden",
+ "sign_out": "Uitloggen",
+ "access_tokens": "Toegangstokens",
+ "access_tokens_description": "Toegangstokens kunnen worden gebruikt om toegang te krijgen tot Linkwarden vanuit andere apps en services zonder uw gebruikersnaam en wachtwoord te verstrekken.",
+ "new_token": "Nieuw Toegangstoken",
+ "name": "Naam",
+ "created_success": "Aangemaakt!",
+ "created": "Aangemaakt",
+ "expires": "Verloopt",
+ "accountSettings": "Accountinstellingen",
+ "language": "Taal",
+ "profile_photo": "Profielfoto",
+ "upload_new_photo": "Upload een nieuwe foto...",
+ "remove_photo": "Foto Verwijderen",
+ "make_profile_private": "Maak profiel privé",
+ "profile_privacy_info": "Dit beperkt wie u kan vinden en toevoegen aan nieuwe collecties.",
+ "whitelisted_users": "Toegestane Gebruikers",
+ "whitelisted_users_info": "Geef alstublieft de gebruikersnaam op van de gebruikers die u zichtbaarheid wilt geven op uw profiel. Gescheiden door komma's.",
+ "whitelisted_users_placeholder": "Uw profiel is momenteel verborgen voor iedereen...",
+ "save_changes": "Wijzigingen Opslaan",
+ "import_export": "Importeren & Exporteren",
+ "import_data": "Importeer uw gegevens van andere platforms.",
+ "download_data": "Download uw gegevens direct.",
+ "export_data": "Gegevens Exporteren",
+ "delete_account": "Account Verwijderen",
+ "delete_account_warning": "Dit zal PERMANENT alle links, collecties, tags en gearchiveerde gegevens die u bezit verwijderen.",
+ "cancel_subscription_notice": "Dit zal ook uw abonnement annuleren.",
+ "account_deletion_page": "Accountverwijdering pagina",
+ "applying_settings": "Instellingen Toepassen...",
+ "settings_applied": "Instellingen Toegepast!",
+ "email_change_request": "E-mailwijzigingsverzoek verzonden. Verifieer het nieuwe e-mailadres.",
+ "image_upload_size_error": "Selecteer een PNG- of JPEG-bestand dat kleiner is dan 1 MB.",
+ "image_upload_format_error": "Ongeldig bestandsformaat.",
+ "importing_bookmarks": "Bladwijzers importeren...",
+ "import_success": "Bladwijzers geïmporteerd! Pagina opnieuw laden...",
+ "more_coming_soon": "Meer binnenkort beschikbaar!",
+ "billing_settings": "Factureringsinstellingen",
+ "manage_subscription_intro": "Beheer of annuleer uw abonnement door naar de",
+ "billing_portal": "Factureringsportaal",
+ "help_contact_intro": "Als u nog steeds hulp nodig heeft of problemen ondervindt, neem gerust contact met ons op via:",
+ "fill_required_fields": "Vul de verplichte velden in.",
+ "deleting_message": "Alles verwijderen, even geduld aub...",
+ "delete_warning": "Dit zal PERMANENT alle links, collecties, tags en gearchiveerde gegevens die u bezit verwijderen. Dit zal ook leiden tot uitloggen. Deze actie is onomkeerbaar!",
+ "optional": "Optioneel",
+ "feedback_help": "(maar het helpt ons echt om te verbeteren!)",
+ "reason_for_cancellation": "Reden voor annulering",
+ "please_specify": "Specificeer alstublieft",
+ "customer_service": "Klantenservice",
+ "low_quality": "Lage Kwaliteit",
+ "missing_features": "Ontbrekende Functies",
+ "switched_service": "Overgestapt naar andere dienst",
+ "too_complex": "Te Complex",
+ "too_expensive": "Te Duur",
+ "unused": "Ongebruikt",
+ "other": "Anders",
+ "more_information": "Meer informatie (hoe meer details, hoe nuttiger het zou zijn)",
+ "feedback_placeholder": "bijv. Ik had een functie nodig die...",
+ "delete_your_account": "Verwijder Uw Account",
+ "change_password": "Wachtwoord Wijzigen",
+ "password_length_error": "Wachtwoorden moeten minstens 8 tekens bevatten.",
+ "applying_changes": "Wijzigingen Toepassen...",
+ "password_change_instructions": "Om uw wachtwoord te wijzigen, vul alstublieft het volgende in. Uw wachtwoord moet minimaal 8 tekens bevatten.",
+ "old_password": "Oud Wachtwoord",
+ "new_password": "Nieuw Wachtwoord",
+ "preference": "Voorkeur",
+ "select_theme": "Selecteer Thema",
+ "dark": "Donker",
+ "light": "Licht",
+ "archive_settings": "Archiveringsinstellingen",
+ "formats_to_archive": "Te archiveren/behouden formaten voor webpagina's:",
+ "screenshot": "Screenshot",
+ "pdf": "PDF",
+ "archive_org_snapshot": "Archive.org Momentopname",
+ "link_settings": "Linkinstellingen",
+ "prevent_duplicate_links": "Voorkom dubbele links",
+ "clicking_on_links_should": "Klikken op links moet:",
+ "open_original_content": "Oorspronkelijke inhoud openen",
+ "open_pdf_if_available": "PDF openen, indien beschikbaar",
+ "open_readable_if_available": "Leesbare versie openen, indien beschikbaar",
+ "open_screenshot_if_available": "Screenshot openen, indien beschikbaar",
+ "open_webpage_if_available": "Webpagina kopie openen, indien beschikbaar",
+ "tag_renamed": "Tag hernoemd!",
+ "tag_deleted": "Tag verwijderd!",
+ "rename_tag": "Tag Hernoemen",
+ "delete_tag": "Tag Verwijderen",
+ "list_created_with_linkwarden": "Lijst gemaakt met Linkwarden",
+ "by_author": "Door {{author}}.",
+ "by_author_and_other": "Door {{author}} en {{count}} andere.",
+ "by_author_and_others": "Door {{author}} en {{count}} anderen.",
+ "search_count_link": "Zoek {{count}} Link",
+ "search_count_links": "Zoek {{count}} Links",
+ "collection_is_empty": "Deze Collectie is leeg...",
+ "all_links": "Alle Links",
+ "all_links_desc": "Links uit elke Collectie",
+ "you_have_not_added_any_links": "U Heeft Nog Geen Links Aangemaakt",
+ "collections_you_own": "Collecties die u bezit",
+ "new_collection": "Nieuwe Collectie",
+ "other_collections": "Andere Collecties",
+ "other_collections_desc": "Gedeelde collecties waarvan u lid bent",
+ "showing_count_results": "Toont {{count}} resultaten",
+ "showing_count_result": "Toont {{count}} resultaat",
+ "edit_collection_info": "Collectie Info Bewerken",
+ "share_and_collaborate": "Delen en Samenwerken",
+ "view_team": "Bekijk Team",
+ "team": "Team",
+ "create_subcollection": "Sub-Collectie Aanmaken",
+ "delete_collection": "Collectie Verwijderen",
+ "leave_collection": "Collectie Verlaten",
+ "email_verified_signing_out": "E-mail geverifieerd. Uitloggen...",
+ "invalid_token": "Ongeldig token.",
+ "sending_password_recovery_link": "Wachtwoordherstel link verzenden...",
+ "please_fill_all_fields": "Vul alle velden in.",
+ "password_updated": "Wachtwoord Bijgewerkt!",
+ "reset_password": "Wachtwoord Resetten",
+ "enter_email_for_new_password": "Voer uw e-mail in zodat we u een link kunnen sturen om een nieuw wachtwoord aan te maken.",
+ "update_password": "Wachtwoord Bijwerken",
+ "password_successfully_updated": "Uw wachtwoord is succesvol bijgewerkt.",
+ "user_already_member": "Gebruiker bestaat al.",
+ "you_are_already_collection_owner": "U bent al de eigenaar van de collectie.",
+ "date_newest_first": "Datum (Nieuwste Eerst)",
+ "date_oldest_first": "Datum (Oudste Eerst)",
+ "name_az": "Naam (A-Z)",
+ "name_za": "Naam (Z-A)",
+ "description_az": "Beschrijving (A-Z)",
+ "description_za": "Beschrijving (Z-A)",
+ "all_rights_reserved": "© {{date}} <0>Linkwarden0>. Alle rechten voorbehouden.",
+ "you_have_no_collections": "U heeft geen Collecties...",
+ "you_have_no_tags": "U heeft geen Tags...",
+ "cant_change_collection_you_dont_own": "U kunt geen wijzigingen aanbrengen in een collectie die u niet bezit.",
+ "account": "Account",
+ "billing": "Facturering",
+ "linkwarden_version": "Linkwarden {{version}}",
+ "help": "Hulp",
+ "github": "GitHub",
+ "twitter": "Twitter",
+ "mastodon": "Mastodon",
+ "link_preservation_in_queue": "De Linkbewaring staat momenteel in de wachtrij",
+ "check_back_later": "Kom later terug om het resultaat te bekijken",
+ "there_are_more_formats": "Er zijn meer bewaarde formaten in de wachtrij",
+ "settings": "Instellingen",
+ "switch_to": "Schakel over naar {{theme}}",
+ "logout": "Uitloggen",
+ "start_journey": "Begin uw reis door een nieuwe link aan te maken!",
+ "create_new_link": "Nieuwe Link Aanmaken",
+ "new_link": "Nieuwe Link",
+ "create_new": "Nieuwe Aanmaken...",
+ "pwa_install_prompt": "Installeer Linkwarden op uw startscherm voor snellere toegang en een verbeterde ervaring. <0>Meer leren0>",
+ "full_content": "Volledige Inhoud",
+ "slower": "Langzamer",
+ "new_version_announcement": "Zie wat er nieuw is in <0>Linkwarden {{version}}!0>",
+ "creating": "Aanmaken...",
+ "upload_file": "Bestand Uploaden",
+ "file": "Bestand",
+ "file_types": "PDF, PNG, JPG (tot {{size}} MB)",
+ "description": "Beschrijving",
+ "auto_generated": "Wordt automatisch gegenereerd als er niets wordt opgegeven.",
+ "example_link": "bijv. Voorbeeldlink",
+ "hide": "Verbergen",
+ "more": "Meer",
+ "options": "Opties",
+ "description_placeholder": "Notities, gedachten, enz.",
+ "deleting": "Verwijderen...",
+ "token_revoked": "Token Ingetrokken.",
+ "revoke_token": "Token Intrekken",
+ "revoke_confirmation": "Weet u zeker dat u dit toegangstoken wilt intrekken? Apps of services die dit token gebruiken, zullen Linkwarden niet langer kunnen benaderen.",
+ "revoke": "Intrekken",
+ "sending_request": "Verzoek Verzenden...",
+ "link_being_archived": "Link wordt gearchiveerd...",
+ "preserved_formats": "Bewaarde Formaten",
+ "available_formats": "De volgende formaten zijn beschikbaar voor deze link:",
+ "readable": "Leesbaar",
+ "preservation_in_queue": "Linkbewaring staat in de wachtrij",
+ "view_latest_snapshot": "Bekijk de laatste momentopname op archive.org",
+ "refresh_preserved_formats": "Vernieuw Bewaarde Formaten",
+ "this_deletes_current_preservations": "Dit verwijdert de huidige bewaarmethodes",
+ "create_new_user": "Nieuwe Gebruiker Aanmaken",
+ "placeholder_johnny": "Johnny",
+ "placeholder_email": "johnny@voorbeeld.com",
+ "placeholder_john": "john",
+ "user_created": "Gebruiker Aangemaakt!",
+ "fill_all_fields_error": "Vul alle velden in.",
+ "password_change_note": "<0>Opmerking:0> Zorg ervoor dat u de gebruiker informeert dat ze hun wachtwoord moeten wijzigen.",
+ "create_user": "Gebruiker Aanmaken",
+ "creating_token": "Token Aanmaken...",
+ "token_created": "Token Aangemaakt!",
+ "access_token_created": "Toegangstoken Aangemaakt",
+ "token_creation_notice": "Uw nieuwe token is aangemaakt. Kopieer het en bewaar het ergens veilig. U kunt het niet opnieuw bekijken.",
+ "copied_to_clipboard": "Gekopieerd naar klembord!",
+ "copy_to_clipboard": "Kopiëren naar Klembord",
+ "create_access_token": "Toegangstoken Aanmaken",
+ "expires_in": "Verloopt over",
+ "token_name_placeholder": "bijv. Voor de iOS snelkoppeling",
+ "create_token": "Toegangstoken Aanmaken",
+ "7_days": "7 Dagen",
+ "30_days": "30 Dagen",
+ "60_days": "60 Dagen",
+ "90_days": "90 Dagen",
+ "no_expiration": "Geen Verloopdatum",
+ "creating_link": "Link Aanmaken...",
+ "link_created": "Link Aangemaakt!",
+ "link_name_placeholder": "Wordt automatisch gegenereerd als leeg gelaten.",
+ "link_url_placeholder": "bijv. http://voorbeeld.com/",
+ "link_description_placeholder": "Notities, gedachten, enz.",
+ "more_options": "Meer Opties",
+ "hide_options": "Opties Verbergen",
+ "create_link": "Link Aanmaken",
+ "new_sub_collection": "Nieuwe Sub-Collectie",
+ "for_collection": "Voor {{name}}",
+ "create_new_collection": "Nieuwe Collectie Aanmaken",
+ "color": "Kleur",
+ "reset": "Herstellen",
+ "updating_collection": "Collectie Bijwerken...",
+ "collection_name_placeholder": "bijv. Voorbeeld Collectie",
+ "collection_description_placeholder": "Het doel van deze Collectie...",
+ "create_collection_button": "Collectie Aanmaken",
+ "password_change_warning": "Bevestig uw wachtwoord voordat u uw e-mailadres wijzigt.",
+ "stripe_update_note": "Door dit veld bij te werken, wijzigt u ook uw facturerings-e-mail op Stripe.",
+ "sso_will_be_removed_warning": "Als u uw e-mailadres wijzigt, worden alle bestaande {{service}} SSO-verbindingen verwijderd.",
+ "old_email": "Oud E-mailadres",
+ "new_email": "Nieuw E-mailadres",
+ "confirm": "Bevestigen",
+ "edit_link": "Link Bewerken",
+ "updating": "Bijwerken...",
+ "updated": "Bijgewerkt!",
+ "placeholder_example_link": "bijv. Voorbeeld Link",
+ "make_collection_public": "Maak Collectie Openbaar",
+ "make_collection_public_checkbox": "Maak dit een openbare collectie",
+ "make_collection_public_desc": "Hierdoor kan iedereen deze collectie en zijn gebruikers bekijken.",
+ "sharable_link_guide": "Deelbare Link (Klik om te kopiëren)",
+ "copied": "Gekopieerd!",
+ "members": "Leden",
+ "members_username_placeholder": "Gebruikersnaam (zonder '@')",
+ "owner": "Eigenaar",
+ "admin": "Beheerder",
+ "contributor": "Bijdrager",
+ "viewer": "Lezer",
+ "viewer_desc": "Alleen-lezen toegang",
+ "contributor_desc": "Kan links bekijken en aanmaken",
+ "admin_desc": "Volledige toegang tot alle links",
+ "remove_member": "Lid Verwijderen",
+ "placeholder_example_collection": "bijv. Voorbeeld Collectie",
+ "placeholder_collection_purpose": "Het doel van deze Collectie...",
+ "deleting_user": "Verwijderen...",
+ "user_deleted": "Gebruiker Verwijderd.",
+ "delete_user": "Gebruiker Verwijderen",
+ "confirm_user_deletion": "Weet u zeker dat u deze gebruiker wilt verwijderen?",
+ "irreversible_action_warning": "Deze actie is onomkeerbaar!",
+ "delete_confirmation": "Verwijderen, ik weet wat ik doe",
+ "delete_link": "Link Verwijderen",
+ "deleted": "Verwijderd.",
+ "link_deletion_confirmation_message": "Weet u zeker dat u deze link wilt verwijderen?",
+ "warning": "Waarschuwing",
+ "irreversible_warning": "Deze actie is onomkeerbaar!",
+ "shift_key_tip": "Houd de Shift-toets ingedrukt terwijl u op 'Verwijderen' klikt om deze bevestiging in de toekomst te omzeilen.",
+ "deleting_collection": "Verwijderen...",
+ "collection_deleted": "Collectie Verwijderd.",
+ "confirm_deletion_prompt": "Ter bevestiging, typ \"{{name}}\" in het onderstaande vak:",
+ "type_name_placeholder": "Typ Hier \"{{name}}\".",
+ "deletion_warning": "Als u deze collectie verwijdert, worden alle inhoud permanent gewist, en wordt deze ontoegankelijk voor iedereen, inclusief leden met eerdere toegang.",
+ "leave_prompt": "Klik op de onderstaande knop om de huidige collectie te verlaten.",
+ "leave": "Verlaten",
+ "edit_links": "Bewerk {{count}} Links",
+ "move_to_collection": "Verplaatsen naar Collectie",
+ "add_tags": "Tags Toevoegen",
+ "remove_previous_tags": "Verwijder vorige tags",
+ "delete_links": "Verwijder {{count}} Links",
+ "links_deletion_confirmation_message": "Weet u zeker dat u {{count}} links wilt verwijderen?",
+ "warning_irreversible": "Waarschuwing: Deze actie is onomkeerbaar!",
+ "shift_key_instruction": "Houd de 'Shift'-toets ingedrukt terwijl u op 'Verwijderen' klikt om deze bevestiging in de toekomst te omzeilen.",
+ "link_selection_error": "U heeft geen toestemming om dit item te bewerken of te verwijderen.",
+ "no_description": "Geen beschrijving opgegeven.",
+ "applying": "Toepassen...",
+ "unpin": "Losmaken",
+ "pin_to_dashboard": "Vastmaken aan Dashboard",
+ "show_link_details": "Toon Linkdetails",
+ "hide_link_details": "Verberg Linkdetails",
+ "link_pinned": "Link Vastgemaakt!",
+ "link_unpinned": "Link Losgemaakt!",
+ "webpage": "Webpagina",
+ "server_administration": "Serverbeheer",
+ "all_collections": "Alle Collecties",
+ "dashboard": "Dashboard",
+ "demo_title": "Demo Alleen",
+ "demo_desc": "Dit is slechts een demo-instantie van Linkwarden en uploads zijn uitgeschakeld.",
+ "demo_desc_2": "Als u de volledige versie wilt proberen, kunt u zich aanmelden voor een gratis proefperiode op:",
+ "demo_button": "Inloggen als demo gebruiker"
+}
\ No newline at end of file
diff --git a/public/locales/pt-BR/common.json b/public/locales/pt-BR/common.json
new file mode 100644
index 0000000..80c7714
--- /dev/null
+++ b/public/locales/pt-BR/common.json
@@ -0,0 +1,400 @@
+{
+ "user_administration": "Administração de Usuários",
+ "search_users": "Pesquisar por Usuários",
+ "no_users_found": "Nenhum usuário encontrado.",
+ "no_user_found_in_search": "Nenhum usuário encontrado com a consulta de pesquisa fornecida.",
+ "username": "Nome de Usuário",
+ "email": "E-mail",
+ "subscribed": "Inscrito",
+ "created_at": "Criado Em",
+ "not_available": "N/D",
+ "check_your_email": "Por favor, verifique seu E-mail",
+ "authenticating": "Autenticando...",
+ "verification_email_sent": "E-mail de verificação enviado.",
+ "view": "Visualizar",
+ "verification_email_sent_desc": "Um link de login foi enviado para seu endereço de e-mail. Se você não vir o e-mail, verifique sua pasta de spam.",
+ "resend_email": "Reenviar E-mail",
+ "reset_defaults": "redefinir para o Padrão",
+ "invalid_credentials": "Credenciais inválidas.",
+ "fill_all_fields": "Por favor, preencha todos os campos.",
+ "enter_credentials": "Digite suas credenciais",
+ "username_or_email": "Nome de Usuário ou E-mail",
+ "password": "Senha",
+ "confirm_password": "Confirmar Senha",
+ "forgot_password": "Esqueceu a Senha?",
+ "login": "Login",
+ "or_continue_with": "Ou continue com",
+ "new_here": "Novo por aqui?",
+ "sign_up": "Inscrever-se",
+ "sign_in_to_your_account": "Faça login na sua conta",
+ "dashboard_desc": "Uma breve visão geral dos seus dados",
+ "date": "Data",
+ "link": "Link",
+ "links": "Links",
+ "collection": "Coleção",
+ "collections": "Coleções",
+ "tag": "Tag",
+ "tags": "Tags",
+ "recent": "Recentes",
+ "recent_links_desc": "Links adicionados recentemente",
+ "view_all": "Ver Todos",
+ "view_added_links_here": "Veja Seus Links Adicionados Recentemente Aqui!",
+ "view_added_links_here_desc": "Esta seção exibirá seus Links adicionados mais recentemente em todas as Coleções às quais você tem acesso.",
+ "add_link": "Adicionar Novo Link",
+ "import_links": "Importar Links",
+ "from_linkwarden": "Do Linkwarden",
+ "from_html": "Do arquivo HTML de Favoritos",
+ "from_wallabag": "Do Wallabag (arquivo JSON)",
+ "pinned": "Fixados",
+ "pinned_links_desc": "Seus Links fixados",
+ "pin_favorite_links_here": "Fixe Seus Links Favoritos Aqui!",
+ "pin_favorite_links_here_desc": "Você pode Fixar seus Links favoritos clicando nos três pontos em cada Link e clicando em Fixar no Painel.",
+ "sending_password_link": "Enviando link de recuperação de senha...",
+ "password_email_prompt": "Digite seu e-mail para que possamos enviar um link para criar uma nova senha.",
+ "send_reset_link": "Enviar Link de Redefinição",
+ "reset_email_sent_desc": "Verifique seu e-mail para obter um link para redefinir sua senha. Se não aparecer em alguns minutos, verifique sua pasta 1 de spam.",
+ "back_to_login": "Voltar para o Login",
+ "email_sent": "E-mail Enviado!",
+ "passwords_mismatch": "As senhas não coincidem.",
+ "password_too_short": "As senhas devem ter pelo menos 8 caracteres.",
+ "creating_account": "Criando Conta...",
+ "account_created": "Conta Criada!",
+ "trial_offer_desc": "Desbloqueie {{count}} dias de Serviço Premium sem custo!",
+ "register_desc": "Criar uma nova conta",
+ "registration_disabled_desc": "O registro está desativado para esta instância, entre em contato com o administrador em caso de problemas.",
+ "regular": "Regular",
+ "enter_details": "Digite seus dados",
+ "display_name": "Nome de Exibição",
+ "sign_up_agreement": "Ao se inscrever, você concorda com nossos Termos de Serviço 1 e Política de Privacidade.",
+ "need_help": "Precisa de ajuda?",
+ "get_in_touch": "Entre em contato",
+ "already_registered": "Já tem uma conta?",
+ "deleting_selections": "Excluindo seleções...",
+ "links_deleted": "{{count}} Links excluídos.",
+ "link_deleted": "1 Link excluído.",
+ "links_selected": "{{count}} Links selecionados",
+ "link_selected": "1 Link selecionado",
+ "nothing_selected": "Nada selecionado",
+ "edit": "Editar",
+ "delete": "Excluir",
+ "nothing_found": "Nada encontrado.",
+ "redirecting_to_stripe": "Redirecionando para o Stripe...",
+ "subscribe_title": "Assine o Linkwarden!",
+ "subscribe_desc": "Você será redirecionado para o Stripe, sinta-se à vontade para nos contatar em support@linkwarden.app 1 em caso de qualquer problema.",
+ "monthly": "Mensal",
+ "yearly": "Anual",
+ "discount_percent": "{{percent}}% de Desconto",
+ "billed_monthly": "Cobrado Mensalmente",
+ "billed_yearly": "Cobrado Anualmente",
+ "total": "Total",
+ "total_annual_desc": "Teste grátis de {{count}} dias, depois ${{annualPrice}} anualmente",
+ "total_monthly_desc": "Teste grátis de {{count}} dias, depois ${{monthlyPrice}} por mês",
+ "plus_tax": "+ IVA se aplicável",
+ "complete_subscription": "Concluir Assinatura",
+ "sign_out": "Sair",
+ "access_tokens": "Tokens de Acesso",
+ "access_tokens_description": "Os Tokens de Acesso podem ser usados para acessar o Linkwarden de outros aplicativos e serviços sem fornecer seu Nome de Usuário e Senha.",
+ "new_token": "Novo Token de Acesso",
+ "name": "Nome",
+ "created_success": "Criado!",
+ "created": "Criado",
+ "expires": "Expira",
+ "accountSettings": "Configurações da Conta",
+ "language": "Idioma",
+ "profile_photo": "Foto de Perfil",
+ "upload_new_photo": "Carregar uma nova foto...",
+ "upload_preview_image": "Carregar Imagem de Pré-visualização",
+ "remove_photo": "Remover Foto",
+ "make_profile_private": "Tornar o perfil privado",
+ "profile_privacy_info": "Isso limitará quem pode encontrar e adicionar você a novas Coleções.",
+ "whitelisted_users": "Usuários da Lista de Permissões",
+ "whitelisted_users_info": "Forneça o Nome de Usuário dos usuários aos quais você deseja conceder visibilidade ao seu perfil. Separados por vírgula.",
+ "whitelisted_users_placeholder": "Seu perfil está oculto de todos agora...",
+ "save_changes": "Salvar Alterações",
+ "saved": "Salvo",
+ "import_export": "Importar e Exportar",
+ "import_data": "Importe seus dados de outras plataformas.",
+ "download_data": "Baixe seus dados instantaneamente.",
+ "duotone": "Duotone",
+ "export_data": "Exportar Dados",
+ "delete_account": "Excluir Conta",
+ "delete_account_warning": "Isso excluirá permanentemente TODOS os Links, Coleções, Tags e dados arquivados que você possui.",
+ "cancel_subscription_notice": "Também cancelará sua assinatura.",
+ "account_deletion_page": "Página de exclusão de conta",
+ "applying_settings": "Aplicando configurações...",
+ "settings_applied": "Configurações Aplicadas!",
+ "sharable_link": "Link Compartilhável",
+ "email_change_request": "Solicitação de alteração de e-mail enviada. Por favor, verifique o novo endereço de e-mail.",
+ "image_upload_no_file_error": "Nenhum arquivo selecionado. Por favor, escolha uma imagem para carregar.",
+ "image_upload_size_error": "Por favor, selecione um arquivo PNG ou JPEG com menos de 1MB.",
+ "image_upload_format_error": "Formato de arquivo inválido.",
+ "importing_bookmarks": "Importando favoritos...",
+ "import_success": "Favoritos importados! Recarregando a página...",
+ "more_coming_soon": "Mais em breve!",
+ "billing_settings": "Configurações de Cobrança",
+ "bold": "Negrito",
+ "manage_subscription_intro": "Para gerenciar/cancelar sua assinatura, visite o",
+ "billing_portal": "Portal de Faturamento",
+ "help_contact_intro": "Se você ainda precisar de ajuda ou encontrar algum problema, sinta-se à vontade para nos contatar em:",
+ "fill_required_fields": "Por favor, preencha os campos obrigatórios.",
+ "deleting_message": "Excluindo tudo, por favor aguarde...",
+ "delete_warning": "Isso excluirá permanentemente todos os Links, Coleções, Tags e dados arquivados que você possui. Também irá desconectá-lo. Esta ação é irreversível!",
+ "optional": "Opcional",
+ "feedback_help": "(mas realmente nos ajuda a melhorar!)",
+ "reason_for_cancellation": "Motivo do cancelamento",
+ "please_specify": "Por favor, especifique",
+ "customer_service": "Atendimento ao Cliente",
+ "low_quality": "Baixa Qualidade",
+ "missing_features": "Recursos Faltando",
+ "switched_service": "Serviço Trocado",
+ "too_complex": "Muito Complexo",
+ "too_expensive": "Muito Caro",
+ "unused": "Não Utilizado",
+ "other": "Outro",
+ "more_information": "Mais informações (quanto mais detalhes, mais útil será)",
+ "feedback_placeholder": "por exemplo, eu precisava de um recurso que...",
+ "delete_your_account": "Excluir sua conta",
+ "change_password": "Alterar senha",
+ "password_length_error": "As senhas devem ter pelo menos 8 caracteres.",
+ "applying_changes": "Aplicando...",
+ "password_change_instructions": "Para alterar sua senha, preencha os seguintes campos. Sua senha deve ter pelo menos 8 caracteres.",
+ "old_password": "Senha Antiga",
+ "new_password": "Nova Senha",
+ "preference": "Preferência",
+ "select_theme": "Selecionar Tema",
+ "dark": "Escuro",
+ "light": "Claro",
+ "light_icon": "Claro",
+ "archive_settings": "Configurações de Arquivo",
+ "formats_to_archive": "Formatos para Arquivar/Preservar páginas da web:",
+ "screenshot": "Captura de Tela",
+ "search": "Busca",
+ "pdf": "PDF",
+ "archive_org_snapshot": "Instantâneo do Archive.org",
+ "link_settings": "Configurações de Link",
+ "prevent_duplicate_links": "Prevenir links duplicados",
+ "preview_unavailable": "Pré-Visualização Indisponível",
+ "clicking_on_links_should": "Clicar em Links deve:",
+ "open_original_content": "Abrir o conteúdo original",
+ "open_pdf_if_available": "Abrir PDF, se disponível",
+ "open_readable_if_available": "Abrir Legível, se disponível",
+ "open_screenshot_if_available": "Abrir Captura de Tela, se disponível",
+ "open_webpage_if_available": "Abrir cópia da página da Web, se disponível",
+ "tag_renamed": "Tag renomeada!",
+ "tag_deleted": "Tag excluída!",
+ "rename_tag": "Renomear Tag",
+ "delete_tag": "Excluir Tag",
+ "list_created_with_linkwarden": "Lista criada com Linkwarden",
+ "by_author": "Por {{author}}.",
+ "by_author_and_other": "Por {{author}} e {{count}} outro.",
+ "by_author_and_others": "Por {{author}} e {{count}} outros.",
+ "search_count_link": "Pesquisar {{count}} Link",
+ "search_count_links": "Pesquisar {{count}} Links",
+ "collection_is_empty": "Esta Coleção está vazia...",
+ "all_links": "Todos os Links",
+ "all_links_desc": "Links de todas as Coleções",
+ "you_have_not_added_any_links": "Você ainda não criou nenhum Link",
+ "collections_you_own": "Coleções que você possui",
+ "new_collection": "Nova Coleção",
+ "other_collections": "Outras Coleções",
+ "other_collections_desc": "Coleções compartilhadas das quais você é membro",
+ "showing_count_results": "Mostrando {{count}} resultados",
+ "showing_count_result": "Mostrando {{count}} resultado",
+ "edit_collection_info": "Editar Informações da Coleção",
+ "share_and_collaborate": "Compartilhar e Colaborar",
+ "view_team": "Ver Equipe",
+ "team": "Equipe",
+ "create_subcollection": "Criar Subcoleção",
+ "delete_collection": "Excluir Coleção",
+ "leave_collection": "Sair da Coleção",
+ "email_verified_signing_out": "E-mail verificado. Saindo...",
+ "invalid_token": "Token inválido.",
+ "sending_password_recovery_link": "Enviando link de recuperação de senha...",
+ "please_fill_all_fields": "Por favor, preencha todos os campos.",
+ "password_updated": "Senha Atualizada!",
+ "reset_password": "Redefinir Senha",
+ "enter_email_for_new_password": "Digite seu e-mail para que possamos enviar um link para criar uma nova senha.",
+ "update_password": "Atualizar Senha",
+ "password_successfully_updated": "Sua senha foi atualizada com sucesso.",
+ "user_already_member": "O usuário já existe.",
+ "you_are_already_collection_owner": "Você já é o proprietário da coleção.",
+ "date_newest_first": "Data (Mais Recente Primeiro)",
+ "date_oldest_first": "Data (Mais Antigo Primeiro)",
+ "default": "Padrão",
+ "name_az": "Nome (A-Z)",
+ "name_za": "Nome (Z-A)",
+ "description_az": "Descrição (A-Z)",
+ "description_za": "Descrição (Z-A)",
+ "all_rights_reserved": "© {{date}} Linkwarden. Todos os direitos reservados.",
+ "you_have_no_collections": "Você não tem Coleções...",
+ "you_have_no_tags": "Você não tem Tags...",
+ "cant_change_collection_you_dont_own": "Você não pode fazer alterações em uma coleção que você não possui.",
+ "change_icon": "Alterar Ícone",
+ "account": "Conta",
+ "billing": "Faturamento",
+ "linkwarden_version": "Linkwarden {{version}}",
+ "help": "Ajuda",
+ "github": "GitHub",
+ "twitter": "Twitter",
+ "mastodon": "Mastodon",
+ "link_preservation_in_queue": "A preservação do Link está atualmente na fila",
+ "check_back_later": "Por favor, verifique mais tarde para ver o resultado",
+ "there_are_more_formats": "Há mais formatos preservados na fila",
+ "thin": "Fino",
+ "settings": "Configurações",
+ "switch_to": "Mudar para {{theme}}",
+ "logout": "Sair",
+ "start_journey": "Comece sua jornada criando um novo Link!",
+ "create_new_link": "Criar Novo Link",
+ "new_link": "Novo Link",
+ "create_new": "Criar Novo...",
+ "pwa_install_prompt": "Instale o Linkwarden na sua tela inicial para um acesso mais rápido e uma experiência aprimorada. Saiba mais",
+ "full_content": "Conteúdo Completo",
+ "slower": "Mais Lento",
+ "new_version_announcement": "Veja as novidades em Linkwarden {{version}}!",
+ "creating": "Criando...",
+ "upload_file": "Enviar Arquivo",
+ "file": "Arquivo",
+ "file_types": "PDF, PNG, JPG (Até {{size}} MB)",
+ "fill": "Preencher",
+ "description": "Descrição",
+ "auto_generated": "Será gerado automaticamente se nada for fornecido.",
+ "example_link": "por exemplo, Link de Exemplo",
+ "hide": "Ocultar",
+ "more": "Mais",
+ "options": "Opções",
+ "description_placeholder": "Notas, pensamentos, etc.",
+ "deleting": "Excluindo...",
+ "token_revoked": "Token Revogado.",
+ "revoke_token": "Revogar Token",
+ "revoke_confirmation": "Tem certeza de que deseja revogar este Token de Acesso? Quaisquer aplicativos ou serviços que usem este token não poderão mais acessar o Linkwarden usando-o.",
+ "revoke": "Revogar",
+ "sending_request": "Enviando solicitação...",
+ "link_being_archived": "O link está sendo arquivado...",
+ "preserved_formats": "Formatos Preservados",
+ "available_formats": "Os seguintes formatos estão disponíveis para este link:",
+ "readable": "Legível",
+ "preservation_in_queue": "A preservação do link está na fila",
+ "view_latest_snapshot": "Ver o último snapshot em archive.org",
+ "refresh_preserved_formats": "Atualizar Formatos Preservados",
+ "this_deletes_current_preservations": "Isso exclui as preservações atuais",
+ "create_new_user": "Criar Novo Usuário",
+ "placeholder_johnny": "Johnny",
+ "placeholder_email": "johnny@example.com",
+ "placeholder_john": "john",
+ "user_created": "Usuário Criado!",
+ "fill_all_fields_error": "Por favor, preencha todos os campos.",
+ "password_change_note": "Nota: Certifique-se de informar o usuário que ele precisa alterar sua senha.",
+ "create_user": "Criar Usuário",
+ "creating_token": "Criando Token...",
+ "token_created": "Token Criado!",
+ "access_token_created": "Token de Acesso Criado",
+ "token_creation_notice": "Seu novo token foi criado. Por favor, copie-o e guarde-o em um local seguro. Você não poderá vê-lo novamente.",
+ "copied_to_clipboard": "Copiado para a área de transferência!",
+ "copy_to_clipboard": "Copiar para a Área de Transferência",
+ "create_access_token": "Criar um Token de Acesso",
+ "expires_in": "Expira em",
+ "token_name_placeholder": "por exemplo, Para o atalho do iOS",
+ "create_token": "Criar Token de Acesso",
+ "7_days": "7 Dias",
+ "30_days": "30 Dias",
+ "60_days": "60 Dias",
+ "90_days": "90 Dias",
+ "no_expiration": "Sem Expiração",
+ "no_tags": "Sem tags.",
+ "creating_link": "Criando link...",
+ "link_created": "Link criado!",
+ "link_name_placeholder": "Será gerado automaticamente se deixado em branco.",
+ "link_url_placeholder": "por exemplo, http://example.com/",
+ "link_description_placeholder": "Notas, pensamentos, etc.",
+ "more_options": "Mais Opções",
+ "hide_options": "Ocultar Opções",
+ "icon": "Icone",
+ "image": "Imagem",
+ "create_link": "Criar Link",
+ "new_sub_collection": "Nova Subcoleção",
+ "for_collection": "Para {{name}}",
+ "create_new_collection": "Criar uma Nova Coleção",
+ "color": "Cor",
+ "columns": "Colunas",
+ "reset": "Redefinir",
+ "updating_collection": "Atualizando Coleção...",
+ "collection_name_placeholder": "por exemplo, Coleção de Exemplo",
+ "collection_description_placeholder": "O propósito desta Coleção...",
+ "create_collection_button": "Criar Coleção",
+ "password_change_warning": "Por favor, confirme sua senha antes de alterar seu endereço de e-mail.",
+ "stripe_update_note": " Atualizar este campo também alterará seu e-mail de cobrança no Stripe.",
+ "sso_will_be_removed_warning": "Se você alterar seu endereço de e-mail, todas as conexões SSO {{service}} existentes serão removidas.",
+ "old_email": "E-mail Antigo",
+ "new_email": "Novo E-mail",
+ "confirm": "Confirmar",
+ "edit_link": "Editar Link",
+ "updating": "Atualizando...",
+ "updated": "Atualizado!",
+ "placeholder_example_link": "por exemplo, Link de Exemplo",
+ "make_collection_public": "Tornar a Coleção Pública",
+ "make_collection_public_checkbox": "Tornar esta uma coleção pública",
+ "make_collection_public_desc": "Isso permitirá que qualquer pessoa visualize esta coleção e seus usuários.",
+ "sharable_link_guide": "Link Compartilhável (Clique para copiar)",
+ "copied": "Copiado!",
+ "members": "Membros",
+ "members_username_placeholder": "Nome de usuário (sem o '@')",
+ "owner": "Proprietário",
+ "admin": "Administrador",
+ "contributor": "Colaborador",
+ "viewer": "Visualizador",
+ "viewer_desc": "Acesso somente leitura",
+ "contributor_desc": "Pode visualizar e criar Links",
+ "admin_desc": "Acesso total a todos os Links",
+ "remove_member": "Remover Membro",
+ "placeholder_example_collection": "por exemplo, Coleção de Exemplo",
+ "placeholder_collection_purpose": "O propósito desta Coleção...",
+ "deleting_user": "Excluindo...",
+ "user_deleted": "Usuário Excluído.",
+ "delete_user": "Excluir Usuário",
+ "confirm_user_deletion": "Tem certeza de que deseja remover este usuário?",
+ "irreversible_action_warning": "Esta ação é irreversível!",
+ "delete_confirmation": "Excluir, eu sei o que estou fazendo",
+ "delete_link": "Excluir Link",
+ "deleted": "Excluído.",
+ "link_deletion_confirmation_message": "Tem certeza de que deseja excluir este Link?",
+ "warning": "Aviso",
+ "irreversible_warning": "Esta ação é irreversível!",
+ "shift_key_tip": "Mantenha a tecla Shift pressionada enquanto clica em 'Excluir' para ignorar esta confirmação no futuro.",
+ "show": "Exibir",
+ "deleting_collection": "Excluindo...",
+ "collection_deleted": "Coleção Excluída.",
+ "confirm_deletion_prompt": "Para confirmar, digite \"{{name}}\" na caixa abaixo:",
+ "type_name_placeholder": "Digite \"{{name}}\" Aqui.",
+ "deletion_warning": "Excluir esta coleção apagará permanentemente todo o seu conteúdo e ela se tornará inacessível para todos, incluindo membros com acesso anterior.",
+ "leave_prompt": "Clique no botão abaixo para sair da coleção atual.",
+ "leave": "Sair",
+ "edit_links": "Editar {{count}} Links",
+ "move_to_collection": "Mover para a Coleção",
+ "add_tags": "Adicionar Tags",
+ "remove_previous_tags": "Remover tags anteriores",
+ "delete_links": "Excluir {{count}} Links",
+ "links_deletion_confirmation_message": "Tem certeza de que deseja excluir {{count}} Links? ",
+ "warning_irreversible": "Aviso: Esta ação é irreversível!",
+ "shift_key_instruction": "Mantenha a tecla 'Shift' pressionada enquanto clica em 'Excluir' para ignorar esta confirmação no futuro.",
+ "link_selection_error": "Você não tem permissão para editar ou excluir este item.",
+ "no_description": "Nenhuma descrição fornecida.",
+ "no_description_provided": "Nenhuma descrição fornecida.",
+ "applying": "Aplicando...",
+ "unpin": "Desafixar",
+ "untitled": "Sem Título",
+ "pin_to_dashboard": "Fixar no Painel",
+ "show_link_details": "Mostrar Detalhes do Link",
+ "link_pinned": "Link Fixado!",
+ "link_unpinned": "Link Desafixado!",
+ "webpage": "Página da Web",
+ "server_administration": "Administração do Servidor",
+ "set_custom_icon": "Definir Ícone Customizado",
+ "all_collections": "Todas as Coleções",
+ "dashboard": "Painel",
+ "demo_title": "Apenas Demonstração",
+ "demo_desc": "Esta é apenas uma instância de demonstração do Linkwarden e os uploads estão desativados.",
+ "demo_desc_2": "Se você quiser experimentar a versão completa, você pode se inscrever para um teste gratuito em:",
+ "demo_button": "Entrar como usuário de demonstração",
+ "notes": "Notas"
+ }
\ No newline at end of file
diff --git a/public/locales/tr/common.json b/public/locales/tr/common.json
new file mode 100644
index 0000000..2cc4ef2
--- /dev/null
+++ b/public/locales/tr/common.json
@@ -0,0 +1,377 @@
+{
+ "user_administration": "Kullanıcı Yönetimi",
+ "search_users": "Kullanıcı Ara",
+ "no_users_found": "Kullanıcı bulunamadı.",
+ "no_user_found_in_search": "Verilen arama sorgusuyla kullanıcı bulunamadı.",
+ "username": "Kullanıcı Adı",
+ "email": "E-posta",
+ "subscribed": "Abone",
+ "created_at": "Oluşturulma Tarihi",
+ "not_available": "Mevcut Değil",
+ "check_your_email": "Lütfen E-postanızı Kontrol Edin",
+ "authenticating": "Kimlik doğrulanıyor...",
+ "verification_email_sent": "Doğrulama e-postası gönderildi.",
+ "verification_email_sent_desc": "Giriş bağlantısı e-posta adresinize gönderildi. E-postayı görmüyorsanız, spam klasörünüzü kontrol edin.",
+ "resend_email": "E-postayı Tekrar Gönder",
+ "invalid_credentials": "Geçersiz kimlik bilgileri.",
+ "fill_all_fields": "Lütfen tüm alanları doldurun.",
+ "enter_credentials": "Kimlik bilgilerinizi girin",
+ "username_or_email": "Kullanıcı Adı veya E-posta",
+ "password": "Şifre",
+ "confirm_password": "Şifreyi Onayla",
+ "forgot_password": "Şifrenizi mi unuttunuz?",
+ "login": "Giriş Yap",
+ "or_continue_with": "Veya devam edin",
+ "new_here": "Yeni misiniz?",
+ "sign_up": "Kayıt Ol",
+ "sign_in_to_your_account": "Hesabınıza giriş yapın",
+ "dashboard_desc": "Verilerinizin kısa bir özeti",
+ "link": "Bağlantı",
+ "links": "Bağlantılar",
+ "collection": "Koleksiyon",
+ "collections": "Koleksiyonlar",
+ "tag": "Etiket",
+ "tags": "Etiketler",
+ "recent": "Son",
+ "recent_links_desc": "Son Eklenen Bağlantılar",
+ "view_all": "Tümünü Görüntüle",
+ "view_added_links_here": "Son Eklediğiniz Bağlantıları Buradan Görüntüleyin!",
+ "view_added_links_here_desc": "Bu bölüm, erişiminiz olan tüm Koleksiyonlardaki en son eklediğiniz Bağlantıları görüntüler.",
+ "add_link": "Yeni Bağlantı Ekle",
+ "import_links": "Bağlantıları İçe Aktar",
+ "from_linkwarden": "Linkwarden'dan",
+ "from_html": "Yer İmleri HTML dosyasından",
+ "from_wallabag": "Wallabag'dan (JSON dosyası)",
+ "pinned": "Sabitlenmiş",
+ "pinned_links_desc": "Sabitlenmiş Bağlantılarınız",
+ "pin_favorite_links_here": "Favori Bağlantılarınızı Buraya Sabitleyin!",
+ "pin_favorite_links_here_desc": "Favori Bağlantılarınızı, her Bağlantının üzerindeki üç noktaya tıklayarak ve Pano'ya Sabitle seçeneğini seçerek sabitleyebilirsiniz.",
+ "sending_password_link": "Şifre sıfırlama bağlantısı gönderiliyor...",
+ "password_email_prompt": "Yeni bir şifre oluşturabilmeniz için e-posta adresinizi girin, size bir bağlantı göndereceğiz.",
+ "send_reset_link": "Sıfırlama Bağlantısını Gönder",
+ "reset_email_sent_desc": "Şifrenizi sıfırlamak için e-postanızı kontrol edin. Birkaç dakika içinde gelmezse, spam klasörünüzü kontrol edin.",
+ "back_to_login": "Girişe Geri Dön",
+ "email_sent": "E-posta Gönderildi!",
+ "passwords_mismatch": "Şifreler uyuşmuyor.",
+ "password_too_short": "Şifreler en az 8 karakter olmalıdır.",
+ "creating_account": "Hesap Oluşturuluyor...",
+ "account_created": "Hesap Oluşturuldu!",
+ "trial_offer_desc": "{{count}} gün Ücretsiz Premium Hizmetin kilidini açın!",
+ "register_desc": "Yeni bir hesap oluştur",
+ "registration_disabled_desc": "Bu sunucu için kayıt devre dışı bırakıldı, herhangi bir sorun yaşarsanız lütfen yönetici ile iletişime geçin.",
+ "enter_details": "Bilgilerinizi girin",
+ "display_name": "Görünen Ad",
+ "sign_up_agreement": "Kaydolarak, <0>Hizmet Şartlarımızı0> ve <1>Gizlilik Politikamızı1> kabul etmiş olursunuz.",
+ "need_help": "Yardıma mı ihtiyacınız var?",
+ "get_in_touch": "İletişime geçin",
+ "already_registered": "Zaten hesabınız var mı?",
+ "deleting_selections": "Seçimler Siliniyor...",
+ "links_deleted": "{{count}} Bağlantı silindi.",
+ "link_deleted": "1 Bağlantı silindi.",
+ "links_selected": "{{count}} Bağlantı seçildi",
+ "link_selected": "1 Bağlantı seçildi",
+ "nothing_selected": "Hiçbir şey seçilmedi",
+ "edit": "Düzenle",
+ "delete": "Sil",
+ "nothing_found": "Hiçbir şey bulunamadı.",
+ "redirecting_to_stripe": "Stripe'a yönlendiriliyor...",
+ "subscribe_title": "Linkwarden'a Abone Olun!",
+ "subscribe_desc": "Stripe'a yönlendirileceksiniz, herhangi bir sorun yaşarsanız <0>support@linkwarden.app0> adresinden bizimle iletişime geçebilirsiniz.",
+ "monthly": "Aylık",
+ "yearly": "Yıllık",
+ "discount_percent": "{{percent}}% İndirim",
+ "billed_monthly": "Aylık Faturalandırılır",
+ "billed_yearly": "Yıllık Faturalandırılır",
+ "total": "Toplam",
+ "total_annual_desc": "{{count}} gün ücretsiz deneme süresi, ardından yıllık {{annualPrice}} $",
+ "total_monthly_desc": "{{count}} gün ücretsiz deneme süresi, ardından aylık {{monthlyPrice}} $",
+ "plus_tax": "+ Uygun ise KDV",
+ "complete_subscription": "Aboneliği Tamamla",
+ "sign_out": "Çıkış Yap",
+ "access_tokens": "Erişim Tokenleri",
+ "access_tokens_description": "Erişim Tokenleri, Kullanıcı Adı ve Şifrenizi vermeden Linkwarden'a diğer uygulamalar ve hizmetler aracılığıyla erişmek için kullanılabilir.",
+ "new_token": "Yeni Erişim Tokeni",
+ "name": "İsim",
+ "created_success": "Oluşturuldu!",
+ "created": "Oluşturuldu",
+ "expires": "Son Kullanma Tarihi",
+ "accountSettings": "Hesap Ayarları",
+ "language": "Dil",
+ "profile_photo": "Profil Fotoğrafı",
+ "upload_new_photo": "Yeni bir fotoğraf yükle...",
+ "remove_photo": "Fotoğrafı Kaldır",
+ "make_profile_private": "Profili gizli yap",
+ "profile_privacy_info": "Bu, kimlerin sizi bulup yeni Koleksiyonlara ekleyebileceğini sınırlayacaktır.",
+ "whitelisted_users": "Beyaz Listeye Alınmış Kullanıcılar",
+ "whitelisted_users_info": "Profilinize görünürlük sağlamak istediğiniz kullanıcı adlarını belirtin. Virgülle ayrılmış olarak.",
+ "whitelisted_users_placeholder": "Profiliniz şu anda herkesten gizlenmiştir...",
+ "save_changes": "Değişiklikleri Kaydet",
+ "import_export": "İçe/Dışa Aktar",
+ "import_data": "Verilerinizi diğer platformlardan içe aktarın.",
+ "download_data": "Verilerinizi hemen indirin.",
+ "export_data": "Verileri Dışa Aktar",
+ "delete_account": "Hesabı Sil",
+ "delete_account_warning": "Bu işlem, SAHİP OLDUĞUNUZ tüm Bağlantılar, Koleksiyonlar, Etiketler ve arşivlenmiş verileri KALICI OLARAK silecektir.",
+ "cancel_subscription_notice": "Ayrıca aboneliğinizi de iptal eder.",
+ "account_deletion_page": "Hesap silme sayfası",
+ "applying_settings": "Ayarlar Uygulanıyor...",
+ "settings_applied": "Ayarlar Uygulandı!",
+ "email_change_request": "E-posta değiştirme isteği gönderildi. Lütfen yeni e-posta adresinizi doğrulayın.",
+ "image_upload_size_error": "Lütfen 1MB'tan küçük bir PNG veya JPEG dosyası seçin.",
+ "image_upload_format_error": "Geçersiz dosya formatı.",
+ "importing_bookmarks": "Yer imleri içe aktarılıyor...",
+ "import_success": "Yer imleri içe aktarıldı! Sayfa yeniden yükleniyor...",
+ "more_coming_soon": "Daha fazlası yakında!",
+ "billing_settings": "Faturalandırma Ayarları",
+ "manage_subscription_intro": "Aboneliğinizi yönetmek/iptal etmek için, şu adrese gidin:",
+ "billing_portal": "Fatura Portalı",
+ "help_contact_intro": "Hala yardıma ihtiyacınız varsa veya herhangi bir sorun yaşadıysanız, bizimle iletişime geçmekten çekinmeyin:",
+ "fill_required_fields": "Lütfen gerekli alanları doldurun.",
+ "deleting_message": "Her şey siliniyor, lütfen bekleyin...",
+ "delete_warning": "Bu işlem, SAHİP OLDUĞUNUZ tüm Bağlantılar, Koleksiyonlar, Etiketler ve arşivlenmiş verileri KALICI OLARAK silecektir. Bu işlem ayrıca çıkış yapmanıza neden olacaktır. Bu işlem geri alınamaz!",
+ "optional": "İsteğe bağlı",
+ "feedback_help": "(ama bu gerçekten gelişmemize yardımcı olur!)",
+ "reason_for_cancellation": "İptal sebebi",
+ "please_specify": "Lütfen belirtin",
+ "customer_service": "Müşteri Hizmetleri",
+ "low_quality": "Düşük Kalite",
+ "missing_features": "Eksik Özellikler",
+ "switched_service": "Hizmeti Değiştirdim",
+ "too_complex": "Çok Karmaşık",
+ "too_expensive": "Çok Pahalı",
+ "unused": "Kullanılmıyor",
+ "other": "Diğer",
+ "more_information": "Daha fazla bilgi (ne kadar ayrıntı, o kadar faydalı olur)",
+ "feedback_placeholder": "ör. Bir özellik gerekiyordu...",
+ "delete_your_account": "Hesabınızı Silin",
+ "change_password": "Şifreyi Değiştir",
+ "password_length_error": "Şifreler en az 8 karakter olmalıdır.",
+ "applying_changes": "Değişiklikler Uygulanıyor...",
+ "password_change_instructions": "Şifrenizi değiştirmek için lütfen aşağıdaki bilgileri doldurun. Şifreniz en az 8 karakter olmalıdır.",
+ "old_password": "Eski Şifre",
+ "new_password": "Yeni Şifre",
+ "preference": "Tercih",
+ "select_theme": "Tema Seçin",
+ "dark": "Koyu",
+ "light": "Açık",
+ "archive_settings": "Arşiv Ayarları",
+ "formats_to_archive": "Web sayfalarını Arşivlemek/Korumak için formatlar:",
+ "screenshot": "Ekran Görüntüsü",
+ "pdf": "PDF",
+ "archive_org_snapshot": "Archive.org Anlık Görüntü",
+ "link_settings": "Bağlantı Ayarları",
+ "prevent_duplicate_links": "Yinelenen bağlantıları önle",
+ "clicking_on_links_should": "Bağlantılara tıklandığında:",
+ "open_original_content": "Orijinal içeriği aç",
+ "open_pdf_if_available": "Mevcutsa PDF aç",
+ "open_readable_if_available": "Mevcutsa Okunabilir aç",
+ "open_screenshot_if_available": "Mevcutsa Ekran Görüntüsü aç",
+ "open_webpage_if_available": "Mevcutsa Web sayfası kopyasını aç",
+ "tag_renamed": "Etiket yeniden adlandırıldı!",
+ "tag_deleted": "Etiket silindi!",
+ "rename_tag": "Etiketi Yeniden Adlandır",
+ "delete_tag": "Etiketi Sil",
+ "list_created_with_linkwarden": "Bu liste Linkwarden ile oluşturuldu",
+ "by_author": "{{author}} tarafından.",
+ "by_author_and_other": "{{author}} ve {{count}} diğer tarafından.",
+ "by_author_and_others": "{{author}} ve {{count}} diğerleri tarafından.",
+ "search_count_link": "{{count}} Bağlantı Ara",
+ "search_count_links": "{{count}} Bağlantı Ara",
+ "collection_is_empty": "Bu Koleksiyon boş...",
+ "all_links": "Tüm Bağlantılar",
+ "all_links_desc": "Her Koleksiyondan Bağlantılar",
+ "you_have_not_added_any_links": "Henüz Bağlantı Oluşturmadınız",
+ "collections_you_own": "Sahip Olduğunuz Koleksiyonlar",
+ "new_collection": "Yeni Koleksiyon",
+ "other_collections": "Diğer Koleksiyonlar",
+ "other_collections_desc": "Üyesi olduğunuz paylaşılan koleksiyonlar",
+ "showing_count_results": "{{count}} sonuç gösteriliyor",
+ "showing_count_result": "{{count}} sonuç gösteriliyor",
+ "edit_collection_info": "Koleksiyon Bilgilerini Düzenle",
+ "share_and_collaborate": "Paylaş ve İş Birliği Yap",
+ "view_team": "Takımı Görüntüle",
+ "team": "Takım",
+ "create_subcollection": "Alt Koleksiyon Oluştur",
+ "delete_collection": "Koleksiyonu Sil",
+ "leave_collection": "Koleksiyondan Ayrıl",
+ "email_verified_signing_out": "E-posta doğrulandı. Çıkış yapılıyor...",
+ "invalid_token": "Geçersiz token.",
+ "sending_password_recovery_link": "Şifre sıfırlama bağlantısı gönderiliyor...",
+ "please_fill_all_fields": "Lütfen tüm alanları doldurun.",
+ "password_updated": "Şifre Güncellendi!",
+ "reset_password": "Şifreyi Sıfırla",
+ "enter_email_for_new_password": "Yeni bir şifre oluşturabilmeniz için e-posta adresinizi girin, size bir bağlantı göndereceğiz.",
+ "update_password": "Şifreyi Güncelle",
+ "password_successfully_updated": "Şifreniz başarıyla güncellendi.",
+ "user_already_member": "Kullanıcı zaten mevcut.",
+ "you_are_already_collection_owner": "Zaten koleksiyon sahibisiniz.",
+ "date_newest_first": "Tarih (En Yeniler İlk)",
+ "date_oldest_first": "Tarih (En Eskiler İlk)",
+ "name_az": "Ad (A-Z)",
+ "name_za": "Ad (Z-A)",
+ "description_az": "Açıklama (A-Z)",
+ "description_za": "Açıklama (Z-A)",
+ "all_rights_reserved": "© {{date}} <0>Linkwarden0>. Tüm hakları saklıdır.",
+ "you_have_no_collections": "Koleksiyonunuz yok...",
+ "you_have_no_tags": "Etiketiniz yok...",
+ "cant_change_collection_you_dont_own": "Sahibi olmadığınız bir koleksiyonu değiştiremezsiniz.",
+ "account": "Hesap",
+ "billing": "Faturalandırma",
+ "linkwarden_version": "Linkwarden {{version}}",
+ "help": "Yardım",
+ "github": "GitHub",
+ "twitter": "Twitter",
+ "mastodon": "Mastodon",
+ "link_preservation_in_queue": "Bağlantı koruma şu anda sırada",
+ "check_back_later": "Sonucu görmek için daha sonra tekrar kontrol edin",
+ "there_are_more_formats": "Sırada daha fazla korunmuş format var",
+ "settings": "Ayarlar",
+ "switch_to": "{{theme}}'ya geç",
+ "logout": "Çıkış Yap",
+ "start_journey": "Yeni bir Bağlantı oluşturarak yolculuğunuza başlayın!",
+ "create_new_link": "Yeni Bağlantı Oluştur",
+ "new_link": "Yeni Bağlantı",
+ "create_new": "Yeni Oluştur...",
+ "pwa_install_prompt": "Daha hızlı erişim ve geliştirilmiş bir deneyim için Linkwarden'ı ana ekranınıza yükleyin. <0>Daha fazla öğren0>",
+ "full_content": "Tam İçerik",
+ "slower": "Daha Yavaş",
+ "new_version_announcement": "<0>Linkwarden {{version}}'da0> nelerin yeni olduğunu görün!",
+ "creating": "Oluşturuluyor...",
+ "upload_file": "Dosya Yükle",
+ "file": "Dosya",
+ "file_types": "PDF, PNG, JPG (En fazla {{size}} MB)",
+ "description": "Açıklama",
+ "auto_generated": "Bir şey sağlanmazsa otomatik olarak oluşturulacaktır.",
+ "example_link": "ör. Örnek Bağlantı",
+ "hide": "Gizle",
+ "more": "Daha Fazla",
+ "options": "Seçenekler",
+ "description_placeholder": "Notlar, düşünceler, vb.",
+ "deleting": "Siliniyor...",
+ "token_revoked": "Token İptal Edildi.",
+ "revoke_token": "Token İptal Et",
+ "revoke_confirmation": "Bu Erişim Tokenini iptal etmek istediğinizden emin misiniz? Bu tokeni kullanan uygulamalar veya hizmetler artık Linkwarden'a erişemeyecektir.",
+
+
+ "revoke": "İptal Et",
+ "sending_request": "İstek Gönderiliyor...",
+ "link_being_archived": "Bağlantı arşivleniyor...",
+ "preserved_formats": "Korunan Formatlar",
+ "available_formats": "Bu bağlantı için kullanılabilir formatlar:",
+ "readable": "Okunabilir",
+ "preservation_in_queue": "Bağlantı koruma sırada",
+ "view_latest_snapshot": "archive.org'da son anlık görüntüyü görüntüle",
+ "refresh_preserved_formats": "Korunan Formatları Yenile",
+ "this_deletes_current_preservations": "Bu mevcut korumaları siler",
+ "create_new_user": "Yeni Kullanıcı Oluştur",
+ "placeholder_johnny": "Johnny",
+ "placeholder_email": "johnny@example.com",
+ "placeholder_john": "john",
+ "user_created": "Kullanıcı Oluşturuldu!",
+ "fill_all_fields_error": "Lütfen tüm alanları doldurun.",
+ "password_change_note": "<0>Not:0> Lütfen kullanıcıya şifresini değiştirmesi gerektiğini bildirdiğinizden emin olun.",
+ "create_user": "Kullanıcı Oluştur",
+ "creating_token": "Token Oluşturuluyor...",
+ "token_created": "Token Oluşturuldu!",
+ "access_token_created": "Erişim Tokeni Oluşturuldu",
+ "token_creation_notice": "Yeni tokeniniz oluşturuldu. Lütfen bunu kopyalayın ve güvenli bir yerde saklayın. Tekrar göremezsiniz.",
+ "copied_to_clipboard": "Panoya kopyalandı!",
+ "copy_to_clipboard": "Panoya Kopyala",
+ "create_access_token": "Erişim Tokeni Oluştur",
+ "expires_in": "Şunun Süresi Doluyor",
+ "token_name_placeholder": "ör. iOS kısayolu için",
+ "create_token": "Erişim Tokeni Oluştur",
+ "7_days": "7 Gün",
+ "30_days": "30 Gün",
+ "60_days": "60 Gün",
+ "90_days": "90 Gün",
+ "no_expiration": "Son Kullanma Tarihi Yok",
+ "creating_link": "Bağlantı Oluşturuluyor...",
+ "link_created": "Bağlantı Oluşturuldu!",
+ "link_name_placeholder": "Boş bırakılırsa otomatik olarak oluşturulacaktır.",
+ "link_url_placeholder": "ör. http://example.com/",
+ "link_description_placeholder": "Notlar, düşünceler, vb.",
+ "more_options": "Daha Fazla Seçenek",
+ "hide_options": "Seçenekleri Gizle",
+ "create_link": "Bağlantı Oluştur",
+ "new_sub_collection": "Yeni Alt Koleksiyon",
+ "for_collection": "{{name}} için",
+ "create_new_collection": "Yeni Koleksiyon Oluştur",
+ "color": "Renk",
+ "reset": "Sıfırla",
+ "updating_collection": "Koleksiyon Güncelleniyor...",
+ "collection_name_placeholder": "ör. Örnek Koleksiyon",
+ "collection_description_placeholder": "Bu Koleksiyonun amacı...",
+ "create_collection_button": "Koleksiyon Oluştur",
+ "password_change_warning": "E-posta adresinizi değiştirmeden önce şifrenizi doğrulayın.",
+ "stripe_update_note": "Bu alanı güncellemek, Stripe üzerindeki fatura e-posta adresinizi de değiştirir.",
+ "sso_will_be_removed_warning": "E-posta adresinizi değiştirirseniz, mevcut {{service}} SSO bağlantıları kaldırılacaktır.",
+ "old_email": "Eski E-posta",
+ "new_email": "Yeni E-posta",
+ "confirm": "Onayla",
+ "edit_link": "Bağlantıyı Düzenle",
+ "updating": "Güncelleniyor...",
+ "updated": "Güncellendi!",
+ "placeholder_example_link": "ör. Örnek Bağlantı",
+ "make_collection_public": "Koleksiyonu Halka Aç",
+ "make_collection_public_checkbox": "Bu bir kamu koleksiyonu olsun",
+ "make_collection_public_desc": "Bu, herkesin bu koleksiyonu ve kullanıcılarını görüntülemesini sağlar.",
+ "sharable_link_guide": "Paylaşılabilir Bağlantı (Kopyalamak için tıklayın)",
+ "copied": "Kopyalandı!",
+ "members": "Üyeler",
+ "members_username_placeholder": "Kullanıcı adı (\"@\" olmadan)",
+ "owner": "Sahip",
+ "admin": "Yönetici",
+ "contributor": "Katkıda Bulunan",
+ "viewer": "Görüntüleyici",
+ "viewer_desc": "Salt okunur erişim",
+ "contributor_desc": "Bağlantıları görüntüleyebilir ve oluşturabilir",
+ "admin_desc": "Tüm Bağlantılara tam erişim",
+ "remove_member": "Üyeyi Kaldır",
+ "placeholder_example_collection": "ör. Örnek Koleksiyon",
+ "placeholder_collection_purpose": "Bu Koleksiyonun amacı...",
+ "deleting_user": "Siliniyor...",
+ "user_deleted": "Kullanıcı Silindi.",
+ "delete_user": "Kullanıcıyı Sil",
+ "confirm_user_deletion": "Bu kullanıcıyı silmek istediğinizden emin misiniz?",
+ "irreversible_action_warning": "Bu işlem geri alınamaz!",
+ "delete_confirmation": "Sil, ne yaptığımı biliyorum",
+ "delete_link": "Bağlantıyı Sil",
+ "deleted": "Silindi.",
+ "link_deletion_confirmation_message": "Bu Bağlantıyı silmek istediğinizden emin misiniz?",
+ "warning": "Uyarı",
+ "irreversible_warning": "Bu işlem geri alınamaz!",
+ "shift_key_tip": "Gelecekte bu onayı atlamak için 'Sil' tuşuna tıklarken Shift tuşunu basılı tutun.",
+ "deleting_collection": "Siliniyor...",
+ "collection_deleted": "Koleksiyon Silindi.",
+ "confirm_deletion_prompt": "Onaylamak için aşağıdaki kutuya \"{{name}}\" yazın:",
+ "type_name_placeholder": "\"{{name}}\" Buraya Yazın.",
+ "deletion_warning": "Bu koleksiyonu silmek, tüm içeriğini kalıcı olarak silecek ve önceki erişime sahip üyeler dahil olmak üzere herkese erişilemez hale getirecektir.",
+ "leave_prompt": "Mevcut koleksiyondan ayrılmak için aşağıdaki düğmeye tıklayın.",
+ "leave": "Ayrıl",
+ "edit_links": "{{count}} Bağlantıyı Düzenle",
+ "move_to_collection": "Koleksiyona Taşı",
+ "add_tags": "Etiket Ekle",
+ "remove_previous_tags": "Önceki etiketleri kaldır",
+ "delete_links": "{{count}} Bağlantıyı Sil",
+ "links_deletion_confirmation_message": "{{count}} Bağlantıyı silmek istediğinizden emin misiniz?",
+ "warning_irreversible": "Uyarı: Bu işlem geri alınamaz!",
+ "shift_key_instruction": "Gelecekte bu onayı atlamak için 'Sil' tuşuna tıklarken Shift tuşunu basılı tutun.",
+ "link_selection_error": "Bu öğeyi düzenleme veya silme izniniz yok.",
+ "no_description": "Açıklama verilmedi.",
+ "applying": "Uygulanıyor...",
+ "unpin": "Sabitleneni Kaldır",
+ "pin_to_dashboard": "Panoya Sabitle",
+ "show_link_details": "Bağlantı Ayrıntılarını Göster",
+ "hide_link_details": "Bağlantı Ayrıntılarını Gizle",
+ "link_pinned": "Bağlantı Sabitlendi!",
+ "link_unpinned": "Bağlantı Sabitlendi!",
+ "webpage": "Web Sayfası",
+ "server_administration": "Sunucu Yönetimi",
+ "all_collections": "Tüm Koleksiyonlar",
+ "dashboard": "Kontrol Paneli",
+ "demo_title": "Sadece Demo",
+ "demo_desc": "Bu sadece bir Linkwarden demo örneğidir ve yüklemeler devre dışı bırakılmıştır.",
+ "demo_desc_2": "Tam sürümü denemek istiyorsanız, ücretsiz deneme için kaydolabilirsiniz:",
+ "demo_button": "Demo kullanıcı olarak giriş yap"
+}
\ No newline at end of file
diff --git a/public/locales/uk/common.json b/public/locales/uk/common.json
new file mode 100644
index 0000000..a88a1bf
--- /dev/null
+++ b/public/locales/uk/common.json
@@ -0,0 +1,397 @@
+{
+ "user_administration": "Адміністрування користувачів",
+ "search_users": "Пошук користувачів",
+ "no_users_found": "Користувачів не знайдено.",
+ "no_user_found_in_search": "За вказаним пошуковим запитом не знайдено користувачів.",
+ "username": "Ім'я користувача",
+ "email": "Електронна скринька",
+ "subscribed": "Підписаний",
+ "created_at": "Створено",
+ "not_available": "недоступний",
+ "check_your_email": "Будь ласка, перевірте свою електронну скриньку",
+ "authenticating": "Автентифікація...",
+ "verification_email_sent": "Надіслано електронний лист для підтвердження.",
+ "verification_email_sent_desc": "Посилання для входу надіслано на вашу адресу електронної скриньки. Якщо ви не бачите листа, перевірте папку зі спамом.",
+ "resend_email": "Повторно надіслати електронний лист",
+ "invalid_credentials": "Недійсні облікові дані.",
+ "fill_all_fields": "Будь ласка, заповніть усі поля.",
+ "enter_credentials": "Введіть свої облікові дані",
+ "username_or_email": "Ім'я користувача чи електронну пошту",
+ "password": "Пароль",
+ "confirm_password": "Підтвердьте пароль",
+ "forgot_password": "Забули пароль?",
+ "login": "Логін",
+ "or_continue_with": "Або продовжити",
+ "new_here": "Ви тут новий?",
+ "sign_up": "Зареєструватися",
+ "sign_in_to_your_account": "Увійдіть у свій обліковий запис",
+ "dashboard_desc": "Короткий огляд ваших даних",
+ "link": "Посилання",
+ "links": "Посилання",
+ "collection": "Колекція",
+ "collections": "Колекції",
+ "tag": "Мітка",
+ "tags": "Мітки",
+ "recent": "Недавні",
+ "recent_links_desc": "Нещодавно додані посилання",
+ "view_all": "Переглянути всі",
+ "view_added_links_here": "Перегляньте свої нещодавно додані посилання тут!",
+ "view_added_links_here_desc": "У цьому розділі відображатимуться ваші останні додані посилання в усіх колекціях, до яких ви маєте доступ.",
+ "add_link": "Додати нове посилання",
+ "import_links": "Імпорт посилань",
+ "from_linkwarden": "Від Linkwarden",
+ "from_html": "З HTML-файлу закладок",
+ "from_wallabag": "Від Wallabag (файл JSON)",
+ "pinned": "Закріплено",
+ "pinned_links_desc": "Ваші закріплені посилання",
+ "pin_favorite_links_here": "Закріпіть тут свої улюблені посилання!",
+ "pin_favorite_links_here_desc": "Ви можете закріпити свої улюблені посилання, натиснувши три крапки на кожному посиланні та натиснувши «Закріпити на інформаційній панелі».",
+ "sending_password_link": "Надсилання посилання для відновлення пароля...",
+ "password_email_prompt": "Введіть свою електронну адресу, щоб ми могли надіслати вам посилання для створення нового пароля.",
+ "send_reset_link": "Надіслати посилання для скидання (пароля)",
+ "reset_email_sent_desc": "Перевірте свою електронну пошту на наявність посилання для скидання пароля. Якщо він не з’явиться протягом кількох хвилин, перевірте папку зі спамом.",
+ "back_to_login": "Назад до входу",
+ "email_sent": "Електронна пошта надіслана!",
+ "passwords_mismatch": "Паролі не збігаються.",
+ "password_too_short": "Паролі мають бути не менше 8 символів.",
+ "creating_account": "Створення облікового запису...",
+ "account_created": "Обліковий запис створено!",
+ "trial_offer_desc": "Розблокуйте {{count}} днів преміумсервісу безплатно!",
+ "register_desc": "Створіть новий обліковий запис",
+ "registration_disabled_desc": "Для цього випадку реєстрацію вимкнено, у разі будь-яких проблем зв’яжіться з адміністратором.",
+ "enter_details": "Введіть свої дані",
+ "display_name": "Відображуване ім'я",
+ "sign_up_agreement": "Реєструючись, ви приймаєте наші <0>Загальні положення та умови0> та <1>Політику конфіденційності1>.",
+ "need_help": "Потрібна допомога?",
+ "get_in_touch": "Зв'яжіться",
+ "already_registered": "Вже маєте акаунт?",
+ "deleting_selections": "Видалення вибраних...",
+ "links_deleted": "{{count}} посилань видалено.",
+ "link_deleted": "1 посилання видалено.",
+ "links_selected": "Вибрано {{count}} посилань",
+ "link_selected": "Вибрано 1 посилання",
+ "nothing_selected": "Нічого не вибрано",
+ "edit": "Редагувати",
+ "delete": "Видалити",
+ "nothing_found": "Нічого не знайдено.",
+ "redirecting_to_stripe": "Переспрямування на сервіс Stripe...",
+ "subscribe_title": "Підпишіться на Linkwarden!",
+ "subscribe_desc": "Ви будете перенаправлені на сторінку сервісу Stripe. Якщо виникнуть проблеми, зв’яжіться з нами за адресою <0>support@linkwarden.app0>.",
+ "monthly": "Щомісяця",
+ "yearly": "Щороку",
+ "discount_percent": "Знижка {{percent}}%",
+ "billed_monthly": "Рахунок виставляється щомісяця",
+ "billed_yearly": "Рахунок виставляється щорічно",
+ "total": "Всього",
+ "total_annual_desc": "{{count}}-денна безкоштовна пробна версія, а потім {{annualPrice}}$ щорічно",
+ "total_monthly_desc": "{{count}}-денна безкоштовна пробна версія, потім {{monthly Price}}$ на місяць",
+ "plus_tax": "+ ПДВ, якщо є",
+ "complete_subscription": "Повна підписка",
+ "sign_out": "Вийти",
+ "access_tokens": "Жетони доступу",
+ "access_tokens_description": "Жетони доступу можна використовувати для доступу до Linkwarden з інших програм і служб, не повідомляючи свого імені користувача та пароля.",
+ "new_token": "Новий жетон доступу",
+ "name": "Ім'я",
+ "created_success": "Створено!",
+ "created": "Створено",
+ "expires": "Термін дії закінчується",
+ "accountSettings": "Налаштування облікового запису",
+ "language": "Мова",
+ "profile_photo": "Фото профілю",
+ "upload_new_photo": "Завантажте нове фото...",
+ "remove_photo": "Видалити фото",
+ "make_profile_private": "Зробити профіль приватним",
+ "profile_privacy_info": "Це обмежить, хтось зможе знаходити вас і додавати до нових колекцій.",
+ "whitelisted_users": "Користувачі з білого списку",
+ "whitelisted_users_info": "Будь ласка, вкажіть ім’я користувача, якому ви хочете надати доступ до свого профілю. Розділяється комою.",
+ "whitelisted_users_placeholder": "Ваш профіль зараз прихований від усіх...",
+ "save_changes": "Зберегти зміни",
+ "import_export": "Імпорт та експорт",
+ "import_data": "Імпортуйте дані з інших платформ.",
+ "download_data": "Миттєво завантажуйте свої дані.",
+ "export_data": "Експорт даних",
+ "delete_account": "Видалити акаунт",
+ "delete_account_warning": "Це назавжди видалить УСІ посилання, колекції, мітки та архівні дані, якими ви володієте.",
+ "cancel_subscription_notice": "Це також скасує вашу підписку.",
+ "account_deletion_page": "Сторінка видалення облікового запису",
+ "applying_settings": "Застосування налаштувань...",
+ "settings_applied": "Налаштування застосовано!",
+ "email_change_request": "Запит на зміну електронної скриньки надіслано. Підтвердьте нову електронну скриньку.",
+ "image_upload_no_file_error": "Файл не вибрано. Будь ласка, виберіть зображення для завантаження.",
+ "image_upload_size_error": "Виберіть файл PNG або JPEG розміром менше ніж 1 МБ.",
+ "image_upload_format_error": "Невірний формат файлу.",
+ "importing_bookmarks": "Імпорт закладок...",
+ "import_success": "Імпортовано закладки! Перезавантаження сторінки...",
+ "more_coming_soon": "Більше смаколиків незабаром!",
+ "billing_settings": "Налаштування платежів",
+ "manage_subscription_intro": "Щоб керувати або скасувати підписку, відвідайте",
+ "billing_portal": "Платіжний портал",
+ "help_contact_intro": "Якщо вам все ще потрібна допомога або виникли проблеми, зв’яжіться з нами за адресою:",
+ "fill_required_fields": "Будь ласка, заповніть необхідні поля.",
+ "deleting_message": "Видалення всього, зачекайте...",
+ "delete_warning": "Це назавжди видалить усі посилання, колекції, мітки та архівні дані, якими ви володієте. Це також призведе до виходу з системи. Ця дія незворотна!",
+ "optional": "Необов'язково",
+ "feedback_help": "(але це дійсно допомагає нам покращуватися!)",
+ "reason_for_cancellation": "Причина скасування",
+ "please_specify": "Будь ласка, уточніть",
+ "customer_service": "Відділ обслуговування клієнтів",
+ "low_quality": "Низька якість",
+ "missing_features": "Відсутні функції",
+ "switched_service": "Зміна сервіса",
+ "too_complex": "Занадто складно",
+ "too_expensive": "Занадто дорого",
+ "unused": "Невикористаний",
+ "other": "інше",
+ "more_information": "Більше інформації (чим більше деталей, тим корисніше буде)",
+ "feedback_placeholder": "напр. Мені потрібна була функція, яка...",
+ "delete_your_account": "Видалити свій акаунт",
+ "change_password": "Змінити пароль",
+ "password_length_error": "Паролі мають бути не менше 8 символів.",
+ "applying_changes": "Застосування...",
+ "password_change_instructions": "Щоб змінити свій пароль, заповніть наступні поля. Ваш пароль має бути не менше 8 символів.",
+ "old_password": "Старий пароль",
+ "new_password": "Новий пароль",
+ "preference": "Перевага",
+ "select_theme": "Виберіть тему",
+ "dark": "темну",
+ "light": "світлу",
+ "archive_settings": "Налаштування архіву",
+ "formats_to_archive": "Формати для архівування/збереження вебсторінок:",
+ "screenshot": "Скриншот",
+ "pdf": "PDF",
+ "archive_org_snapshot": "Знімок Archive.org",
+ "link_settings": "Налаштування посилання",
+ "prevent_duplicate_links": "Запобігати повторюваним посиланням",
+ "clicking_on_links_should": "Натискання на посилання веде:",
+ "open_original_content": "Відкрити оригінальний вміст",
+ "open_pdf_if_available": "Відкрити PDF, якщо доступний",
+ "open_readable_if_available": "Відкрийте Readable, якщо доступно",
+ "open_screenshot_if_available": "Відкрийте скриншот, якщо доступний",
+ "open_webpage_if_available": "Відкрийте копію вебсторінки, якщо вона доступна",
+ "tag_renamed": "Мітка перейменована!",
+ "tag_deleted": "Мітка видалена!",
+ "rename_tag": "Перейменувати мітку",
+ "delete_tag": "Видалити мітку",
+ "list_created_with_linkwarden": "Список створено за допомогою Linkwarden",
+ "by_author": "Автор: {{author}}.",
+ "by_author_and_other": "Автор: {{author}} та ще {{count}} іншій.",
+ "by_author_and_others": "Автор: {{author}} та ще {{count}} іншіх.",
+ "search_count_link": "Пошук {{count}} посилання",
+ "search_count_links": "Пошук {{count}} посилань",
+ "collection_is_empty": "Ця колекція порожня...",
+ "all_links": "Усі посилання",
+ "all_links_desc": "Посилання з кожної колекції",
+ "you_have_not_added_any_links": "Ви ще не створили жодного посилання",
+ "collections_you_own": "Колекції, якими ви володієте",
+ "new_collection": "Нова колекція",
+ "other_collections": "Інші колекції",
+ "other_collections_desc": "Спільні колекції, учасником яких ви є",
+ "showing_count_results": "Показано {{count}} результатів",
+ "showing_count_result": "Показано {{count}} результата",
+ "edit_collection_info": "Редагувати інформацію про колекцію",
+ "share_and_collaborate": "Діліться та співпрацюйте",
+ "view_team": "Переглянути команду",
+ "team": "команда",
+ "create_subcollection": "Створення підколекції",
+ "delete_collection": "Видалити колекцію",
+ "leave_collection": "Залишити колекцію",
+ "email_verified_signing_out": "Електронна скринька підтверджена. Вихід...",
+ "invalid_token": "Недійсний жетон.",
+ "sending_password_recovery_link": "Надсилання посилання для відновлення пароля...",
+ "please_fill_all_fields": "Будь ласка, заповніть усі поля.",
+ "password_updated": "Пароль оновлено!",
+ "reset_password": "Скинути пароль",
+ "enter_email_for_new_password": "Введіть свою адресу електронної скриньки, щоб ми могли надіслати вам посилання для створення нового пароля.",
+ "update_password": "Оновити пароль",
+ "password_successfully_updated": "Ваш пароль успішно оновлено.",
+ "user_already_member": "Користувач уже існує.",
+ "you_are_already_collection_owner": "Ви вже є власником колекції.",
+ "date_newest_first": "Дата (спочатку найновіші)",
+ "date_oldest_first": "Дата (спочатку найдавніші)",
+ "name_az": "Ім'я, зростання за алфавітом (А-Я)",
+ "name_za": "Ім'я, спадання за алфавітом (Я-А)",
+ "description_az": "Опис, зростання за алфавітом (A-Z)",
+ "description_za": "Опис, спадання за алфавітом (Z-A)",
+ "all_rights_reserved": "© {{date}} <0>Linkwarden0>. Всі права захищені.",
+ "you_have_no_collections": "У вас немає колекцій...",
+ "you_have_no_tags": "У вас немає міток...",
+ "cant_change_collection_you_dont_own": "Ви не можете вносити зміни в колекцію, яка вам не належить.",
+ "account": "Обліковий запис",
+ "billing": "Виставлення рахунків",
+ "linkwarden_version": "Linkwarden {{version}}",
+ "help": "Довідка",
+ "github": "GitHub",
+ "twitter": "Twitter",
+ "mastodon": "Mastodon",
+ "link_preservation_in_queue": "Збереження посилання наразі в черзі",
+ "check_back_later": "Перевірте пізніше, щоб побачити результат",
+ "there_are_more_formats": "У черзі більше збережених форматів",
+ "settings": "Налаштування",
+ "switch_to": "Перемикнути на {{theme}} тему",
+ "logout": "Вийти",
+ "start_journey": "Почніть свою подорож, створивши нове посилання!",
+ "create_new_link": "Створити нове посилання",
+ "new_link": "Нове посилання",
+ "create_new": "Створити новий...",
+ "pwa_install_prompt": "Установіть Linkwarden на головний екран для швидшого доступу та покращеного досвіду. <0>Докладніше0>",
+ "full_content": "Повний вміст",
+ "slower": "повільніше",
+ "new_version_announcement": "Подивіться, що нового в <0>Linkwarden {{version}}!0>",
+ "creating": "Створення...",
+ "upload_file": "Завантажте файл",
+ "file": "Файл",
+ "file_types": "PDF, PNG, JPG (до {{size}} МБ)",
+ "description": "Опис",
+ "auto_generated": "Буде створено автоматично, якщо нічого не надано.",
+ "example_link": "напр. Приклад посилання",
+ "hide": "Приховувати",
+ "more": "Більше",
+ "options": "Параметри",
+ "description_placeholder": "Нотатки, думки тощо.",
+ "deleting": "Видалення...",
+ "token_revoked": "Жетон відкликано.",
+ "revoke_token": "Відкликати жетон",
+ "revoke_confirmation": "Ви впевнені, що бажаєте відкликати цей жетон доступу? Будь-які програми чи служби, що використовують цей жетон, більше не зможуть отримати доступ до Linkwarden за допомогою нього.",
+ "revoke": "Відкликати",
+ "sending_request": "Надсилання запиту...",
+ "link_being_archived": "Посилання архівується...",
+ "preserved_formats": "Збережені формати",
+ "available_formats": "Для цього посилання доступні такі формати:",
+ "readable": "Читабельний",
+ "preservation_in_queue": "У черзі збереження посилання",
+ "view_latest_snapshot": "Перегляньте останній знімок на archive.org",
+ "refresh_preserved_formats": "Оновити збережені формати",
+ "this_deletes_current_preservations": "Це видаляє поточні збереження",
+ "create_new_user": "Створити нового користувача",
+ "placeholder_johnny": "Микола",
+ "placeholder_email": "mykola@ukr.net",
+ "placeholder_john": "mykola",
+ "user_created": "Користувач створений!",
+ "fill_all_fields_error": "Будь ласка, заповніть усі поля.",
+ "password_change_note": "<0>Примітка:0> переконайтеся, що ви повідомили користувача, що йому потрібно змінити свій пароль.",
+ "create_user": "Створити користувача",
+ "creating_token": "Створення жетона...",
+ "token_created": "Жетон створено!",
+ "access_token_created": "Жетон доступу створено",
+ "token_creation_notice": "Ваш новий жетон створено. Будь ласка, скопіюйте його та зберігайте в безпечному місці. Ви не зможете побачити це знову.",
+ "copied_to_clipboard": "Скопійовано в буфер обміну!",
+ "copy_to_clipboard": "Копіювати в буфер обміну",
+ "create_access_token": "Створіть жетон доступу",
+ "expires_in": "Термін дії закінчується через",
+ "token_name_placeholder": "напр. Для ярлика iOS",
+ "create_token": "Створити жетон доступу",
+ "7_days": "7 днів",
+ "30_days": "30 днів",
+ "60_days": "60 днів",
+ "90_days": "90 днів",
+ "no_expiration": "Без терміну дії",
+ "creating_link": "Створення посилання...",
+ "link_created": "Посилання створено!",
+ "link_name_placeholder": "Буде створено автоматично, якщо залишити поле пустим.",
+ "link_url_placeholder": "напр. http://example.com/",
+ "link_description_placeholder": "Нотатки, думки тощо.",
+ "more_options": "Більш параметрів",
+ "hide_options": "Сховати параметри",
+ "create_link": "Створити посилання",
+ "new_sub_collection": "Нова підколекція",
+ "for_collection": "Для {{name}}",
+ "create_new_collection": "Створити нову колекцію",
+ "color": "Колір",
+ "reset_defaults": "Скинути до значень за замовчуванням",
+ "updating_collection": "Оновлення колекції...",
+ "collection_name_placeholder": "напр. Збірка прикладів",
+ "collection_description_placeholder": "Мета цієї збірки...",
+ "create_collection_button": "Створити колекцію",
+ "password_change_warning": "Перш ніж змінювати адресу електронної скриньки, підтвердьте свій пароль.",
+ "stripe_update_note": " Оновлення цього поля також змінить вашу платіжну електронну скриньку на сервісі Stripe.",
+ "sso_will_be_removed_warning": "Якщо ви зміните адресу електронної скриньки, усі теперішні з’єднання SSO {{service}} буде видалено.",
+ "old_email": "Стара електронна скринька",
+ "new_email": "Нова електронна скринька",
+ "confirm": "Підтвердити",
+ "edit_link": "Редагувати посилання",
+ "updating": "Оновлення...",
+ "updated": "Оновлено!",
+ "placeholder_example_link": "напр. Приклад посилання",
+ "make_collection_public": "Зробити колекцію публічною",
+ "make_collection_public_checkbox": "Зробити це загальнодоступною колекцією",
+ "make_collection_public_desc": "Це дозволить будь-кому переглядати цю колекцію та її користувачів.",
+ "sharable_link": "Посилання для спільного використання",
+ "copied": "Скопійовано!",
+ "members": "Члени",
+ "members_username_placeholder": "Ім'я користувача (без '@')",
+ "owner": "Власник",
+ "admin": "Адмін",
+ "contributor": "Дописувач",
+ "viewer": "Переглядач",
+ "viewer_desc": "Доступ лише для читання",
+ "contributor_desc": "Може переглядати та створювати посилання",
+ "admin_desc": "Повний доступ до всіх посилань",
+ "remove_member": "Видалити учасника",
+ "placeholder_example_collection": "напр. Збірка прикладів",
+ "placeholder_collection_purpose": "Мета цієї колекції...",
+ "deleting_user": "Видалення...",
+ "user_deleted": "Користувача видалено.",
+ "delete_user": "Видалити користувача",
+ "confirm_user_deletion": "Ви впевнені, що хочете видалити цього користувача?",
+ "irreversible_action_warning": "Це незворотна дія!",
+ "delete_confirmation": "Видаліть, я знаю, що роблю",
+ "delete_link": "Видалити посилання",
+ "deleted": "Видалено.",
+ "link_deletion_confirmation_message": "Ви впевнені, що хочете видалити це посилання?",
+ "warning": "Попередження",
+ "irreversible_warning": "Це незворотна дія!",
+ "shift_key_tip": "Утримуйте клавішу Shift під час натискання 'Видалити', щоб обійти це підтвердження в майбутньому.",
+ "deleting_collection": "Видалення...",
+ "collection_deleted": "Колекцію видалено.",
+ "confirm_deletion_prompt": "Щоб підтвердити, введіть \"{{name}}\" у полі нижче:",
+ "type_name_placeholder": "Введіть \"{{name}}\" тут.",
+ "deletion_warning": "Видалення цієї колекції призведе до остаточного видалення всього її вмісту, і вона стане недоступною для всіх, включаючи учасників з попереднім доступом.",
+ "leave_prompt": "Натисніть кнопку нижче, щоб залишити поточну колекцію.",
+ "leave": "Залишити",
+ "edit_links": "Редагувати {{count}} посилання",
+ "move_to_collection": "Перейти до колекції",
+ "add_tags": "Додайте мітки",
+ "remove_previous_tags": "Видалити попередні мітки",
+ "delete_links": "Видалити {{count}} посилання",
+ "links_deletion_confirmation_message": "Ви впевнені, що хочете видалити ці посилання? ",
+ "warning_irreversible": "Увага: Це незворотна дія!",
+ "shift_key_instruction": "Утримуйте клавішу 'Shift' під час натискання 'Видалити', щоб обійти це підтвердження в майбутньому.",
+ "link_selection_error": "У вас немає дозволу редагувати або видаляти цей елемент.",
+ "no_description": "Опис не надано.",
+ "applying": "Застосування...",
+ "unpin": "Відкріпити",
+ "pin_to_dashboard": "Закріплення на інформаційній панелі",
+ "show_link_details": "Показати деталі посилання",
+ "link_pinned": "Посилання закріплено!",
+ "link_unpinned": "Посилання відкріплене!",
+ "webpage": "Вебсторінка",
+ "server_administration": "Адміністрування сервера",
+ "all_collections": "Всі колекції",
+ "dashboard": "Інформаційна панелі",
+ "demo_title": "Тільки демонстрація",
+ "demo_desc": "Це лише демонстраційний екземпляр Linkwarden, і завантаження вимкнено.",
+ "demo_desc_2": "Якщо ви хочете спробувати повну версію, ви можете підписатися на безплатну пробну версію за посиланням:",
+ "demo_button": "Увійдіть як демокористувач",
+ "regular": "Звичний",
+ "thin": "Тонкий",
+ "bold": "Жирний",
+ "fill": "Заповнений",
+ "duotone": "У двоколірному режимі",
+ "light_icon": "Світлий",
+ "search": "Пошук",
+ "set_custom_icon": "Встановити користувальницьку піктограму",
+ "view": "Переглянути",
+ "show": "Показати",
+ "image": "Зображення",
+ "icon": "Піктограма",
+ "date": "Дата",
+ "preview_unavailable": "Попередній перегляд недоступний",
+ "saved": "Збережено",
+ "untitled": "Без назви",
+ "no_tags": "Без міток.",
+ "no_description_provided": "Опис не надано.",
+ "change_icon": "Змінити піктограму",
+ "upload_preview_image": "Завантажте зображення для попереднього перегляду",
+ "columns": "Стовпці",
+ "default": "За замовчуванням"
+}
\ No newline at end of file
diff --git a/public/locales/zh-TW/common.json b/public/locales/zh-TW/common.json
new file mode 100644
index 0000000..d3efefc
--- /dev/null
+++ b/public/locales/zh-TW/common.json
@@ -0,0 +1,374 @@
+{
+ "user_administration": "使用者管理",
+ "search_users": "搜尋使用者",
+ "no_users_found": "未找到使用者。",
+ "no_user_found_in_search": "在給定的搜尋查詢中未找到使用者。",
+ "username": "使用者名稱",
+ "email": "電子郵件",
+ "subscribed": "訂閱",
+ "created_at": "建立時間",
+ "not_available": "N/A",
+ "check_your_email": "檢查你的電子郵件",
+ "authenticating": "身份驗證中...",
+ "verification_email_sent": "發送驗證郵件。",
+ "verification_email_sent_desc": "登入連結已發送到您的電子郵件信箱。如果沒有看到郵件,請檢查你的垃圾郵件資料夾。",
+ "resend_email": "重新發送電子郵件",
+ "invalid_credentials": "無效憑證",
+ "fill_all_fields": "請填寫所有欄位",
+ "enter_credentials": "帳號登入",
+ "username_or_email": "使用者名稱或電子郵件",
+ "password": "密碼",
+ "confirm_password": "確認密碼",
+ "forgot_password": "忘記密碼?",
+ "login": "登入",
+ "or_continue_with": "使用其他方式登入",
+ "new_here": "新用戶?",
+ "sign_up": "註冊",
+ "sign_in_to_your_account": "登入你的帳戶",
+ "dashboard_desc": "您的數據概覽",
+ "link": "連結",
+ "links": "連結",
+ "collection": "收藏夾",
+ "collections": "收藏夾",
+ "tag": "標籤",
+ "tags": "標籤",
+ "recent": "最近",
+ "recent_links_desc": "最近新增的連結",
+ "view_all": "查看全部",
+ "view_added_links_here": "查看最近新增的連結!",
+ "view_added_links_here_desc": "此部分將顯示您有權存取的每個收藏夾中最新新增的連結。",
+ "add_link": "新增連結",
+ "import_links": "匯入連結",
+ "from_linkwarden": "從 Linkwarden",
+ "from_html": "從書籤 HTML 檔案",
+ "from_wallabag": "從 Wallabag(JSON 檔案)",
+ "pinned": "釘選",
+ "pinned_links_desc": "您釘選的連結",
+ "pin_favorite_links_here": "在這裡釘選您最喜歡的連結!",
+ "pin_favorite_links_here_desc": "您可以透過點擊每個連結上的三個點,然後點擊「釘選到儀表板」來釘選您最喜歡的連結。",
+ "sending_password_link": "發送重設密碼連結",
+ "password_email_prompt": "輸入您的電子郵件,我們會給您發送一個重設密碼的連結。",
+ "send_reset_link": "發送重設連結",
+ "reset_email_sent_desc": "檢查您的電子郵件以取得重設密碼的連結。如果它在幾分鐘內沒有出現,請檢查您的垃圾郵件資料夾。",
+ "back_to_login": "返回登入",
+ "email_sent": "郵件已發送!",
+ "passwords_mismatch": "密碼錯誤。",
+ "password_too_short": "密碼需至少 8 個字元。",
+ "creating_account": "正在建立帳戶...",
+ "account_created": "帳戶建立成功!",
+ "trial_offer_desc": "免費解鎖 {{count}} 天的高級服務!",
+ "register_desc": "建立新帳戶",
+ "registration_disabled_desc": "此系統已停用註冊,如有任何問題,請聯絡管理員。",
+ "enter_details": "輸入您的詳細資訊",
+ "display_name": "顯示名稱",
+ "sign_up_agreement": "註冊即表示您同意遵守我們的 <0>服務條款0> 和 <1>隱私政策1>。",
+ "need_help": "需要幫助嗎?",
+ "get_in_touch": "聯絡我們",
+ "already_registered": "已經有帳戶?",
+ "deleting_selections": "正在刪除選取的連結...",
+ "links_deleted": "已刪除 {{count}} 個連結。",
+ "link_deleted": "已刪除 1 個連結。",
+ "links_selected": "已選取 {{count}} 個連結。",
+ "link_selected": "已選取 1 個連結。",
+ "nothing_selected": "未選取任何內容",
+ "edit": "編輯",
+ "delete": "刪除",
+ "nothing_found": "沒有找到任何內容。",
+ "redirecting_to_stripe": "正在重新導向到 Stripe...",
+ "subscribe_title": "訂閱 Linkwarden!",
+ "subscribe_desc": "您將跳轉到 Stripe,如有任何問題請隨時聯繫我們 <0>support@linkwarden.app0>。",
+ "monthly": "每月",
+ "yearly": "每年",
+ "discount_percent": "{{percent}}% 折扣",
+ "billed_monthly": "每月計費",
+ "billed_yearly": "每年計費",
+ "total": "總計",
+ "total_annual_desc": "{{count}} 天免費體驗,然後每年 ${{annualPrice}}",
+ "total_monthly_desc": "{{count}} 天免費體驗,然後每月 ${{monthlyPrice}}",
+ "plus_tax": "+稅金(如適用)",
+ "complete_subscription": "完成訂閱",
+ "sign_out": "登出",
+ "access_tokens": "Access Tokens",
+ "access_tokens_description": "Access Tokens 可用於從其他應用程式和服務存取 Linkwarden,而無需洩露您的使用者名稱和密碼。",
+ "new_token": "新 Access Tokens",
+ "name": "名稱",
+ "created_success": "建立成功!",
+ "created": "已建立",
+ "expires": "過期",
+ "accountSettings": "帳戶設定",
+ "language": "語言",
+ "profile_photo": "頭像",
+ "upload_new_photo": "上傳新頭像",
+ "remove_photo": "移除照片",
+ "make_profile_private": "將個人資料設為私人",
+ "profile_privacy_info": "這將限制誰可以找到您並將您添加到新收藏夾。",
+ "whitelisted_users": "白名單使用者",
+ "whitelisted_users_info": "請提供您希望允許查看您個人資料的使用者名稱,以逗號分隔。",
+ "whitelisted_users_placeholder": "您的資料現在對所有人都是隱藏的。",
+ "save_changes": "儲存變更",
+ "import_export": "匯入 & 匯出",
+ "import_data": "從其他平台匯入",
+ "download_data": "下載資料",
+ "export_data": "匯出資料",
+ "delete_account": "刪除帳戶",
+ "delete_account_warning": "這將永久刪除您擁有的所有連結、收藏夾、標籤和存檔資料。",
+ "cancel_subscription_notice": "這將取消您的訂閱。",
+ "account_deletion_page": "帳戶刪除頁面",
+ "applying_settings": "正在套用設定...",
+ "settings_applied": "設定已套用!",
+ "email_change_request": "已發送電子郵件變更請求。請確認新的電子郵件地址。",
+ "image_upload_size_error": "請選擇小於 1 MB 的 PNG 或 JPEG 檔案。",
+ "image_upload_format_error": "無效的檔案格式。",
+ "importing_bookmarks": "正在匯入書籤...",
+ "import_success": "書籤已匯入!請重新整理頁面。",
+ "more_coming_soon": "更多功能即將推出...",
+ "billing_settings": "帳單設定",
+ "manage_subscription_intro": "要管理/取消訂閱,請訪問",
+ "billing_portal": "帳單管理",
+ "help_contact_intro": "如果您仍然需要協助或遇到任何問題,請隨時與我們聯繫:",
+ "fill_required_fields": "請填寫必填欄位。",
+ "deleting_message": "正在刪除所有內容,請稍候...",
+ "delete_warning": "這將永久刪除您擁有的所有連結、收藏夾、標籤和存檔資料。它還將登出您的帳戶。此操作不可逆!",
+ "optional": "可選",
+ "feedback_help": "(但它確實能幫助我們改善!)",
+ "reason_for_cancellation": "取消原因",
+ "please_specify": "請指定",
+ "customer_service": "客戶服務",
+ "low_quality": "品質不佳",
+ "missing_features": "缺少功能",
+ "switched_service": "選擇服務",
+ "too_complex": "太複雜",
+ "too_expensive": "太昂貴",
+ "unused": "未使用",
+ "other": "其他",
+ "more_information": "更多資訊(越詳細,越有幫助)",
+ "feedback_placeholder": "例如,我需要一個功能...",
+ "delete_your_account": "刪除帳戶",
+ "change_password": "更改密碼",
+ "password_length_error": "密碼需至少 8 個字元。",
+ "applying_changes": "正在套用...",
+ "password_change_instructions": "要更改您的密碼,請填寫以下內容。您的密碼至少應為 8 個字元。",
+ "old_password": "舊密碼",
+ "new_password": "新密碼",
+ "preference": "偏好設定",
+ "select_theme": "選擇主題",
+ "dark": "深色",
+ "light": "淺色",
+ "archive_settings": "封存設定",
+ "formats_to_archive": "封存/保存網頁格式:",
+ "screenshot": "截圖",
+ "pdf": "PDF",
+ "archive_org_snapshot": "Archive.org 快照",
+ "link_settings": "連結設定",
+ "prevent_duplicate_links": "防止重複連結",
+ "clicking_on_links_should": "點擊連結:",
+ "open_original_content": "開啟原始內容",
+ "open_pdf_if_available": "開啟 PDF(如果有)",
+ "open_readable_if_available": "開啟可讀視圖(如果可用)",
+ "open_screenshot_if_available": "開啟截圖(如果有)",
+ "open_webpage_if_available": "開啟網頁副本(如果有)",
+ "tag_renamed": "標籤已重新命名!",
+ "tag_deleted": "標籤已刪除!",
+ "rename_tag": "重新命名標籤",
+ "delete_tag": "刪除標籤",
+ "list_created_with_linkwarden": "使用 Linkwarden 建立的清單",
+ "by_author": "作者 {{author}}",
+ "by_author_and_other": "作者:{{author}} 和其他 {{count}} 人",
+ "by_author_and_others": "作者:{{author}} 和其他 {{count}} 人",
+ "search_count_link": "搜尋 {{count}} 個連結",
+ "search_count_links": "搜尋 {{count}} 個連結",
+ "collection_is_empty": "此收藏夾為空",
+ "all_links": "所有連結",
+ "all_links_desc": "所有收藏夾的連結",
+ "you_have_not_added_any_links": "您還沒有新增任何連結",
+ "collections_you_own": "您的收藏夾",
+ "new_collection": "新收藏夾",
+ "other_collections": "其他收藏夾",
+ "other_collections_desc": "您所屬的共享收藏夾",
+ "showing_count_results": "顯示 {{count}} 筆結果",
+ "showing_count_result": "顯示 {{count}} 筆結果",
+ "edit_collection_info": "編輯收藏夾資訊",
+ "share_and_collaborate": "共享與協作",
+ "view_team": "查看團隊",
+ "team": "團隊",
+ "create_subcollection": "建立子收藏夾",
+ "delete_collection": "刪除收藏夾",
+ "leave_collection": "離開收藏夾",
+ "email_verified_signing_out": "電子郵件已驗證。正在登出...",
+ "invalid_token": "無效的 token",
+ "sending_password_recovery_link": "正在發送密碼重設連結...",
+ "please_fill_all_fields": "請填寫所有欄位。",
+ "password_updated": "密碼已更新!",
+ "reset_password": "重設密碼",
+ "enter_email_for_new_password": "輸入您的電子郵件,以便我們向您發送建立新密碼的連結。",
+ "update_password": "更新密碼",
+ "password_successfully_updated": "您的密碼已成功更新。",
+ "user_already_member": "使用者已存在。",
+ "you_are_already_collection_owner": "您已經是收藏夾的擁有者。",
+ "date_newest_first": "日期(最新)",
+ "date_oldest_first": "日期(最早)",
+ "name_az": "名稱(A-Z)",
+ "name_za": "名稱(Z-A)",
+ "description_az": "描述(A-Z)",
+ "description_za": "描述(Z-A)",
+ "all_rights_reserved": "© {{date}} <0>Linkwarden0> 版權所有",
+ "you_have_no_collections": "您還沒有收藏夾...",
+ "you_have_no_tags": "您還沒有標籤...",
+ "cant_change_collection_you_dont_own": "您無法對不屬於您的收藏夾進行更改。",
+ "account": "帳戶",
+ "billing": "帳單",
+ "linkwarden_version": "Linkwarden {{version}}",
+ "help": "說明",
+ "github": "GitHub",
+ "twitter": "Twitter",
+ "mastodon": "Mastodon",
+ "link_preservation_in_queue": "連結保存正在處理中...",
+ "check_back_later": "請稍後再查看結果",
+ "there_are_more_formats": "隊列中有更多已保存的格式。",
+ "settings": "設定",
+ "switch_to": "切換到 {{theme}}",
+ "logout": "登出",
+ "start_journey": "透過建立新的連結開始您的旅程!",
+ "create_new_link": "建立新連結",
+ "new_link": "新連結",
+ "create_new": "新建",
+ "pwa_install_prompt": "安裝 Linkwarden 到您的主畫面,以獲得更快的存取和增強的體驗。<0>了解更多0>",
+ "full_content": "完整內容",
+ "slower": "較慢",
+ "new_version_announcement": "查看 <0>Linkwarden {{version}}0> 了解新功能。",
+ "creating": "正在建立...",
+ "upload_file": "上傳檔案",
+ "file": "檔案",
+ "file_types": "PDF,PNG,JPG(不超過 {{size}} MB)",
+ "description": "描述",
+ "auto_generated": "若未提供將自動產生。",
+ "example_link": "例如:範例連結",
+ "hide": "隱藏",
+ "more": "更多",
+ "options": "選項",
+ "description_placeholder": "筆記、想法等等。",
+ "deleting": "正在刪除...",
+ "token_revoked": "Token 已撤銷。",
+ "revoke_token": "撤銷 Token",
+ "revoke_confirmation": "確定要撤銷此 Access Token 嗎?任何使用此 Token 的應用程式或服務將無法再使用它存取 Linkwarden。",
+ "revoke": "撤銷",
+ "sending_request": "正在發送請求...",
+ "link_being_archived": "連結正在封存...",
+ "preserved_formats": "保存格式",
+ "available_formats": "以下格式可用於此連結:",
+ "readable": "可讀視圖",
+ "preservation_in_queue": "連結保存正在處理中...",
+ "view_latest_snapshot": "在 archive.org 上查看最新快照",
+ "refresh_preserved_formats": "重新整理保存格式",
+ "this_deletes_current_preservations": "這將刪除目前的保存",
+ "create_new_user": "建立新使用者",
+ "placeholder_johnny": "Johnny",
+ "placeholder_email": "johnny@example.com",
+ "placeholder_john": "john",
+ "user_created": "使用者已建立",
+ "fill_all_fields_error": "請填寫所有欄位。",
+ "password_change_note": "<0>注意:0>請務必通知使用者他們需要更改密碼。",
+ "create_user": "建立使用者",
+ "creating_token": "正在建立 Token...",
+ "token_created": "Token 建立完成",
+ "access_token_created": "Access Token 已建立",
+ "token_creation_notice": "您的新 Token 已建立。請複製並保存在安全的地方。您將無法再看到它。",
+ "copied_to_clipboard": "已複製到剪貼簿",
+ "copy_to_clipboard": "複製到剪貼簿",
+ "create_access_token": "建立一個 Access Token",
+ "expires_in": "有效期:",
+ "token_name_placeholder": "例如:iOS 快捷方式",
+ "create_token": "建立 Access Token",
+ "7_days": "7 天",
+ "30_days": "30 天",
+ "60_days": "60 天",
+ "90_days": "90 天",
+ "no_expiration": "無期限",
+ "creating_link": "正在建立連結...",
+ "link_created": "連結已建立!",
+ "link_name_placeholder": "若留空將自動產生。",
+ "link_url_placeholder": "例如:http://example.com/",
+ "link_description_placeholder": "筆記、想法等等。",
+ "more_options": "更多選項",
+ "hide_options": "隱藏選項",
+ "create_link": "建立連結",
+ "new_sub_collection": "新子收藏夾",
+ "for_collection": "針對 {{name}}",
+ "create_new_collection": "建立新收藏夾",
+ "color": "顏色",
+ "reset": "重設",
+ "collection_name_placeholder": "例如:範例收藏夾",
+ "collection_description_placeholder": "此收藏夾用於...",
+ "create_collection_button": "建立收藏夾",
+ "password_change_warning": "更改電子郵件前,請確認密碼。",
+ "stripe_update_note": " 更新此欄位也會更改 Stripe 上的帳單電子郵件。",
+ "sso_will_be_removed_warning": "如果您更改電子郵件地址,任何現有的 {{service}} SSO 連結都將被刪除。",
+ "old_email": "舊電子郵件",
+ "new_email": "新電子郵件",
+ "confirm": "確認",
+ "edit_link": "編輯連結",
+ "updating": "正在更新...",
+ "updated": "已更新",
+ "placeholder_example_link": "例如:範例連結",
+ "make_collection_public": "公開收藏夾",
+ "make_collection_public_checkbox": "將其設為公開收藏夾",
+ "make_collection_public_desc": "這將允許任何人查看該收藏夾及其使用者。",
+ "sharable_link_guide": "可分享的連結(點擊複製)",
+ "copied": "已複製",
+ "members": "成員",
+ "members_username_placeholder": "使用者名稱(不含 '@')",
+ "owner": "擁有者",
+ "admin": "管理員",
+ "contributor": "Contributor",
+ "viewer": "Viewer",
+ "viewer_desc": "唯讀存取",
+ "contributor_desc": "可以查看和建立連結",
+ "admin_desc": "完全存取所有連結",
+ "remove_member": "移除成員",
+ "placeholder_example_collection": "例如:範例收藏夾",
+ "placeholder_collection_purpose": "此收藏夾的目的...",
+ "deleting_user": "正在刪除使用者...",
+ "user_deleted": "使用者已刪除",
+ "delete_user": "刪除使用者",
+ "confirm_user_deletion": "確定要刪除此使用者嗎?",
+ "irreversible_action_warning": "此操作不可逆!",
+ "delete_confirmation": "刪除,我知道我在做什麼。",
+ "delete_link": "刪除連結",
+ "deleted": "已刪除",
+ "link_deletion_confirmation_message": "要刪除此連結嗎?",
+ "warning": "警告",
+ "irreversible_warning": "此操作不可逆!",
+ "shift_key_tip": "按住 Shift 鍵並點擊「刪除」即可在以後繞過此確認。",
+ "deleting_collection": "正在刪除...",
+ "collection_deleted": "收藏夾已刪除。",
+ "confirm_deletion_prompt": "請確認,在下面的輸入框中輸入 \"{{name}}\":",
+ "type_name_placeholder": "在此輸入 \"{{name}}\" 。",
+ "deletion_warning": "刪除此收藏夾將永久清除其所有內容,並且所有人都將無法存取,包括之前具有存取權限的成員。",
+ "leave_prompt": "點擊下面的按鈕離開當前收藏夾。",
+ "leave": "離開",
+ "edit_links": "編輯 {{count}} 個連結",
+ "move_to_collection": "移至收藏夾",
+ "add_tags": "新增標籤",
+ "remove_previous_tags": "刪除之前的標籤",
+ "delete_links": "刪除 {{count}} 個連結",
+ "links_deletion_confirmation_message": "確定要刪除 {{count}} 個連結嗎?",
+ "warning_irreversible": "警告:此操作不可逆!",
+ "shift_key_instruction": "按住「Shift」鍵並點擊「刪除」即可在以後繞過此確認。",
+ "link_selection_error": "您無權編輯或刪除此項目。",
+ "no_description": "未提供描述",
+ "applying": "正在套用...",
+ "unpin": "取消釘選",
+ "pin_to_dashboard": "釘選到儀表板",
+ "show_link_details": "顯示連結詳細資訊",
+ "hide_link_details": "隱藏連結詳細資訊",
+ "link_pinned": "連結已釘選!",
+ "link_unpinned": "連結已取消釘選!",
+ "webpage": "網頁",
+ "server_administration": "系統管理",
+ "all_collections": "所有收藏夾",
+ "dashboard": "儀表板",
+ "demo_title": "僅供展示",
+ "demo_desc": "這只是 Linkwarden 的展示實例,禁止上傳檔案。",
+ "demo_desc_2": "如果您想嘗試完整版,您可以註冊免費試用:",
+ "demo_button": "以展示用戶登入"
+}
\ No newline at end of file
diff --git a/public/locales/zh/common.json b/public/locales/zh/common.json
new file mode 100644
index 0000000..b5b7977
--- /dev/null
+++ b/public/locales/zh/common.json
@@ -0,0 +1,374 @@
+{
+ "user_administration": "用户管理",
+ "search_users": "搜索用户",
+ "no_users_found": "未找到用户。",
+ "no_user_found_in_search": "在给定的搜索查询中未找到用户。",
+ "username": "用户名",
+ "email": "邮箱",
+ "subscribed": "订阅",
+ "created_at": "创建时间",
+ "not_available": "N/A",
+ "check_your_email": "检查你的邮箱",
+ "authenticating": "身份验证中...",
+ "verification_email_sent": "发送验证邮件。",
+ "verification_email_sent_desc": "登录链接已发送到您的邮箱。如果没有看到邮件,请检查你的垃圾邮件文件夹。",
+ "resend_email": "重新发送邮件",
+ "invalid_credentials": "无效凭证",
+ "fill_all_fields": "请填写所有字段",
+ "enter_credentials": "账号登录",
+ "username_or_email": "用户名或邮箱",
+ "password": "密码",
+ "confirm_password": "确认密码",
+ "forgot_password": "忘记密码?",
+ "login": "登录",
+ "or_continue_with": "第三方登录",
+ "new_here": "新用户?",
+ "sign_up": "注册",
+ "sign_in_to_your_account": "登录你的账户",
+ "dashboard_desc": "你的数据概览",
+ "link": "链接",
+ "links": "链接",
+ "collection": "收藏夹",
+ "collections": "收藏夹",
+ "tag": "标签",
+ "tags": "标签",
+ "recent": "最近",
+ "recent_links_desc": "最近添加的链接",
+ "view_all": "查看全部",
+ "view_added_links_here": "查看最近添加的链接!",
+ "view_added_links_here_desc": "此部分将查看您有权访问的每个收藏夹中最新添加的链接。",
+ "add_link": "添加新链接",
+ "import_links": "导入链接",
+ "from_linkwarden": "从 Linkwarden",
+ "from_html": "从书签 HTML 文件",
+ "from_wallabag": "从 Wallabag(JSON 文件)",
+ "pinned": "置顶",
+ "pinned_links_desc": "你置顶的链接",
+ "pin_favorite_links_here": "在这里置顶您最喜欢的链接!",
+ "pin_favorite_links_here_desc": "您可以通过点击每个链接上的三个点,然后点击“置顶到仪表板”来置顶您最喜欢的链接。",
+ "sending_password_link": "发送重置密码链接",
+ "password_email_prompt": "输入你的邮箱,我们会给你发送一个重置密码的链接。",
+ "send_reset_link": "发送重置链接",
+ "reset_email_sent_desc": "检查你的邮箱以获取重置密码的链接。如果它在几分钟内没有出现,请检查你的垃圾邮件文件夹。",
+ "back_to_login": "返回登录",
+ "email_sent": "邮件已发送!",
+ "passwords_mismatch": "密码错误。",
+ "password_too_short": "密码需至少 8 个字符。",
+ "creating_account": "正在创建账户...",
+ "account_created": "创建账户成功!",
+ "trial_offer_desc": "免费解锁 {{count}} 天的高级服务!",
+ "register_desc": "创建新的账户",
+ "registration_disabled_desc": "此实例已禁用注册,如有任何问题,请与管理员联系。",
+ "enter_details": "输入您的详细信息",
+ "display_name": "昵称",
+ "sign_up_agreement": "注册即表示您同意遵守我们的 <0>服务条款0> 和 <1>隐私政策1>。",
+ "need_help": "需要帮助吗?",
+ "get_in_touch": "保持联系",
+ "already_registered": "已有账户?",
+ "deleting_selections": "正在删除选中的链接...",
+ "links_deleted": "{{count}} 个链接已删除。",
+ "link_deleted": "1 个链接已删除。",
+ "links_selected": "{{count}} 个链接已选中。",
+ "link_selected": "1 个链接已选中。",
+ "nothing_selected": "未选中任何内容",
+ "edit": "编辑",
+ "delete": "删除",
+ "nothing_found": "沒有找到任何内容。",
+ "redirecting_to_stripe": "重定向到 Stripe...",
+ "subscribe_title": "订阅 Linkwarden!",
+ "subscribe_desc": "你将跳转到 Stripe,如有任何问题请随时联系我们 <0>support@linkwarden.app0> 。",
+ "monthly": "每月",
+ "yearly": "每年",
+ "discount_percent": "{{percent}}% 折扣",
+ "billed_monthly": "月付",
+ "billed_yearly": "年付",
+ "total": "总计",
+ "total_annual_desc": "{{count}}-天免费体验,然后 ${{annualPrice}} 每年",
+ "total_monthly_desc": "{{count}}-天免费体验,然后 ${{monthlyPrice}} 每月",
+ "plus_tax": "+增值税(如适用)",
+ "complete_subscription": "完成订阅",
+ "sign_out": "退出",
+ "access_tokens": "Access Tokens",
+ "access_tokens_description": "Access Tokens 可用于从其他应用程序和服务访问 Linkwarden,而无需泄露您的用户名和密码。",
+ "new_token": "新 Access Token",
+ "name": "名称",
+ "created_success": "创建成功!",
+ "created": "已创建",
+ "expires": "过期",
+ "accountSettings": "账户设置",
+ "language": "语言",
+ "profile_photo": "头像",
+ "upload_new_photo": "上传新头像",
+ "remove_photo": "移除照片",
+ "make_profile_private": "将个人资料设为私密",
+ "profile_privacy_info": "这将限制谁可以找到你并将你添加到新收藏夹。",
+ "whitelisted_users": "白名单用户",
+ "whitelisted_users_info": "请提供您希望允许查看您个人资料的用户的用户名,以逗号分隔。",
+ "whitelisted_users_placeholder": "你的资料现在对所有人都是隐藏的。",
+ "save_changes": "保存修改",
+ "import_export": "导入 & 导出",
+ "import_data": "从其它平台导入",
+ "download_data": "下载数据",
+ "export_data": "导出数据",
+ "delete_account": "删除账户",
+ "delete_account_warning": "这将永久删除您拥有的所有链接、收藏夹、标签和存档数据。",
+ "cancel_subscription_notice": "它将取消你的订阅。",
+ "account_deletion_page": "账户删除页面",
+ "applying_settings": "应用设置中...",
+ "settings_applied": "已应用设置!",
+ "email_change_request": "已发送电子邮件更改请求。请确认新的邮箱地址。",
+ "image_upload_size_error": "请选择小于 1 MB的 PNG 或 JPEG 文件。",
+ "image_upload_format_error": "无效的文件格式。",
+ "importing_bookmarks": "正在导入书签...",
+ "import_success": "已导入书签!请刷新页面。",
+ "more_coming_soon": "即将推出...",
+ "billing_settings": "账单设置",
+ "manage_subscription_intro": "要管理/取消订阅,请访问",
+ "billing_portal": "账单管理",
+ "help_contact_intro": "如果您仍然需要帮助或遇到任何问题,请随时与我们联系:",
+ "fill_required_fields": "请填写必填字段。",
+ "deleting_message": "删除所有内容,请稍等...",
+ "delete_warning": "这将永久删除您拥有的所有链接、收藏夹、标签和存档数据。它还将注销您的账户。此操作不可逆!",
+ "optional": "可选",
+ "feedback_help": "(但它确实能帮助我们改善!)",
+ "reason_for_cancellation": "取消原因",
+ "please_specify": "请指定",
+ "customer_service": "客户服务",
+ "low_quality": "低质量",
+ "missing_features": "缺失功能",
+ "switched_service": "选择服务",
+ "too_complex": "太复杂",
+ "too_expensive": "太昂贵",
+ "unused": "从未使用",
+ "other": "其它",
+ "more_information": "更多信息(越详细,越有帮助)",
+ "feedback_placeholder": "例如,我需要一个功能...",
+ "delete_your_account": "删除账户",
+ "change_password": "修改密码",
+ "password_length_error": "密码需至少 8 个字符。",
+ "applying_changes": "正在申请...",
+ "password_change_instructions": "要更改您的密码,请填写以下内容。您的密码至少应为 8 个字符。",
+ "old_password": "旧密码",
+ "new_password": "新密码",
+ "preference": "首选项",
+ "select_theme": "选择主题",
+ "dark": "Dark",
+ "light": "Light",
+ "archive_settings": "存档设置",
+ "formats_to_archive": "存档/保存网页格式:",
+ "screenshot": "截图",
+ "pdf": "PDF",
+ "archive_org_snapshot": "Archive.org 快照",
+ "link_settings": "链接设置",
+ "prevent_duplicate_links": "防止重复链接",
+ "clicking_on_links_should": "点击链接:",
+ "open_original_content": "打开原始内容",
+ "open_pdf_if_available": "打开PDF,如果有的话",
+ "open_readable_if_available": "打开可读视图(如果可用)",
+ "open_screenshot_if_available": "打开屏幕截图,如果有的话",
+ "open_webpage_if_available": "打开网页副本,如果有的话",
+ "tag_renamed": "标签已重命名!",
+ "tag_deleted": "标签已删除!",
+ "rename_tag": "重命名标签",
+ "delete_tag": "删除标签",
+ "list_created_with_linkwarden": "使用 Linkwarden 创建的列表",
+ "by_author": "作者 {{author}}",
+ "by_author_and_other": "作者:{{author}} 和 {{count}} 其他人",
+ "by_author_and_others": "作者: {{author}} 和 {{count}} 其他人",
+ "search_count_link": "搜索 {{count}} 个链接",
+ "search_count_links": "搜索 {{count}} 个链接",
+ "collection_is_empty": "此收藏夹为空",
+ "all_links": "全部链接",
+ "all_links_desc": "所有收藏夹的链接",
+ "you_have_not_added_any_links": "你还没有创建任何链接",
+ "collections_you_own": "你的收藏夹",
+ "new_collection": "新收藏夹",
+ "other_collections": "其它收藏夹",
+ "other_collections_desc": "您所属的共享收藏夹",
+ "showing_count_results": "展示 {{count}} 条结果",
+ "showing_count_result": "展示 {{count}} 条结果",
+ "edit_collection_info": "编辑收藏夹信息",
+ "share_and_collaborate": "共享和协作",
+ "view_team": "查看团队",
+ "team": "团队",
+ "create_subcollection": "创建子收藏夹",
+ "delete_collection": "删除收藏夹",
+ "leave_collection": "离开收藏夹",
+ "email_verified_signing_out": "邮箱已验证。正在退出...",
+ "invalid_token": "无效 token",
+ "sending_password_recovery_link": "发送密码重置链接...",
+ "please_fill_all_fields": "请填写所有字段。",
+ "password_updated": "密码已修改!",
+ "reset_password": "重置密码",
+ "enter_email_for_new_password": "输入您的邮箱,以便我们向您发送创建新密码的链接。",
+ "update_password": "更新密码",
+ "password_successfully_updated": "您的密码已成功更新。",
+ "user_already_member": "用户已存在。",
+ "you_are_already_collection_owner": "您已经是收藏夹的所有者。",
+ "date_newest_first": "日期 (最新)",
+ "date_oldest_first": "日期 (最早)",
+ "name_az": "名字 (A-Z)",
+ "name_za": "名字 (Z-A)",
+ "description_az": "描述 (A-Z)",
+ "description_za": "描述 (Z-A)",
+ "all_rights_reserved": "© {{date}} <0>Linkwarden0> 版权所有",
+ "you_have_no_collections": "你还没有收藏夹...",
+ "you_have_no_tags": "你还没有标签...",
+ "cant_change_collection_you_dont_own": "您无法对不属于您的收藏夹进行更改。",
+ "account": "账户",
+ "billing": "帐单",
+ "linkwarden_version": "Linkwarden {{version}}",
+ "help": "帮助",
+ "github": "GitHub",
+ "twitter": "Twitter",
+ "mastodon": "Mastodon",
+ "link_preservation_in_queue": "链接保存正在处理中...",
+ "check_back_later": "请稍后再查看结果",
+ "there_are_more_formats": "队列中有更多已保存的格式。",
+ "settings": "设置",
+ "switch_to": "切换到 {{theme}}",
+ "logout": "注销",
+ "start_journey": "通过创建一个新的链接开始你的旅程!",
+ "create_new_link": "创建新链接",
+ "new_link": "新链接",
+ "create_new": "新建",
+ "pwa_install_prompt": "安装 Linkwarden 到您的主屏幕,以获得更快的访问和增强的体验。 <0>了解更多0>",
+ "full_content": "完整内容",
+ "slower": "较慢",
+ "new_version_announcement": "查看 <0>Linkwarden {{version}}0> 了解新功能。",
+ "creating": "正在创建...",
+ "upload_file": "上传文件",
+ "file": "文件",
+ "file_types": "PDF,PNG,JPG (不超过 {{size}} MB)",
+ "description": "描述",
+ "auto_generated": "若未提供将自动生成。",
+ "example_link": "例如:示例链接",
+ "hide": "隐藏",
+ "more": "更多",
+ "options": "选项",
+ "description_placeholder": "笔记,想法等等。",
+ "deleting": "正在删除...",
+ "token_revoked": "Token 已撤销。",
+ "revoke_token": "撤销 Token",
+ "revoke_confirmation": "确定要撤销此 Access Token 吗?任何使用此 token 的应用或服务将无法再使用它访问 Linkwarden。",
+ "revoke": "撤销",
+ "sending_request": "正在发送请求...",
+ "link_being_archived": "链接正在归档...",
+ "preserved_formats": "保存格式",
+ "available_formats": "以下格式可用于此链接:",
+ "readable": "可读视图",
+ "preservation_in_queue": "链接保存正在处理中...",
+ "view_latest_snapshot": "在 archive.org 上查看最新快照",
+ "refresh_preserved_formats": "刷新保留格式",
+ "this_deletes_current_preservations": "这将删除当前保存",
+ "create_new_user": "创建新用户",
+ "placeholder_johnny": "Johnny",
+ "placeholder_email": "johnny@example.com",
+ "placeholder_john": "john",
+ "user_created": "用户已创建",
+ "fill_all_fields_error": "请填写所有的字段。",
+ "password_change_note": "<0>注意:0> 请务必通知用户他们需要更改密码。",
+ "create_user": "创建用户",
+ "creating_token": "创建 Token 中...",
+ "token_created": "Token 创建完成",
+ "access_token_created": "Access Token 已创建",
+ "token_creation_notice": "你的新 token 已创建。 请复制并保存在安全的地方。您将无法再看到它。",
+ "copied_to_clipboard": "已复制到剪贴板",
+ "copy_to_clipboard": "复制到剪贴板",
+ "create_access_token": "创建一个 Access Token",
+ "expires_in": "有效期:",
+ "token_name_placeholder": "例如:iOS 快捷方式",
+ "create_token": "创建 Access Token",
+ "7_days": "7 天",
+ "30_days": "30 天",
+ "60_days": "60 天",
+ "90_days": "90 天",
+ "no_expiration": "永久",
+ "creating_link": "正在创建链接...",
+ "link_created": "链接已创建!",
+ "link_name_placeholder": "若留空将自动生成。",
+ "link_url_placeholder": "示例: http://example.com/",
+ "link_description_placeholder": "笔记,想法等等。",
+ "more_options": "更多选项",
+ "hide_options": "隐藏选项",
+ "create_link": "创建链接",
+ "new_sub_collection": "新子收藏夹",
+ "for_collection": "对于 {{name}}",
+ "create_new_collection": "创建新收藏夹",
+ "color": "颜色",
+ "reset": "重置",
+ "collection_name_placeholder": "例如:示例收藏夹",
+ "collection_description_placeholder": "该收藏夹用于...",
+ "create_collection_button": "创建收藏夹",
+ "password_change_warning": "更改邮箱前,请确认密码。",
+ "stripe_update_note": " 更新此字段也会更改 Stripe 上的账单邮箱。",
+ "sso_will_be_removed_warning": "如果您更改电子邮件地址,任何现有的 {{service}} SSO 连接都将被删除。",
+ "old_email": "旧邮箱",
+ "new_email": "新邮箱",
+ "confirm": "确认",
+ "edit_link": "编辑链接",
+ "updating": "正在更新...",
+ "updated": "已更新",
+ "placeholder_example_link": "例如:示例链接",
+ "make_collection_public": "公开收藏夹",
+ "make_collection_public_checkbox": "将其设为公开收藏夹",
+ "make_collection_public_desc": "这将允许任何人查看该收藏夹及其用户。",
+ "sharable_link_guide": "可分享的链接(点击复制)",
+ "copied": "已复制",
+ "members": "成员",
+ "members_username_placeholder": "用户名(不带'@')",
+ "owner": "所有者",
+ "admin": "管理员",
+ "contributor": "Contributor",
+ "viewer": "Viewer",
+ "viewer_desc": "只读访问",
+ "contributor_desc": "可以查看和创建链接",
+ "admin_desc": "完全访问所有链接",
+ "remove_member": "移除成员",
+ "placeholder_example_collection": "例如:示例收藏夹",
+ "placeholder_collection_purpose": "此收藏夹的目的...",
+ "deleting_user": "正在删除用户...",
+ "user_deleted": "用户已删除",
+ "delete_user": "删除用户",
+ "confirm_user_deletion": "确定删除该用户吗?",
+ "irreversible_action_warning": "此操作不可逆!",
+ "delete_confirmation": "删除,我知道我在做什么。",
+ "delete_link": "删除链接",
+ "deleted": "已删除",
+ "link_deletion_confirmation_message": "要删除此链接吗?",
+ "warning": "警告",
+ "irreversible_warning": "此操作不可逆!",
+ "shift_key_tip": "按住 Shift 键并单击“删除”即可在以后绕过此确认。",
+ "deleting_collection": "删除中...",
+ "collection_deleted": "收藏夹已删除。",
+ "confirm_deletion_prompt": "请确认, 在下面的输入框中输入 \"{{name}}\" :",
+ "type_name_placeholder": "在此输入 \"{{name}}\" 。",
+ "deletion_warning": "删除此收藏夹将永久清除其所有内容,并且所有人都将无法访问,包括之前具有访问权限的成员。",
+ "leave_prompt": "单击下面的按钮离开当前收藏夹。",
+ "leave": "离开",
+ "edit_links": "编辑 {{count}} 链接",
+ "move_to_collection": "移至收藏夹",
+ "add_tags": "添加标签",
+ "remove_previous_tags": "删除以前的标签",
+ "delete_links": "删除 {{count}} 个链接",
+ "links_deletion_confirmation_message": "确定要删除 {{count}} 个链接吗?",
+ "warning_irreversible": "警告:此操作不可逆!",
+ "shift_key_instruction": "按住“Shift”键并单击“删除”即可在以后绕过此确认。",
+ "link_selection_error": "您无权编辑或删除此项目。",
+ "no_description": "未提供描述",
+ "applying": "正在申请...",
+ "unpin": "取消置顶",
+ "pin_to_dashboard": "置顶到仪表盘",
+ "show_link_details": "显示链接详细信息",
+ "hide_link_details": "隐藏链接详细信息",
+ "link_pinned": "链接已置顶!",
+ "link_unpinned": "链接已取消置顶!",
+ "webpage": "网页",
+ "server_administration": "后台管理",
+ "all_collections": "全部收藏夹",
+ "dashboard": "仪表盘",
+ "demo_title": "仅限演示",
+ "demo_desc": "这只是 Linkwarden 的演示实例,禁止上传文件。",
+ "demo_desc_2": "如果你想尝试完整版,你可以注册免费试用:",
+ "demo_button": "以演示用户登录"
+}
\ No newline at end of file
diff --git a/public/logo_maskable.png b/public/logo_maskable.png
index 307583a..bfc2c96 100644
Binary files a/public/logo_maskable.png and b/public/logo_maskable.png differ
diff --git a/scripts/migration/v2.6.1/index.js b/scripts/migration/v2.6.1/index.js
new file mode 100644
index 0000000..0c537e0
--- /dev/null
+++ b/scripts/migration/v2.6.1/index.js
@@ -0,0 +1,169 @@
+// Run the script with `node scripts/migration/v2.6.1/index.js`
+// Docker users can run the script with `docker exec -it CONTAINER_ID /bin/bash -c 'node scripts/migration/v2.6.1/index.js'`
+
+// There are two parts to this script:
+
+// Firstly we decided that the "name" field should be the auto-generated field instead of the "description" field, so we need to
+// move the data from the "description" field to the "name" field for links that have an empty name.
+
+// Secondly it looks for every link and checks if the pdf/screenshot exist in the filesystem.
+// If they do, it updates the link with the path in the db.
+// If they don't, it passes.
+
+const { S3 } = require("@aws-sdk/client-s3");
+const { PrismaClient } = require("@prisma/client");
+const { existsSync } = require("fs");
+const util = require("util");
+
+const prisma = new PrismaClient();
+
+const STORAGE_FOLDER = process.env.STORAGE_FOLDER || "data";
+
+const s3Client =
+ process.env.SPACES_ENDPOINT &&
+ process.env.SPACES_REGION &&
+ process.env.SPACES_KEY &&
+ process.env.SPACES_SECRET
+ ? new S3({
+ forcePathStyle: false,
+ endpoint: process.env.SPACES_ENDPOINT,
+ region: process.env.SPACES_REGION,
+ credentials: {
+ accessKeyId: process.env.SPACES_KEY,
+ secretAccessKey: process.env.SPACES_SECRET,
+ },
+ })
+ : undefined;
+
+async function checkFileExistence(path) {
+ if (s3Client) {
+ // One millisecond delay to avoid rate limiting
+ await new Promise((resolve) => setTimeout(resolve, 1));
+
+ const bucketParams = {
+ Bucket: process.env.SPACES_BUCKET_NAME,
+ Key: path,
+ };
+
+ try {
+ const headObjectAsync = util.promisify(
+ s3Client.headObject.bind(s3Client)
+ );
+
+ try {
+ await headObjectAsync(bucketParams);
+ return true;
+ } catch (err) {
+ return false;
+ }
+ } catch (err) {
+ console.log("Error:", err);
+
+ return false;
+ }
+ } else {
+ try {
+ if (existsSync(STORAGE_FOLDER + "/" + path)) {
+ return true;
+ } else return false;
+ } catch (err) {
+ console.log(err);
+ }
+ }
+}
+
+async function main() {
+ console.log("Starting... Please do not interrupt the process.");
+
+ const linksWithoutName = await prisma.link.findMany({
+ where: {
+ name: "",
+ description: {
+ not: "",
+ },
+ },
+ select: {
+ id: true,
+ description: true,
+ },
+ });
+
+ for (const link of linksWithoutName) {
+ await prisma.link.update({
+ where: {
+ id: link.id,
+ },
+ data: {
+ name: link.description,
+ description: "",
+ },
+ });
+ }
+
+ const links = await prisma.link.findMany({
+ select: {
+ id: true,
+ collectionId: true,
+ image: true,
+ pdf: true,
+ readable: true,
+ monolith: true,
+ },
+ orderBy: { id: "asc" },
+ });
+
+ // PDFs
+ for (let link of links) {
+ const path = `archives/${link.collectionId}/${link.id}.pdf`;
+
+ const res = await checkFileExistence(path);
+
+ if (res) {
+ await prisma.link.update({
+ where: { id: link.id },
+ data: { pdf: path },
+ });
+ }
+
+ console.log("Indexing the PDF for link:", link.id);
+ }
+
+ // Screenshots (PNGs)
+ for (let link of links) {
+ const path = `archives/${link.collectionId}/${link.id}.png`;
+
+ const res = await checkFileExistence(path);
+
+ if (res) {
+ await prisma.link.update({
+ where: { id: link.id },
+ data: { image: path },
+ });
+ }
+
+ console.log("Indexing the PNG for link:", link.id);
+ }
+
+ // Screenshots (JPEGs)
+ for (let link of links) {
+ const path = `archives/${link.collectionId}/${link.id}.jpeg`;
+
+ const res = await checkFileExistence(path);
+
+ if (res) {
+ await prisma.link.update({
+ where: { id: link.id },
+ data: { image: path },
+ });
+ }
+
+ console.log("Indexing the JPEG for link:", link.id);
+ }
+
+ await prisma.$disconnect();
+}
+
+main().catch((e) => {
+ console.error(e);
+ process.exit(1);
+});
diff --git a/scripts/worker.ts b/scripts/worker.ts
index 6b646c5..ca7a6ca 100644
--- a/scripts/worker.ts
+++ b/scripts/worker.ts
@@ -38,6 +38,13 @@ async function processBatch() {
{
readable: "pending",
},
+ ///////////////////////
+ {
+ monolith: null,
+ },
+ {
+ monolith: "pending",
+ },
],
},
take: archiveTakeCount,
@@ -75,6 +82,13 @@ async function processBatch() {
{
readable: "pending",
},
+ ///////////////////////
+ {
+ monolith: null,
+ },
+ {
+ monolith: "pending",
+ },
],
},
take: archiveTakeCount,
diff --git a/store/account.ts b/store/account.ts
deleted file mode 100644
index c1da399..0000000
--- a/store/account.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { create } from "zustand";
-import { AccountSettings } from "@/types/global";
-
-type ResponseObject = {
- ok: boolean;
- data: Omit
| object | string;
-};
-
-type AccountStore = {
- account: AccountSettings;
- setAccount: (id: number) => void;
- updateAccount: (user: AccountSettings) => Promise;
-};
-
-const useAccountStore = create()((set) => ({
- account: {} as AccountSettings,
- setAccount: async (id) => {
- const response = await fetch(`/api/v1/users/${id}`);
-
- const data = await response.json();
-
- if (response.ok) set({ account: { ...data.response } });
- },
- updateAccount: async (user) => {
- const response = await fetch(`/api/v1/users/${user.id}`, {
- method: "PUT",
- body: JSON.stringify(user),
- headers: {
- "Content-Type": "application/json",
- },
- });
-
- const data = await response.json();
-
- if (response.ok) set({ account: { ...data.response } });
-
- return { ok: response.ok, data: data.response };
- },
-}));
-
-export default useAccountStore;
diff --git a/store/collections.ts b/store/collections.ts
deleted file mode 100644
index 466b652..0000000
--- a/store/collections.ts
+++ /dev/null
@@ -1,94 +0,0 @@
-import { create } from "zustand";
-import { CollectionIncludingMembersAndLinkCount } from "@/types/global";
-import useTagStore from "./tags";
-
-type ResponseObject = {
- ok: boolean;
- data: object | string;
-};
-
-type CollectionStore = {
- collections: CollectionIncludingMembersAndLinkCount[];
- setCollections: () => void;
- addCollection: (
- body: CollectionIncludingMembersAndLinkCount
- ) => Promise;
- updateCollection: (
- collection: CollectionIncludingMembersAndLinkCount
- ) => Promise;
- removeCollection: (collectionId: number) => Promise;
-};
-
-const useCollectionStore = create()((set) => ({
- collections: [],
- setCollections: async () => {
- const response = await fetch("/api/v1/collections");
-
- const data = await response.json();
-
- if (response.ok) set({ collections: data.response });
- },
- addCollection: async (body) => {
- const response = await fetch("/api/v1/collections", {
- body: JSON.stringify(body),
- headers: {
- "Content-Type": "application/json",
- },
- method: "POST",
- });
-
- const data = await response.json();
-
- if (response.ok)
- set((state) => ({
- collections: [...state.collections, data.response],
- }));
-
- return { ok: response.ok, data: data.response };
- },
- updateCollection: async (collection) => {
- const response = await fetch(`/api/v1/collections/${collection.id}`, {
- body: JSON.stringify(collection),
- headers: {
- "Content-Type": "application/json",
- },
- method: "PUT",
- });
-
- const data = await response.json();
-
- if (response.ok)
- set((state) => ({
- collections: state.collections.map((e) =>
- e.id === data.response.id ? data.response : e
- ),
- }));
-
- return { ok: response.ok, data: data.response };
- },
- removeCollection: async (collectionId) => {
- const response = await fetch(`/api/v1/collections/${collectionId}`, {
- headers: {
- "Content-Type": "application/json",
- },
- method: "DELETE",
- });
-
- const data = await response.json();
-
- if (response.ok) {
- set((state) => ({
- collections: state.collections.filter(
- (collection) =>
- collection.id !== collectionId &&
- collection.parentId !== collectionId
- ),
- }));
- useTagStore.getState().setTags();
- }
-
- return { ok: response.ok, data: data.response };
- },
-}));
-
-export default useCollectionStore;
diff --git a/store/links.ts b/store/links.ts
index 408a3ee..18fbe15 100644
--- a/store/links.ts
+++ b/store/links.ts
@@ -1,7 +1,5 @@
import { create } from "zustand";
import { LinkIncludingShortenedCollectionAndTags } from "@/types/global";
-import useTagStore from "./tags";
-import useCollectionStore from "./collections";
type ResponseObject = {
ok: boolean;
@@ -9,20 +7,8 @@ type ResponseObject = {
};
type LinkStore = {
- links: LinkIncludingShortenedCollectionAndTags[];
selectedLinks: LinkIncludingShortenedCollectionAndTags[];
- setLinks: (
- data: LinkIncludingShortenedCollectionAndTags[],
- isInitialCall: boolean
- ) => void;
setSelectedLinks: (links: LinkIncludingShortenedCollectionAndTags[]) => void;
- addLink: (
- body: LinkIncludingShortenedCollectionAndTags
- ) => Promise;
- getLink: (linkId: number, publicRoute?: boolean) => Promise;
- updateLink: (
- link: LinkIncludingShortenedCollectionAndTags
- ) => Promise;
updateLinks: (
links: LinkIncludingShortenedCollectionAndTags[],
removePreviousTags: boolean,
@@ -31,110 +17,11 @@ type LinkStore = {
"tags" | "collectionId"
>
) => Promise;
- removeLink: (linkId: number) => Promise;
- deleteLinksById: (linkIds: number[]) => Promise;
- resetLinks: () => void;
};
const useLinkStore = create()((set) => ({
- links: [],
selectedLinks: [],
- setLinks: async (data, isInitialCall) => {
- isInitialCall &&
- set(() => ({
- links: [],
- }));
- set((state) => ({
- // Filter duplicate links by id
- links: [...state.links, ...data].reduce(
- (links: LinkIncludingShortenedCollectionAndTags[], item) => {
- if (!links.some((link) => link.id === item.id)) {
- links.push(item);
- }
- return links;
- },
- []
- ),
- }));
- },
setSelectedLinks: (links) => set({ selectedLinks: links }),
- addLink: async (body) => {
- const response = await fetch("/api/v1/links", {
- body: JSON.stringify(body),
- headers: {
- "Content-Type": "application/json",
- },
- method: "POST",
- });
-
- const data = await response.json();
-
- if (response.ok) {
- set((state) => ({
- links: [data.response, ...state.links],
- }));
- useTagStore.getState().setTags();
- useCollectionStore.getState().setCollections();
- }
-
- return { ok: response.ok, data: data.response };
- },
- getLink: async (linkId, publicRoute) => {
- const path = publicRoute
- ? `/api/v1/public/links/${linkId}`
- : `/api/v1/links/${linkId}`;
-
- const response = await fetch(path);
-
- const data = await response.json();
-
- if (response.ok) {
- set((state) => {
- const linkExists = state.links.some(
- (link) => link.id === data.response.id
- );
-
- if (linkExists) {
- return {
- links: state.links.map((e) =>
- e.id === data.response.id ? data.response : e
- ),
- };
- } else {
- return {
- links: [...state.links, data.response],
- };
- }
- });
-
- return data;
- }
-
- return { ok: response.ok, data: data.response };
- },
- updateLink: async (link) => {
- const response = await fetch(`/api/v1/links/${link.id}`, {
- body: JSON.stringify(link),
- headers: {
- "Content-Type": "application/json",
- },
- method: "PUT",
- });
-
- const data = await response.json();
-
- if (response.ok) {
- set((state) => ({
- links: state.links.map((e) =>
- e.id === data.response.id ? data.response : e
- ),
- }));
- useTagStore.getState().setTags();
- useCollectionStore.getState().setCollections();
- }
-
- return { ok: response.ok, data: data.response };
- },
updateLinks: async (links, removePreviousTags, newData) => {
const response = await fetch("/api/v1/links", {
body: JSON.stringify({ links, removePreviousTags, newData }),
@@ -147,71 +34,11 @@ const useLinkStore = create()((set) => ({
const data = await response.json();
if (response.ok) {
- set((state) => ({
- links: state.links.map((e) =>
- links.some((link) => link.id === e.id)
- ? {
- ...e,
- collectionId: newData.collectionId ?? e.collectionId,
- collection: {
- ...e.collection,
- id: newData.collectionId ?? e.collection.id,
- },
- tags: removePreviousTags
- ? [...(newData.tags ?? [])]
- : [...e.tags, ...(newData.tags ?? [])],
- }
- : e
- ),
- }));
- useTagStore.getState().setTags();
- useCollectionStore.getState().setCollections();
+ // Update the selected links with the new data
}
return { ok: response.ok, data: data.response };
},
- removeLink: async (linkId) => {
- const response = await fetch(`/api/v1/links/${linkId}`, {
- headers: {
- "Content-Type": "application/json",
- },
- method: "DELETE",
- });
-
- const data = await response.json();
-
- if (response.ok) {
- set((state) => ({
- links: state.links.filter((e) => e.id !== linkId),
- }));
- useTagStore.getState().setTags();
- useCollectionStore.getState().setCollections();
- }
-
- return { ok: response.ok, data: data.response };
- },
- deleteLinksById: async (linkIds: number[]) => {
- const response = await fetch("/api/v1/links", {
- body: JSON.stringify({ linkIds }),
- headers: {
- "Content-Type": "application/json",
- },
- method: "DELETE",
- });
-
- const data = await response.json();
-
- if (response.ok) {
- set((state) => ({
- links: state.links.filter((e) => !linkIds.includes(e.id as number)),
- }));
- useTagStore.getState().setTags();
- useCollectionStore.getState().setCollections();
- }
-
- return { ok: response.ok, data: data.response };
- },
- resetLinks: () => set({ links: [] }),
}));
export default useLinkStore;
diff --git a/store/localSettings.ts b/store/localSettings.ts
index 6c79d6b..57254d0 100644
--- a/store/localSettings.ts
+++ b/store/localSettings.ts
@@ -1,13 +1,26 @@
+import { Sort } from "@/types/global";
import { create } from "zustand";
type LocalSettings = {
- theme?: string;
- viewMode?: string;
+ theme: string;
+ viewMode: string;
+ show: {
+ link: boolean;
+ name: boolean;
+ description: boolean;
+ image: boolean;
+ tags: boolean;
+ icon: boolean;
+ collection: boolean;
+ date: boolean;
+ };
+ columns: number;
+ sortBy?: Sort;
};
type LocalSettingsStore = {
settings: LocalSettings;
- updateSettings: (settings: LocalSettings) => void;
+ updateSettings: (settings: Partial) => void;
setSettings: () => void;
};
@@ -15,42 +28,93 @@ const useLocalSettingsStore = create((set) => ({
settings: {
theme: "",
viewMode: "",
+ show: {
+ link: true,
+ name: true,
+ description: true,
+ image: true,
+ tags: true,
+ icon: true,
+ collection: true,
+ date: true,
+ },
+ columns: 0,
+ sortBy: Sort.DateNewestFirst,
},
- updateSettings: async (newSettings) => {
- if (
- newSettings.theme &&
- newSettings.theme !== localStorage.getItem("theme")
- ) {
- localStorage.setItem("theme", newSettings.theme);
+ updateSettings: (newSettings) => {
+ const { theme, viewMode, sortBy, show, columns } = newSettings;
- const localTheme = localStorage.getItem("theme") || "";
-
- document.querySelector("html")?.setAttribute("data-theme", localTheme);
+ if (theme !== undefined && theme !== localStorage.getItem("theme")) {
+ localStorage.setItem("theme", theme);
+ document.querySelector("html")?.setAttribute("data-theme", theme);
}
if (
- newSettings.viewMode &&
- newSettings.viewMode !== localStorage.getItem("viewMode")
+ viewMode !== undefined &&
+ viewMode !== localStorage.getItem("viewMode")
) {
- localStorage.setItem("viewMode", newSettings.viewMode);
-
- // const localTheme = localStorage.getItem("viewMode") || "";
+ localStorage.setItem("viewMode", viewMode);
}
- set((state) => ({ settings: { ...state.settings, ...newSettings } }));
- },
- setSettings: async () => {
- if (!localStorage.getItem("theme")) {
- localStorage.setItem("theme", "dark");
+ if (sortBy !== undefined) {
+ localStorage.setItem("sortBy", sortBy.toString());
}
- const localTheme = localStorage.getItem("theme") || "";
+ if (columns !== undefined) {
+ localStorage.setItem("columns", columns.toString());
+ }
+
+ const currentShowString = localStorage.getItem("show");
+ const newShowString = show ? JSON.stringify(show) : currentShowString;
+
+ if (newShowString !== currentShowString) {
+ localStorage.setItem("show", newShowString || "");
+ }
set((state) => ({
- settings: { ...state.settings, theme: localTheme },
+ settings: {
+ ...state.settings,
+ ...newSettings,
+ show: show ? { ...state.settings.show, ...show } : state.settings.show,
+ },
}));
+ },
+ setSettings: () => {
+ const theme = localStorage.getItem("theme") || "dark";
+ localStorage.setItem("theme", theme);
- document.querySelector("html")?.setAttribute("data-theme", localTheme);
+ const viewMode = localStorage.getItem("viewMode") || "card";
+ localStorage.setItem("viewMode", viewMode);
+
+ const columns = parseInt(localStorage.getItem("columns") || "0");
+ localStorage.setItem("columns", columns.toString());
+
+ const storedShow = localStorage.getItem("show");
+ const show = storedShow
+ ? JSON.parse(storedShow)
+ : {
+ link: true,
+ name: true,
+ description: true,
+ image: true,
+ tags: true,
+ icon: true,
+ collection: true,
+ date: true,
+ };
+ localStorage.setItem("show", JSON.stringify(show));
+
+ set({
+ settings: {
+ theme,
+ viewMode,
+ show,
+ columns,
+ sortBy: useLocalSettingsStore.getState().settings.sortBy,
+ },
+ });
+
+ document.querySelector("html")?.setAttribute("data-theme", theme);
},
}));
diff --git a/store/modals.ts b/store/modals.ts
deleted file mode 100644
index f709d70..0000000
--- a/store/modals.ts
+++ /dev/null
@@ -1,64 +0,0 @@
-import {
- CollectionIncludingMembersAndLinkCount,
- LinkIncludingShortenedCollectionAndTags,
-} from "@/types/global";
-import { create } from "zustand";
-
-type Modal =
- | {
- modal: "LINK";
- state: boolean;
- method: "CREATE";
- active?: LinkIncludingShortenedCollectionAndTags;
- }
- | {
- modal: "LINK";
- state: boolean;
- method: "UPDATE";
- active: LinkIncludingShortenedCollectionAndTags;
- }
- | {
- modal: "LINK";
- state: boolean;
- method: "FORMATS";
- active: LinkIncludingShortenedCollectionAndTags;
- }
- | {
- modal: "COLLECTION";
- state: boolean;
- method: "UPDATE";
- isOwner: boolean;
- active: CollectionIncludingMembersAndLinkCount;
- defaultIndex?: number;
- }
- | {
- modal: "COLLECTION";
- state: boolean;
- method: "CREATE";
- isOwner?: boolean;
- active?: CollectionIncludingMembersAndLinkCount;
- defaultIndex?: number;
- }
- | {
- modal: "COLLECTION";
- state: boolean;
- method: "VIEW_TEAM";
- isOwner?: boolean;
- active?: CollectionIncludingMembersAndLinkCount;
- defaultIndex?: number;
- }
- | null;
-
-type ModalsStore = {
- modal: Modal;
- setModal: (modal: Modal) => void;
-};
-
-const useModalStore = create((set) => ({
- modal: null,
- setModal: (modal: Modal) => {
- set({ modal });
- },
-}));
-
-export default useModalStore;
diff --git a/store/tags.ts b/store/tags.ts
deleted file mode 100644
index f8a0337..0000000
--- a/store/tags.ts
+++ /dev/null
@@ -1,66 +0,0 @@
-import { create } from "zustand";
-import { TagIncludingLinkCount } from "@/types/global";
-
-type ResponseObject = {
- ok: boolean;
- data: object | string;
-};
-
-type TagStore = {
- tags: TagIncludingLinkCount[];
- setTags: (collectionId?: number) => void;
- updateTag: (tag: TagIncludingLinkCount) => Promise;
- removeTag: (tagId: number) => Promise;
-};
-
-const useTagStore = create()((set) => ({
- tags: [],
- setTags: async (collectionId?: number) => {
- let path = "/api/v1/tags";
- if (collectionId) {
- path = "/api/v1/public/collections/tags?collectionId=" + encodeURIComponent(collectionId);
- }
- const response = await fetch(path);
-
- const data = await response.json();
-
- if (response.ok) set({ tags: data.response });
- },
- updateTag: async (tag) => {
- const response = await fetch(`/api/v1/tags/${tag.id}`, {
- body: JSON.stringify(tag),
- headers: {
- "Content-Type": "application/json",
- },
- method: "PUT",
- });
-
- const data = await response.json();
-
- if (response.ok) {
- set((state) => ({
- tags: state.tags.map((e) =>
- e.id === data.response.id ? data.response : e
- ),
- }));
- }
-
- return { ok: response.ok, data: data.response };
- },
- removeTag: async (tagId) => {
- const response = await fetch(`/api/v1/tags/${tagId}`, {
- method: "DELETE",
- });
-
- if (response.ok) {
- set((state) => ({
- tags: state.tags.filter((e) => e.id !== tagId),
- }));
- }
-
- const data = await response.json();
- return { ok: response.ok, data: data.response };
- },
-}));
-
-export default useTagStore;
diff --git a/store/tokens.ts b/store/tokens.ts
deleted file mode 100644
index eff1100..0000000
--- a/store/tokens.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { AccessToken } from "@prisma/client";
-import { create } from "zustand";
-
-// Token store
-
-type ResponseObject = {
- ok: boolean;
- data: object | string;
-};
-
-type TokenStore = {
- tokens: Partial[];
- setTokens: (data: Partial[]) => void;
- addToken: (body: Partial[]) => Promise;
- revokeToken: (tokenId: number) => Promise;
-};
-
-const useTokenStore = create((set) => ({
- tokens: [],
- setTokens: async (data) => {
- set(() => ({
- tokens: data,
- }));
- },
- addToken: async (body) => {
- const response = await fetch("/api/v1/tokens", {
- body: JSON.stringify(body),
- method: "POST",
- });
-
- const data = await response.json();
-
- if (response.ok)
- set((state) => ({
- tokens: [...state.tokens, data.response.token],
- }));
-
- return { ok: response.ok, data: data.response };
- },
- revokeToken: async (tokenId) => {
- const response = await fetch(`/api/v1/tokens/${tokenId}`, {
- method: "DELETE",
- });
-
- const data = await response.json();
-
- if (response.ok)
- set((state) => ({
- tokens: state.tokens.filter((token) => token.id !== tokenId),
- }));
-
- return { ok: response.ok, data: data.response };
- },
-}));
-
-export default useTokenStore;
diff --git a/styles/globals.css b/styles/globals.css
index 256106b..de596a4 100644
--- a/styles/globals.css
+++ b/styles/globals.css
@@ -36,6 +36,14 @@
scrollbar-width: none;
}
+.hide-color-picker {
+ opacity: 0;
+ display: block;
+ width: 32px;
+ height: 32px;
+ border: none;
+}
+
.hyphens {
hyphens: auto;
}
@@ -136,15 +144,16 @@
/* For react-colorful */
.color-picker .react-colorful {
- width: 100%;
- height: 7.5rem;
+ height: 7rem;
+ width: 7rem;
}
.color-picker .react-colorful__hue {
height: 1rem;
}
.color-picker .react-colorful__pointer {
- width: 1.3rem;
- height: 1.3rem;
+ width: 1rem;
+ height: 1rem;
+ border-width: 1px;
}
/* For the Link banner */
@@ -153,6 +162,19 @@
height: fit-content;
}
+.react-select__indicator-separator {
+ display: none;
+}
+
+.react-select__control--is-focused .react-select__dropdown-indicator,
+.react-select__control .react-select__dropdown-indicator,
+.react-select__control .react-select__dropdown-indicator:hover,
+.react-select__control .react-select__dropdown-indicator:focus,
+.react-select__control--is-focused .react-select__dropdown-indicator:hover,
+.react-select__control--is-focused .react-select__dropdown-indicator:focus {
+ color: oklch(var(--n));
+}
+
/* Theme */
@layer components {
@@ -160,13 +182,13 @@
@apply bg-base-200 hover:border-neutral-content;
}
+ .react-select-container .react-select__control--is-focused {
+ @apply border-primary hover:border-primary;
+ }
+
.react-select-container .react-select__menu {
@apply bg-base-100 border-neutral-content border rounded-md;
}
- /*
- .react-select-container .react-select__menu-list {
- @apply h-20;
- } */
.react-select-container .react-select__input-container,
.react-select-container .react-select__single-value {
@@ -255,32 +277,6 @@
border-radius: 8px;
}
-.rainbow {
- background: linear-gradient(
- 45deg,
- #ff00004b,
- #ff99004b,
- #33cc334b,
- #0099cc4b,
- #9900cc4b,
- #ff33cc4b
- );
- background-size: 400% 400%;
- animation: rainbow 30s linear infinite;
-}
-
-@keyframes rainbow {
- 0% {
- background-position: 0% 50%;
- }
- 50% {
- background-position: 100% 50%;
- }
- 100% {
- background-position: 0% 50%;
- }
-}
-
.custom-file-input::file-selector-button {
cursor: pointer;
}
diff --git a/templates/passwordReset.html b/templates/passwordReset.html
new file mode 100644
index 0000000..d3b6f5e
--- /dev/null
+++ b/templates/passwordReset.html
@@ -0,0 +1,388 @@
+
+
+
+
+
+ Email
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Reset your password?
+
+
+
+ Hi {{user}}!
+
+
+
+ Someone has requested a link to change your password.
+
+
+
+
+
+ If you didn't request this, you can safely ignore this email
+ and your password will not be changed.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/verifyEmail.html b/templates/verifyEmail.html
new file mode 100644
index 0000000..14e62ea
--- /dev/null
+++ b/templates/verifyEmail.html
@@ -0,0 +1,413 @@
+
+
+
+
+
+ Email
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Verify your email address
+
+
+
+ Thank you for signing up with Linkwarden! 🥳
+
+
+
+ Just one small step left. Simply verify your email address,
+ and you’re all set!
+
+
+
+
+
+
+
+ If you’re having trouble clicking the button, click on the
+ following link:
+
+
+
+ {{url}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/templates/verifyEmailChange.html b/templates/verifyEmailChange.html
new file mode 100644
index 0000000..284b837
--- /dev/null
+++ b/templates/verifyEmailChange.html
@@ -0,0 +1,424 @@
+
+
+
+
+
+ Email
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Verify your new Linkwarden email address
+
+
+ Hi {{user}}!
+
+
+ You recently requested to change the email address
+ associated with your
+ Linkwarden account. To verify your
+ new email address, please click the button below.
+
+
+ Old Email:
+
+
+
+ {{oldEmail}}
+
+
+
+ New Email:
+
+
+
+ {{newEmail}}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/types/enviornment.d.ts b/types/enviornment.d.ts
deleted file mode 100644
index b737915..0000000
--- a/types/enviornment.d.ts
+++ /dev/null
@@ -1,414 +0,0 @@
-declare global {
- namespace NodeJS {
- interface ProcessEnv {
- NEXTAUTH_SECRET: string;
- DATABASE_URL: string;
- NEXTAUTH_URL: string;
- NEXT_PUBLIC_DISABLE_REGISTRATION?: string;
- PAGINATION_TAKE_COUNT?: string;
- STORAGE_FOLDER?: string;
- AUTOSCROLL_TIMEOUT?: string;
- RE_ARCHIVE_LIMIT?: string;
- NEXT_PUBLIC_MAX_FILE_SIZE?: string;
- MAX_LINKS_PER_USER?: string;
- ARCHIVE_TAKE_COUNT?: string;
- IGNORE_UNAUTHORIZED_CA?: string;
- IGNORE_URL_SIZE_LIMIT?: string;
-
- SPACES_KEY?: string;
- SPACES_SECRET?: string;
- SPACES_ENDPOINT?: string;
- SPACES_BUCKET_NAME?: string;
- SPACES_REGION?: string;
- SPACES_FORCE_PATH_STYLE?: string;
-
- NEXT_PUBLIC_CREDENTIALS_ENABLED?: string;
- DISABLE_NEW_SSO_USERS?: string;
-
- NEXT_PUBLIC_EMAIL_PROVIDER?: string;
- EMAIL_FROM?: string;
- EMAIL_SERVER?: string;
-
- NEXT_PUBLIC_STRIPE?: string;
- STRIPE_SECRET_KEY?: string;
- MONTHLY_PRICE_ID?: string;
- YEARLY_PRICE_ID?: string;
- NEXT_PUBLIC_STRIPE_BILLING_PORTAL_URL?: string;
- NEXT_PUBLIC_TRIAL_PERIOD_DAYS?: string;
- BASE_URL?: string;
-
- // Proxy settings
- PROXY?: string;
- PROXY_USERNAME?: string;
- PROXY_PASSWORD?: string;
- PROXY_BYPASS?: string;
-
- // PDF archive settings
- PDF_MARGIN_TOP?: string;
- PDF_MARGIN_BOTTOM?: string;
-
- //
- // SSO Providers
- //
-
- // 42 School
- NEXT_PUBLIC_FORTYTWO_ENABLED?: string;
- FORTYTWO_CUSTOM_NAME?: string;
- FORTYTWO_CLIENT_ID?: string;
- FORTYTWO_CLIENT_SECRET?: string;
-
- // Apple
- NEXT_PUBLIC_APPLE_ENABLED?: string;
- APPLE_CUSTOM_NAME?: string;
- APPLE_ID?: string;
- APPLE_SECRET?: string;
-
- // Atlassian
- NEXT_PUBLIC_ATLASSIAN_ENABLED?: string;
- ATLASSIAN_CUSTOM_NAME?: string;
- ATLASSIAN_CLIENT_ID?: string;
- ATLASSIAN_CLIENT_SECRET?: string;
- ATLASSIAN_SCOPE?: string;
-
- // Auth0
- NEXT_PUBLIC_AUTH0_ENABLED?: string;
- AUTH0_CUSTOM_NAME?: string;
- AUTH0_ISSUER?: string;
- AUTH0_CLIENT_SECRET?: string;
- AUTH0_CLIENT_ID?: string;
-
- // Authentik
- NEXT_PUBLIC_AUTHENTIK_ENABLED?: string;
- AUTHENTIK_CUSTOM_NAME?: string;
- AUTHENTIK_ISSUER?: string;
- AUTHENTIK_CLIENT_ID?: string;
- AUTHENTIK_CLIENT_SECRET?: string;
-
- // TODO: Azure AD B2C
- // TODO: Azure AD
-
- // Battle.net
- NEXT_PUBLIC_BATTLENET_ENABLED?: string;
- BATTLENET_CUSTOM_NAME?: string;
- BATTLENET_CLIENT_ID?: string;
- BATTLENET_CLIENT_SECRET?: string;
- BATLLENET_ISSUER?: string;
-
- // Box
- NEXT_PUBLIC_BOX_ENABLED?: string;
- BOX_CUSTOM_NAME?: string;
- BOX_CLIENT_ID?: string;
- BOX_CLIENT_SECRET?: string;
-
- // TODO: BoxyHQ SAML
-
- // Bungie
- NEXT_PUBLIC_BUNGIE_ENABLED?: string;
- BUNGIE_CUSTOM_NAME?: string;
- BUNGIE_CLIENT_ID?: string;
- BUNGIE_CLIENT_SECRET?: string;
- BUNGIE_API_KEY?: string;
-
- // Cognito
- NEXT_PUBLIC_COGNITO_ENABLED?: string;
- COGNITO_CUSTOM_NAME?: string;
- COGNITO_CLIENT_ID?: string;
- COGNITO_CLIENT_SECRET?: string;
- COGNITO_ISSUER?: string;
-
- // Coinbase
- NEXT_PUBLIC_COINBASE_ENABLED?: string;
- COINBASE_CUSTOM_NAME?: string;
- COINBASE_CLIENT_ID?: string;
- COINBASE_CLIENT_SECRET?: string;
-
- // Discord
- NEXT_PUBLIC_DISCORD_ENABLED?: string;
- DISCORD_CUSTOM_NAME?: string;
- DISCORD_CLIENT_ID?: string;
- DISCORD_CLIENT_SECRET?: string;
-
- // Dropbox
- NEXT_PUBLIC_DROPBOX_ENABLED?: string;
- DROPBOX_CUSTOM_NAME?: string;
- DROPBOX_CLIENT_ID?: string;
- DROPBOX_CLIENT_SECRET?: string;
-
- // DuendeIndentityServer6
- NEXT_PUBLIC_DUENDE_IDS6_ENABLED?: string;
- DUENDE_IDS6_CUSTOM_NAME?: string;
- DUENDE_IDS6_CLIENT_ID?: string;
- DUENDE_IDS6_CLIENT_SECRET?: string;
- DUENDE_IDS6_ISSUER?: string;
-
- // EVE Online
- NEXT_PUBLIC_EVEONLINE_ENABLED?: string;
- EVEONLINE_CUSTOM_NAME?: string;
- EVEONLINE_CLIENT_ID?: string;
- EVEONLINE_CLIENT_SECRET?: string;
-
- // Facebook
- NEXT_PUBLIC_FACEBOOK_ENABLED?: string;
- FACEBOOK_CUSTOM_NAME?: string;
- FACEBOOK_CLIENT_ID?: string;
- FACEBOOK_CLIENT_SECRET?: string;
-
- // FACEIT
- NEXT_PUBLIC_FACEIT_ENABLED?: string;
- FACEIT_CUSTOM_NAME?: string;
- FACEIT_CLIENT_ID?: string;
- FACEIT_CLIENT_SECRET?: string;
-
- // Foursquare
- NEXT_PUBLIC_FOURSQUARE_ENABLED?: string;
- FOURSQUARE_CUSTOM_NAME?: string;
- FOURSQUARE_CLIENT_ID?: string;
- FOURSQUARE_CLIENT_SECRET?: string;
- FOURSQUARE_APIVERSION?: string;
-
- // Freshbooks
- NEXT_PUBLIC_FRESHBOOKS_ENABLED?: string;
- FRESHBOOKS_CUSTOM_NAME?: string;
- FRESHBOOKS_CLIENT_ID?: string;
- FRESHBOOKS_CLIENT_SECRET?: string;
-
- // FusionAuth
- NEXT_PUBLIC_FUSIONAUTH_ENABLED?: string;
- FUSIONAUTH_CUSTOM_NAME?: string;
- FUSIONAUTH_CLIENT_ID?: string;
- FUSIONAUTH_CLIENT_SECRET?: string;
- FUSIONAUTH_ISSUER?: string;
- FUSIONAUTH_TENANT_ID?: string;
-
- // GitHub
- NEXT_PUBLIC_GITHUB_ENABLED?: string;
- GITHUB_CUSTOM_NAME?: string;
- GITHUB_CLIENT_ID?: string;
- GITHUB_CLIENT_SECRET?: string;
-
- // GitLab
- NEXT_PUBLIC_GITLAB_ENABLED?: string;
- GITLAB_CUSTOM_NAME?: string;
- GITLAB_CLIENT_ID?: string;
- GITLAB_CLIENT_SECRET?: string;
-
- // Google
- NEXT_PUBLIC_GOOGLE_ENABLED?: string;
- GOOGLE_CUSTOM_NAME?: string;
- GOOGLE_CLIENT_ID?: string;
- GOOGLE_CLIENT_SECRET?: string;
-
- // HubSpot
- NEXT_PUBLIC_HUBSPOT_ENABLED?: string;
- HUBSPOT_CUSTOM_NAME?: string;
- HUBSPOT_CLIENT_ID?: string;
- HUBSPOT_CLIENT_SECRET?: string;
-
- // IdentityServer4
- NEXT_PUBLIC_IDS4_ENABLED?: string;
- IDS4_CUSTOM_NAME?: string;
- IDS4_CLIENT_ID?: string;
- IDS4_CLIENT_SECRET?: string;
- IDS4_ISSUER?: string;
-
- // TODO: Instagram (Doesn't return email)
-
- // Kakao
- NEXT_PUBLIC_KAKAO_ENABLED?: string;
- KAKAO_CUSTOM_NAME?: string;
- KAKAO_CLIENT_ID?: string;
- KAKAO_CLIENT_SECRET?: string;
-
- // Keycloak
- NEXT_PUBLIC_KEYCLOAK_ENABLED?: string;
- KEYCLOAK_CUSTOM_NAME?: string;
- KEYCLOAK_ISSUER?: string;
- KEYCLOAK_CLIENT_ID?: string;
- KEYCLOAK_CLIENT_SECRET?: string;
-
- // LINE
- NEXT_PUBLIC_LINE_ENABLED?: string;
- LINE_CUSTOM_NAME?: string;
- LINE_CLIENT_ID?: string;
- LINE_CLIENT_SECRET?: string;
-
- // LinkedIn
- NEXT_PUBLIC_LINKEDIN_ENABLED?: string;
- LINKEDIN_CUSTOM_NAME?: string;
- LINKEDIN_CLIENT_ID?: string;
- LINKEDIN_CLIENT_SECRET?: string;
-
- // Mailchimp
- NEXT_PUBLIC_MAILCHIMP_ENABLED?: string;
- MAILCHIMP_CUSTOM_NAME?: string;
- MAILCHIMP_CLIENT_ID?: string;
- MAILCHIMP_CLIENT_SECRET?: string;
-
- // Mail.ru
- NEXT_PUBLIC_MAILRU_ENABLED?: string;
- MAILRU_CUSTOM_NAME?: string;
- MAILRU_CLIENT_ID?: string;
- MAILRU_CLIENT_SECRET?: string;
-
- // TODO: Medium (Doesn't return email)
-
- // Naver
- NEXT_PUBLIC_NAVER_ENABLED?: string;
- NAVER_CUSTOM_NAME?: string;
- NAVER_CLIENT_ID?: string;
- NAVER_CLIENT_SECRET?: string;
-
- // Netlify
- NEXT_PUBLIC_NETLIFY_ENABLED?: string;
- NETLIFY_CUSTOM_NAME?: string;
- NETLIFY_CLIENT_ID?: string;
- NETLIFY_CLIENT_SECRET?: string;
-
- // Okta
- NEXT_PUBLIC_OKTA_ENABLED?: string;
- OKTA_CUSTOM_NAME?: string;
- OKTA_CLIENT_ID?: string;
- OKTA_CLIENT_SECRET?: string;
- OKTA_ISSUER?: string;
-
- // OneLogin
- NEXT_PUBLIC_ONELOGIN_ENABLED?: string;
- ONELOGIN_CUSTOM_NAME?: string;
- ONELOGIN_CLIENT_ID?: string;
- ONELOGIN_CLIENT_SECRET?: string;
- ONELOGIN_ISSUER?: string;
-
- // Osso
- NEXT_PUBLIC_OSSO_ENABLED?: string;
- OSSO_CUSTOM_NAME?: string;
- OSSO_CLIENT_ID?: string;
- OSSO_CLIENT_SECRET?: string;
- OSSO_ISSUER?: string;
-
- // osu!
- NEXT_PUBLIC_OSU_ENABLED?: string;
- OSU_CUSTOM_NAME?: string;
- OSU_CLIENT_ID?: string;
- OSU_CLIENT_SECRET?: string;
-
- // Patreon
- NEXT_PUBLIC_PATREON_ENABLED?: string;
- PATREON_CUSTOM_NAME?: string;
- PATREON_CLIENT_ID?: string;
- PATREON_CLIENT_SECRET?: string;
-
- // Pinterest
- NEXT_PUBLIC_PINTEREST_ENABLED?: string;
- PINTEREST_CUSTOM_NAME?: string;
- PINTEREST_CLIENT_ID?: string;
- PINTEREST_CLIENT_SECRET?: string;
-
- // Pipedrive
- NEXT_PUBLIC_PIPEDRIVE_ENABLED?: string;
- PIPEDRIVE_CUSTOM_NAME?: string;
- PIPEDRIVE_CLIENT_ID?: string;
- PIPEDRIVE_CLIENT_SECRET?: string;
-
- // Reddit
- // TODO (1h tokens)
- NEXT_PUBLIC_REDDIT_ENABLED?: string;
- REDDIT_CUSTOM_NAME?: string;
- REDDIT_CLIENT_ID?: string;
- REDDIT_CLIENT_SECRET?: string;
-
- // Salesforce
- NEXT_PUBLIC_SALESFORCE_ENABLED?: string;
- SALESFORCE_CUSTOM_NAME?: string;
- SALESFORCE_CLIENT_ID?: string;
- SALESFORCE_CLIENT_SECRET?: string;
-
- // Slack
- NEXT_PUBLIC_SLACK_ENABLED?: string;
- SLACK_CUSTOM_NAME?: string;
- SLACK_CLIENT_ID?: string;
- SLACK_CLIENT_SECRET?: string;
-
- // Spotify
- NEXT_PUBLIC_SPOTIFY_ENABLED?: string;
- SPOTIFY_CUSTOM_NAME?: string;
- SPOTIFY_CLIENT_ID?: string;
- SPOTIFY_CLIENT_SECRET?: string;
-
- // Strava
- NEXT_PUBLIC_STRAVA_ENABLED?: string;
- STRAVA_CUSTOM_NAME?: string;
- STRAVA_CLIENT_ID?: string;
- STRAVA_CLIENT_SECRET?: string;
-
- // Todoist
- NEXT_PUBLIC_TODOIST_ENABLED?: string;
- TODOIST_CUSTOM_NAME?: string;
- TODOIST_CLIENT_ID?: string;
- TODOIST_CLIENT_SECRET?: string;
-
- // TODO: Trakt (Doesn't return email)
-
- // Twitch
- NEXT_PUBLIC_TWITCH_ENABLED?: string;
- TWITCH_CUSTOM_NAME?: string;
- TWITCH_CLIENT_ID?: string;
- TWITCH_CLIENT_SECRET?: string;
-
- // TODO: Twitter (OAuth 1.0)
-
- // United Effects
- NEXT_PUBLIC_UNITED_EFFECTS_ENABLED?: string;
- UNITED_EFFECTS_CUSTOM_NAME?: string;
- UNITED_EFFECTS_CLIENT_ID?: string;
- UNITED_EFFECTS_CLIENT_SECRET?: string;
- UNITED_EFFECTS_ISSUER?: string;
-
- // VK
- NEXT_PUBLIC_VK_ENABLED?: string;
- VK_CUSTOM_NAME?: string;
- VK_CLIENT_ID?: string;
- VK_CLIENT_SECRET?: string;
-
- // Wikimedia
- NEXT_PUBLIC_WIKIMEDIA_ENABLED?: string;
- WIKIMEDIA_CUSTOM_NAME?: string;
- WIKIMEDIA_CLIENT_ID?: string;
- WIKIMEDIA_CLIENT_SECRET?: string;
-
- // Wordpress.com
- NEXT_PUBLIC_WORDPRESS_ENABLED?: string;
- WORDPRESS_CUSTOM_NAME?: string;
- WORDPRESS_CLIENT_ID?: string;
- WORDPRESS_CLIENT_SECRET?: string;
-
- // TODO: WorkOS (Custom flow)
-
- // Yandex
- NEXT_PUBLIC_YANDEX_ENABLED?: string;
- YANDEX_CUSTOM_NAME?: string;
- YANDEX_CLIENT_ID?: string;
- YANDEX_CLIENT_SECRET?: string;
-
- // Zitadel
- NEXT_PUBLIC_ZITADEL_ENABLED?: string;
- ZITADEL_CUSTOM_NAME?: string;
- ZITADEL_CLIENT_ID?: string;
- ZITADEL_CLIENT_SECRET?: string;
- ZITADEL_ISSUER?: string;
-
- // Zoho
- NEXT_PUBLIC_ZOHO_ENABLED?: string;
- ZOHO_CUSTOM_NAME?: string;
- ZOHO_CLIENT_ID?: string;
- ZOHO_CLIENT_SECRET?: string;
-
- // Zoom
- NEXT_PUBLIC_ZOOM_ENABLED?: string;
- ZOOM_CUSTOM_NAME?: string;
- ZOOM_CLIENT_ID?: string;
- ZOOM_CLIENT_SECRET?: string;
- }
- }
-}
-
-export {};
diff --git a/types/global.ts b/types/global.ts
index b347659..2be9f81 100644
--- a/types/global.ts
+++ b/types/global.ts
@@ -22,6 +22,7 @@ export interface LinkIncludingShortenedCollectionAndTags
pinnedBy?: {
id: number;
}[];
+ updatedAt?: string;
collection: OptionalExcluding;
}
@@ -50,6 +51,7 @@ export interface TagIncludingLinkCount extends Tag {
export interface AccountSettings extends User {
newPassword?: string;
+ oldPassword?: string;
whitelistedUsers: string[];
subscription?: {
active?: boolean;
@@ -66,8 +68,8 @@ export interface PublicCollectionIncludingLinks extends Collection {
export enum ViewMode {
Card = "card",
- Grid = "grid",
List = "list",
+ Masonry = "masonry",
}
export enum Sort {
@@ -79,8 +81,10 @@ export enum Sort {
DescriptionZA,
}
+export type Order = { [key: string]: "asc" | "desc" };
+
export type LinkRequestQuery = {
- sort: Sort;
+ sort?: Sort;
cursor?: number;
collectionId?: number;
tagId?: number;
@@ -114,6 +118,7 @@ export type MigrationRequest = {
export enum MigrationFormat {
linkwarden,
htmlFile,
+ wallabag,
}
export enum Plan {
@@ -134,12 +139,14 @@ export enum ArchivedFormat {
jpeg,
pdf,
readability,
+ monolith,
}
export enum LinkType {
url,
pdf,
image,
+ monolith,
}
export enum TokenExpiry {
diff --git a/yarn.lock b/yarn.lock
index 37c6839..d3403a7 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -666,6 +666,20 @@
dependencies:
regenerator-runtime "^0.14.0"
+"@babel/runtime@^7.23.2", "@babel/runtime@^7.23.9":
+ version "7.24.6"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.6.tgz#5b76eb89ad45e2e4a0a8db54c456251469a3358e"
+ integrity sha512-Ja18XcETdEl5mzzACGd+DKgaGJzPTCow7EglgwTmHdwokzDFYh/MHua6lU6DV/hjF2IaOJ4oX2nqnjG7RElKOw==
+ dependencies:
+ regenerator-runtime "^0.14.0"
+
+"@babel/runtime@^7.24.1":
+ version "7.24.5"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.24.5.tgz#230946857c053a36ccc66e1dd03b17dd0c4ed02c"
+ integrity sha512-Nms86NXrsaeU9vbBJKni6gXiEXZ4CVpYVzEjDH9Sb8vmZ3UljyA1GSOJl/6LGPO8EHLuSF9H+IxNXHPX8QHJ4g==
+ dependencies:
+ regenerator-runtime "^0.14.0"
+
"@babel/types@^7.18.6":
version "7.21.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.0.tgz#1da00d89c2f18b226c9207d96edbeb79316a1819"
@@ -1267,6 +1281,16 @@
resolved "https://registry.yarnpkg.com/@panva/hkdf/-/hkdf-1.1.1.tgz#ab9cd8755d1976e72fc77a00f7655a64efe6cd5d"
integrity sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==
+"@phosphor-icons/core@^2.1.1":
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/@phosphor-icons/core/-/core-2.1.1.tgz#62a4cfbec9772f1a613a647da214fbb96f3ad39d"
+ integrity sha512-v4ARvrip4qBCImOE5rmPUylOEK4iiED9ZyKjcvzuezqMaiRASCHKcRIuvvxL/twvLpkfnEODCOJp5dM4eZilxQ==
+
+"@phosphor-icons/react@^2.1.7":
+ version "2.1.7"
+ resolved "https://registry.yarnpkg.com/@phosphor-icons/react/-/react-2.1.7.tgz#b11a4b25849b7e3849970b688d9fe91e5d4fd8d7"
+ integrity sha512-g2e2eVAn1XG2a+LI09QU3IORLhnFNAFkNbo2iwbX6NOKSLOwvEMmTa7CgOzEbgNWR47z8i8kwjdvYZ5fkGx1mQ==
+
"@pkgr/utils@^2.3.1":
version "2.3.1"
resolved "https://registry.yarnpkg.com/@pkgr/utils/-/utils-2.3.1.tgz#0a9b06ffddee364d6642b3cd562ca76f55b34a03"
@@ -1279,15 +1303,12 @@
tiny-glob "^0.2.9"
tslib "^2.4.0"
-"@playwright/test@^1.35.1":
- version "1.35.1"
- resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.35.1.tgz#a596b61e15b980716696f149cc7a2002f003580c"
- integrity sha512-b5YoFe6J9exsMYg0pQAobNDR85T1nLumUYgUTtKm4d21iX2L7WqKq9dW8NGJ+2vX0etZd+Y7UeuqsxDXm9+5ZA==
+"@playwright/test@^1.45.0":
+ version "1.45.0"
+ resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.45.0.tgz#790a66165a46466c0d7099dd260881802f5aba7e"
+ integrity sha512-TVYsfMlGAaxeUllNkywbwek67Ncf8FRGn8ZlRdO291OL3NjG9oMbfVhyP82HQF0CZLMrYsvesqoUekxdWuF9Qw==
dependencies:
- "@types/node" "*"
- playwright-core "1.35.1"
- optionalDependencies:
- fsevents "2.3.2"
+ playwright "1.45.0"
"@prisma/client@^4.16.2":
version "4.16.2"
@@ -1301,10 +1322,10 @@
resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-4.16.1-1.4bc8b6e1b66cb932731fb1bdbbc550d1e010de81.tgz#d3b5dcf95b6d220e258cbf6ae19b06d30a7e9f14"
integrity sha512-q617EUWfRIDTriWADZ4YiWRZXCa/WuhNgLTVd+HqWLffjMSPzyM5uOWoauX91wvQClSKZU4pzI4JJLQ9Kl62Qg==
-"@prisma/engines@5.1.0":
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-5.1.0.tgz#4ccf7f344eaeee08ca1e4a1bb2dc14e36ff1d5ec"
- integrity sha512-HqaFsnPmZOdMWkPq6tT2eTVTQyaAXEDdKszcZ4yc7DGMBIYRP6j/zAJTtZUG9SsMV8FaucdL5vRyxY/p5Ni28g==
+"@prisma/engines@4.16.2":
+ version "4.16.2"
+ resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-4.16.2.tgz#5ec8dd672c2173d597e469194916ad4826ce2e5f"
+ integrity sha512-vx1nxVvN4QeT/cepQce68deh/Turxy5Mr+4L4zClFuK1GlxN3+ivxfuv+ej/gvidWn1cE1uAhW7ALLNlYbRUAw==
"@radix-ui/primitive@1.0.1":
version "1.0.1"
@@ -1892,6 +1913,30 @@
dependencies:
tslib "^2.4.0"
+"@tanstack/query-core@5.51.15":
+ version "5.51.15"
+ resolved "https://registry.yarnpkg.com/@tanstack/query-core/-/query-core-5.51.15.tgz#7aee6a2d5d3f64de3e54096607233b1132dc6afd"
+ integrity sha512-xyobHDJ0yhPE3+UkSQ2/4X1fLSg7ICJI5J1JyU9yf7F3deQfEwSImCDrB1WSRrauJkMtXW7YIEcC0oA6ZZWt5A==
+
+"@tanstack/query-devtools@5.51.15":
+ version "5.51.15"
+ resolved "https://registry.yarnpkg.com/@tanstack/query-devtools/-/query-devtools-5.51.15.tgz#81c5c28231adc4b95fe4a5e1004020fdca5ea447"
+ integrity sha512-1oSCl+PsCa/aBCGVM2ZdcQLuQ0QYmKXJJB264twEMVM1M0n5CI40trtywORPF+wLGuZNIZzkKL7j/98mOLAIag==
+
+"@tanstack/react-query-devtools@^5.51.15":
+ version "5.51.15"
+ resolved "https://registry.yarnpkg.com/@tanstack/react-query-devtools/-/react-query-devtools-5.51.15.tgz#5c4d21305fd25c35dc88bd280304f77a45554fc2"
+ integrity sha512-bvGvJoncjZ3irEofoFevptj5BPkDpQrp2+dZhtFqPUZXRT6MAKPmOqtSmZPfacLR5jQLpqw/7d3Zxr173z7WDA==
+ dependencies:
+ "@tanstack/query-devtools" "5.51.15"
+
+"@tanstack/react-query@^5.51.15":
+ version "5.51.15"
+ resolved "https://registry.yarnpkg.com/@tanstack/react-query/-/react-query-5.51.15.tgz#059bb2966f828263adb355de81410d107e22b5bc"
+ integrity sha512-UgFg23SrdIYrmfTSxAUn9g+J64VQy11pb9/EefoY/u2+zWuNMeqEOnvpJhf52XQy0yztQoyM9p6x8PFyTNaxXg==
+ dependencies:
+ "@tanstack/query-core" "5.51.15"
+
"@tokenizer/token@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276"
@@ -1956,7 +2001,7 @@
"@types/minimatch" "*"
"@types/node" "*"
-"@types/hoist-non-react-statics@^3.3.0":
+"@types/hoist-non-react-statics@^3.3.0", "@types/hoist-non-react-statics@^3.3.4":
version "3.3.5"
resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz#dab7867ef789d87e2b4b0003c9d65c49cc44a494"
integrity sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==
@@ -2554,6 +2599,13 @@ chownr@^2.0.0:
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
+class-variance-authority@^0.7.0:
+ version "0.7.0"
+ resolved "https://registry.yarnpkg.com/class-variance-authority/-/class-variance-authority-0.7.0.tgz#1c3134d634d80271b1837452b06d821915954522"
+ integrity sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==
+ dependencies:
+ clsx "2.0.0"
+
client-only@0.0.1, client-only@^0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
@@ -2568,6 +2620,16 @@ cliui@^8.0.1:
strip-ansi "^6.0.1"
wrap-ansi "^7.0.0"
+clsx@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b"
+ integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==
+
+clsx@^2.1.1:
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.1.1.tgz#eed397c9fd8bd882bfb18deab7102049a2f32999"
+ integrity sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==
+
color-convert@^1.9.0:
version "1.9.3"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
@@ -2662,6 +2724,11 @@ core-js@^2.6.12:
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
+core-js@^3:
+ version "3.37.1"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.37.1.tgz#d21751ddb756518ac5a00e4d66499df981a62db9"
+ integrity sha512-Xn6qmxrQZyB0FFY8E3bgRXei3lWDJHhvI+u0q9TKIYM49G8pAr0FgnnrFRAmsbptZL1yxRADVXn+x5AGsbBfyw==
+
core-util-is@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
@@ -3312,7 +3379,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
-fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9:
+fast-glob@^3.2.11, fast-glob@^3.2.9:
version "3.2.12"
resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80"
integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==
@@ -3323,6 +3390,17 @@ fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9:
merge2 "^1.3.0"
micromatch "^4.0.4"
+fast-glob@^3.3.0:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129"
+ integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==
+ dependencies:
+ "@nodelib/fs.stat" "^2.0.2"
+ "@nodelib/fs.walk" "^1.2.3"
+ glob-parent "^5.1.2"
+ merge2 "^1.3.0"
+ micromatch "^4.0.4"
+
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"
@@ -3496,6 +3574,11 @@ functions-have-names@^1.2.2:
resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834"
integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==
+fuse.js@^7.0.0:
+ version "7.0.0"
+ resolved "https://registry.yarnpkg.com/fuse.js/-/fuse.js-7.0.0.tgz#6573c9fcd4c8268e403b4fc7d7131ffcf99a9eb2"
+ integrity sha512-14F4hBIxqKvD4Zz/XjDc3y94mNZN6pRv3U13Udo0lNLCWRBUsrMv2xwcF/y/Z5sV6+FQW+/ow68cHpm4sunt8Q==
+
gauge@^3.0.0:
version "3.0.2"
resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395"
@@ -3712,6 +3795,18 @@ graphemer@^1.4.0:
resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
+handlebars@^4.7.8:
+ version "4.7.8"
+ resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9"
+ integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==
+ dependencies:
+ minimist "^1.2.5"
+ neo-async "^2.6.2"
+ source-map "^0.6.1"
+ wordwrap "^1.0.0"
+ optionalDependencies:
+ uglify-js "^3.1.4"
+
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
@@ -3800,6 +3895,13 @@ html-encoding-sniffer@^3.0.0:
dependencies:
whatwg-encoding "^2.0.0"
+html-parse-stringify@^3.0.1:
+ version "3.0.1"
+ resolved "https://registry.yarnpkg.com/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz#dfc1017347ce9f77c8141a507f233040c59c55d2"
+ integrity sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==
+ dependencies:
+ void-elements "3.1.0"
+
http-errors@1.7.3:
version "1.7.3"
resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06"
@@ -3837,6 +3939,18 @@ https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1:
agent-base "6"
debug "4"
+i18next-fs-backend@^2.3.1:
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/i18next-fs-backend/-/i18next-fs-backend-2.3.1.tgz#0c7d2459ff4a039e2b3228131809fbc0e74ff1a8"
+ integrity sha512-tvfXskmG/9o+TJ5Fxu54sSO5OkY6d+uMn+K6JiUGLJrwxAVfer+8V3nU8jq3ts9Pe5lXJv4b1N7foIjJ8Iy2Gg==
+
+i18next@^23.11.5:
+ version "23.11.5"
+ resolved "https://registry.yarnpkg.com/i18next/-/i18next-23.11.5.tgz#d71eb717a7e65498d87d0594f2664237f9e361ef"
+ integrity sha512-41pvpVbW9rhZPk5xjCX2TPJi2861LEig/YRhUkY+1FQ2IQPS0bKUDYnEqY8XPPbB48h1uIwLnP9iiEfuSl20CA==
+ dependencies:
+ "@babel/runtime" "^7.23.2"
+
iconv-lite@0.4.24:
version "0.4.24"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
@@ -4165,10 +4279,10 @@ jimp@^0.22.10:
"@jimp/types" "^0.22.10"
regenerator-runtime "^0.13.3"
-jiti@^1.18.2:
- version "1.18.2"
- resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.18.2.tgz#80c3ef3d486ebf2450d9335122b32d121f2a83cd"
- integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg==
+jiti@^1.21.0:
+ version "1.21.6"
+ resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268"
+ integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==
jose@^4.11.1, jose@^4.11.4, jose@^4.14.1:
version "4.14.4"
@@ -4441,6 +4555,11 @@ minimist@^1.2.0, minimist@^1.2.6:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18"
integrity sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==
+minimist@^1.2.5:
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
+ integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
+
minipass@^3.0.0:
version "3.3.6"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a"
@@ -4511,6 +4630,11 @@ ndarray@^1.0.13:
iota-array "^1.0.0"
is-buffer "^1.0.2"
+neo-async@^2.6.2:
+ version "2.6.2"
+ resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
+ integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
+
next-auth@^4.22.1:
version "4.22.1"
resolved "https://registry.yarnpkg.com/next-auth/-/next-auth-4.22.1.tgz#1ea5084e38867966dc6492a71c6729c8f5cfa96b"
@@ -4526,6 +4650,17 @@ next-auth@^4.22.1:
preact-render-to-string "^5.1.19"
uuid "^8.3.2"
+next-i18next@^15.3.0:
+ version "15.3.0"
+ resolved "https://registry.yarnpkg.com/next-i18next/-/next-i18next-15.3.0.tgz#b4530c80573854d00f95229af405e1e5beedbf18"
+ integrity sha512-bq7Cc9XJFcmGOCLnyEtHaeJ3+JJNsI/8Pkj9BaHAnhm4sZ9vNNC4ZsaqYnlRZ7VH5ypSo73fEqLK935jLsmCvQ==
+ dependencies:
+ "@babel/runtime" "^7.23.2"
+ "@types/hoist-non-react-statics" "^3.3.4"
+ core-js "^3"
+ hoist-non-react-statics "^3.3.2"
+ i18next-fs-backend "^2.3.1"
+
next@13.4.12:
version "13.4.12"
resolved "https://registry.yarnpkg.com/next/-/next-13.4.12.tgz#809b21ea0aabbe88ced53252c88c4a5bd5af95df"
@@ -4920,17 +5055,19 @@ pixelmatch@^4.0.2:
dependencies:
pngjs "^3.0.0"
-playwright-core@1.35.1:
- version "1.35.1"
- resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.35.1.tgz#52c1e6ffaa6a8c29de1a5bdf8cce0ce290ffb81d"
- integrity sha512-pNXb6CQ7OqmGDRspEjlxE49w+4YtR6a3X6mT1hZXeJHWmsEz7SunmvZeiG/+y1yyMZdHnnn73WKYdtV1er0Xyg==
+playwright-core@1.45.0:
+ version "1.45.0"
+ resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.45.0.tgz#5741a670b7c9060ce06852c0051d84736fb94edc"
+ integrity sha512-lZmHlFQ0VYSpAs43dRq1/nJ9G/6SiTI7VPqidld9TDefL9tX87bTKExWZZUF5PeRyqtXqd8fQi2qmfIedkwsNQ==
-playwright@^1.35.1:
- version "1.35.1"
- resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.35.1.tgz#f991d0c76ae517d4a0023d9428b09d19d5e87128"
- integrity sha512-NbwBeGJLu5m7VGM0+xtlmLAH9VUfWwYOhUi/lSEDyGg46r1CA9RWlvoc5yywxR9AzQb0mOCm7bWtOXV7/w43ZA==
+playwright@1.45.0, playwright@^1.45.0:
+ version "1.45.0"
+ resolved "https://registry.yarnpkg.com/playwright/-/playwright-1.45.0.tgz#400c709c64438690f13705cb9c88ef93089c5c27"
+ integrity sha512-4z3ac3plDfYzGB6r0Q3LF8POPR20Z8D0aXcxbJvmfMgSSq1hkcgvFRXJk9rUq5H/MJ0Ktal869hhOdI/zUTeLA==
dependencies:
- playwright-core "1.35.1"
+ playwright-core "1.45.0"
+ optionalDependencies:
+ fsevents "2.3.2"
pngjs@^3.0.0, pngjs@^3.3.3:
version "3.4.0"
@@ -5038,12 +5175,12 @@ pretty-format@^3.8.0:
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385"
integrity sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==
-prisma@^5.1.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/prisma/-/prisma-5.1.0.tgz#29e316b54844f5694a83017a9781a6d6f7cb99ea"
- integrity sha512-wkXvh+6wxk03G8qwpZMOed4Y3j+EQ+bMTlvbDZHeal6k1E8QuGKzRO7DRXlE1NV0WNgOAas8kwZqcLETQ2+BiQ==
+prisma@^4.16.2:
+ version "4.16.2"
+ resolved "https://registry.yarnpkg.com/prisma/-/prisma-4.16.2.tgz#469e0a0991c6ae5bcde289401726bb012253339e"
+ integrity sha512-SYCsBvDf0/7XSJyf2cHTLjLeTLVXYfqp7pG5eEVafFLeT0u/hLFz/9W196nDRGUOo1JfPatAEb+uEnTQImQC1g==
dependencies:
- "@prisma/engines" "5.1.0"
+ "@prisma/engines" "4.16.2"
process@^0.11.10:
version "0.11.10"
@@ -5150,11 +5287,24 @@ react-hot-toast@^2.4.1:
dependencies:
goober "^2.1.10"
+react-i18next@^14.1.2:
+ version "14.1.2"
+ resolved "https://registry.yarnpkg.com/react-i18next/-/react-i18next-14.1.2.tgz#cd57a755f25a32a5fcc3dbe546cf3cc62b4f3ebd"
+ integrity sha512-FSIcJy6oauJbGEXfhUgVeLzvWBhIBIS+/9c6Lj4niwKZyGaGb4V4vUbATXSlsHJDXXB+ociNxqFNiFuV1gmoqg==
+ dependencies:
+ "@babel/runtime" "^7.23.9"
+ html-parse-stringify "^3.0.1"
+
react-image-file-resizer@^0.4.8:
version "0.4.8"
resolved "https://registry.yarnpkg.com/react-image-file-resizer/-/react-image-file-resizer-0.4.8.tgz#85f4ae4469fd2867d961568af660ef403d7a79af"
integrity sha512-Ue7CfKnSlsfJ//SKzxNMz8avDgDSpWQDOnTKOp/GNRFJv4dO9L5YGHNEnj40peWkXXAK2OK0eRIoXhOYpUzUTQ==
+react-intersection-observer@^9.13.0:
+ version "9.13.0"
+ resolved "https://registry.yarnpkg.com/react-intersection-observer/-/react-intersection-observer-9.13.0.tgz#ee10827954cf6ccc204d027f8400a6ddb8df163a"
+ integrity sha512-y0UvBfjDiXqC8h0EWccyaj4dVBWMxgEx0t5RGNzQsvkfvZwugnKwxpu70StY4ivzYuMajavwUDjH4LJyIki9Lw==
+
react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@@ -5165,6 +5315,11 @@ react-is@^17.0.2:
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
+react-masonry-css@^1.0.16:
+ version "1.0.16"
+ resolved "https://registry.yarnpkg.com/react-masonry-css/-/react-masonry-css-1.0.16.tgz#72b28b4ae3484e250534700860597553a10f1a2c"
+ integrity sha512-KSW0hR2VQmltt/qAa3eXOctQDyOu7+ZBevtKgpNDSzT7k5LA/0XntNa9z9HKCdz3QlxmJHglTZ18e4sX4V8zZQ==
+
react-redux@^7.0.3:
version "7.2.9"
resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-7.2.9.tgz#09488fbb9416a4efe3735b7235055442b042481d"
@@ -5211,10 +5366,10 @@ react-select@^5.7.4:
react-transition-group "^4.3.0"
use-isomorphic-layout-effect "^1.1.2"
-react-spinners@^0.13.8:
- version "0.13.8"
- resolved "https://registry.yarnpkg.com/react-spinners/-/react-spinners-0.13.8.tgz#5262571be0f745d86bbd49a1e6b49f9f9cb19acc"
- integrity sha512-3e+k56lUkPj0vb5NDXPVFAOkPC//XyhKPJjvcGjyMNPWsBKpplfeyialP74G7H7+It7KzhtET+MvGqbKgAqpZA==
+react-spinners@^0.14.1:
+ version "0.14.1"
+ resolved "https://registry.yarnpkg.com/react-spinners/-/react-spinners-0.14.1.tgz#de7d7d6b3e6d4f29d9620c65495b502c7dd90812"
+ integrity sha512-2Izq+qgQ08HTofCVEdcAQCXFEYfqTDdfeDQJeo/HHQiQJD4imOicNLhkfN2eh1NYEWVOX4D9ok2lhuDB0z3Aag==
react-style-singleton@^2.2.1:
version "2.2.1"
@@ -5528,6 +5683,11 @@ source-map@^0.5.7:
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==
+source-map@^0.6.1:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
+ integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
+
spawn-command@0.0.2:
version "0.0.2"
resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2.tgz#9544e1a43ca045f8531aac1a48cb29bdae62338e"
@@ -5720,20 +5880,27 @@ synckit@^0.8.4:
"@pkgr/utils" "^2.3.1"
tslib "^2.5.0"
-tailwindcss@^3.3.3:
- version "3.3.3"
- resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.3.tgz#90da807393a2859189e48e9e7000e6880a736daf"
- integrity sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w==
+tailwind-merge@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/tailwind-merge/-/tailwind-merge-2.3.0.tgz#27d2134fd00a1f77eca22bcaafdd67055917d286"
+ integrity sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==
+ dependencies:
+ "@babel/runtime" "^7.24.1"
+
+tailwindcss@^3.4.10:
+ version "3.4.10"
+ resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.4.10.tgz#70442d9aeb78758d1f911af29af8255ecdb8ffef"
+ integrity sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==
dependencies:
"@alloc/quick-lru" "^5.2.0"
arg "^5.0.2"
chokidar "^3.5.3"
didyoumean "^1.2.2"
dlv "^1.1.3"
- fast-glob "^3.2.12"
+ fast-glob "^3.3.0"
glob-parent "^6.0.2"
is-glob "^4.0.3"
- jiti "^1.18.2"
+ jiti "^1.21.0"
lilconfig "^2.1.0"
micromatch "^4.0.5"
normalize-path "^3.0.0"
@@ -5978,6 +6145,11 @@ typescript@4.9.4:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.4.tgz#a2a3d2756c079abda241d75f149df9d561091e78"
integrity sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==
+uglify-js@^3.1.4:
+ version "3.17.4"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c"
+ integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==
+
unbox-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e"
@@ -6093,10 +6265,10 @@ v8-compile-cache-lib@^3.0.1:
resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf"
integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==
-vaul@^0.8.8:
- version "0.8.8"
- resolved "https://registry.yarnpkg.com/vaul/-/vaul-0.8.8.tgz#c5edc041825fdeaddf0a89e326abcc7ac7449a2d"
- integrity sha512-Z9K2b90M/LtY/sRyM1yfA8Y4mHC/5WIqhO2u7Byr49r5LQXkLGdVXiehsnjtws9CL+DyknwTuRMJXlCOHTqg/g==
+vaul@^0.9.1:
+ version "0.9.1"
+ resolved "https://registry.yarnpkg.com/vaul/-/vaul-0.9.1.tgz#3640198e04636b209b1f907fcf3079bec6ecc66b"
+ integrity sha512-fAhd7i4RNMinx+WEm6pF3nOl78DFkAazcN04ElLPFF9BMCNGbY/kou8UMhIcicm0rJCNePJP0Yyza60gGOD0Jw==
dependencies:
"@radix-ui/react-dialog" "^1.0.4"
@@ -6109,6 +6281,11 @@ verror@1.10.0:
core-util-is "1.0.2"
extsprintf "^1.2.0"
+void-elements@3.1.0:
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-3.1.0.tgz#614f7fbf8d801f0bb5f0661f5b2f5785750e4f09"
+ integrity sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==
+
w3c-xmlserializer@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz#aebdc84920d806222936e3cdce408e32488a3073"
@@ -6214,6 +6391,11 @@ wide-align@^1.1.2:
dependencies:
string-width "^1.0.2 || 2 || 3 || 4"
+wordwrap@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"
+ integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==
+
wrap-ansi@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
@@ -6329,6 +6511,11 @@ zod@3.21.4:
resolved "https://registry.yarnpkg.com/zod/-/zod-3.21.4.tgz#10882231d992519f0a10b5dd58a38c9dabbb64db"
integrity sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==
+zod@^3.23.8:
+ version "3.23.8"
+ resolved "https://registry.yarnpkg.com/zod/-/zod-3.23.8.tgz#e37b957b5d52079769fb8097099b592f0ef4067d"
+ integrity sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==
+
zustand@^4.3.8:
version "4.3.8"
resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.3.8.tgz#37113df8e9e1421b0be1b2dca02b49b76210e7c4"