Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 385416d231 | |||
| 4d04e3e9a1 | |||
| e08ebdec28 | |||
| 86605829c6 | |||
| c398af6c92 | |||
| 973f2a464d | |||
| 02cef5ea92 | |||
| d615c2cea1 | |||
| 446f871536 | |||
| 34bff557e3 | |||
| a0e54e3768 | |||
| d6ec1dc7e6 | |||
| 62e20aa247 | |||
| 0199c82e98 | |||
| 3c07ff358a | |||
| d9c85ff18f | |||
| 6d84fa21c5 | |||
| 5666fd8199 | |||
| abdacf8239 | |||
| 1068153b25 | |||
| 09876aba6d | |||
| 8ceb55dd02 | |||
| b1f3cc50ee | |||
| c72c47f0cd | |||
| 37b75263f8 | |||
| c08840358b | |||
| e99baaa6bb | |||
| a8857f2849 | |||
| df1f9281b4 | |||
| c210b7b092 | |||
| 660d21fe46 | |||
| c7780cb9cb | |||
| 4e265629c3 | |||
| 1c611d6c4f | |||
| ab6af41d33 | |||
| 15dfe0cc7c |
@@ -9,7 +9,7 @@ You will need to import the `Footer` component from the package and wrap your co
|
||||
```jsx live
|
||||
function App() {
|
||||
return (
|
||||
<div style={{ height: "500px" }}>
|
||||
<div style={{ height: "500px"}}>
|
||||
<Excalidraw>
|
||||
<Footer>
|
||||
<button
|
||||
@@ -27,19 +27,19 @@ function App() {
|
||||
|
||||
This will only work for `Desktop` devices.
|
||||
|
||||
For `mobile` you will need to render it inside the [MainMenu](#mainmenu). You can use the [`useEditorInterface`](#useEditorInterface) hook to check the type of device, this will be available only inside the `children` of `Excalidraw` component.
|
||||
For `mobile` you will need to render it inside the [MainMenu](#mainmenu). You can use the [`useDevice`](#useDevice) hook to check the type of device, this will be available only inside the `children` of `Excalidraw` component.
|
||||
|
||||
Open the `Menu` in the below playground and you will see the `custom footer` rendered.
|
||||
|
||||
```jsx live noInline
|
||||
const MobileFooter = ({}) => {
|
||||
const editorInterface = useEditorInterface();
|
||||
if (editorInterface.formFactor === "phone") {
|
||||
const device = useDevice();
|
||||
if (device.editor.isMobile) {
|
||||
return (
|
||||
<Footer>
|
||||
<button
|
||||
className="custom-footer"
|
||||
style={{ marginLeft: "20px", height: "2rem" }}
|
||||
style= {{ marginLeft: '20px', height: '2rem'}}
|
||||
onClick={() => alert("This is custom footer in mobile menu")}
|
||||
>
|
||||
custom footer
|
||||
|
||||
@@ -292,7 +292,7 @@ viewportCoordsToSceneCoords({ clientX: number, clientY: number },<br/> 
|
||||
appState: <a href="https://github.com/excalidraw/excalidraw/blob/master/packages/excalidraw/types.ts#L95">AppState</a><br/>): {x: number, y: number}
|
||||
</pre>
|
||||
|
||||
### useEditorInterface
|
||||
### useDevice
|
||||
|
||||
This hook can be used to check the type of device which is being used. It can only be used inside the `children` of `Excalidraw` component.
|
||||
|
||||
@@ -300,8 +300,8 @@ Open the `main menu` in the below example to view the footer.
|
||||
|
||||
```jsx live noInline
|
||||
const MobileFooter = ({}) => {
|
||||
const editorInterface = useEditorInterface();
|
||||
if (editorInterface.formFactor === "phone") {
|
||||
const device = useDevice();
|
||||
if (device.editor.isMobile) {
|
||||
return (
|
||||
<Footer>
|
||||
<button
|
||||
@@ -336,20 +336,12 @@ render(<App />);
|
||||
The `device` has the following `attributes`, some grouped into `viewport` and `editor` objects, per context.
|
||||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
|
||||
The `EditorInterface` object has the following properties:
|
||||
|
||||
| Name | Type | Description |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `formFactor` | `'phone' | 'tablet' | 'desktop'` | Indicates the device type based on screen size |
|
||||
| `desktopUIMode` | `'compact' | 'full'` | UI mode for desktop form factor |
|
||||
| `userAgent.raw` | `string` | Raw user agent string |
|
||||
| `userAgent.isMobileDevice` | `boolean` | True if device is mobile |
|
||||
| `userAgent.platform` | `'ios' | 'android' | 'other' | 'unknown'` | Device platform |
|
||||
| `isTouchScreen` | `boolean` | True if touch events are detected |
|
||||
| `canFitSidebar` | `boolean` | True if sidebar can fit in the viewport |
|
||||
| `isLandscape` | `boolean` | True if viewport is in landscape mode |
|
||||
| --- | --- | --- |
|
||||
| `viewport.isMobile` | `boolean` | Set to `true` when viewport is in `mobile` breakpoint |
|
||||
| `viewport.isLandscape` | `boolean` | Set to `true` when the viewport is in `landscape` mode |
|
||||
| `editor.canFitSidebar` | `boolean` | Set to `true` if there's enough space to fit the `sidebar` |
|
||||
| `editor.isMobile` | `boolean` | Set to `true` when editor container is in `mobile` breakpoint |
|
||||
| `isTouchScreen` | `boolean` | Set to `true` for `touch` when touch event detected |
|
||||
|
||||
### i18n
|
||||
|
||||
|
||||
@@ -12,10 +12,10 @@ const MobileFooter = ({
|
||||
excalidrawAPI: ExcalidrawImperativeAPI;
|
||||
excalidrawLib: typeof TExcalidraw;
|
||||
}) => {
|
||||
const { useEditorInterface, Footer } = excalidrawLib;
|
||||
const { useDevice, Footer } = excalidrawLib;
|
||||
|
||||
const editorInterface = useEditorInterface();
|
||||
if (editorInterface.formFactor === "phone") {
|
||||
const device = useDevice();
|
||||
if (device.editor.isMobile) {
|
||||
return (
|
||||
<Footer>
|
||||
<CustomFooter
|
||||
|
||||
+3
-18
@@ -4,7 +4,6 @@ import {
|
||||
TTDDialogTrigger,
|
||||
CaptureUpdateAction,
|
||||
reconcileElements,
|
||||
useEditorInterface,
|
||||
} from "@excalidraw/excalidraw";
|
||||
import { trackEvent } from "@excalidraw/excalidraw/analytics";
|
||||
import { getDefaultAppState } from "@excalidraw/excalidraw/appState";
|
||||
@@ -138,9 +137,6 @@ import { ExcalidrawPlusIframeExport } from "./ExcalidrawPlusIframeExport";
|
||||
|
||||
import "./index.scss";
|
||||
|
||||
import { ExcalidrawPlusPromoBanner } from "./components/ExcalidrawPlusPromoBanner";
|
||||
import { AppSidebar } from "./components/AppSidebar";
|
||||
|
||||
import type { CollabAPI } from "./collab/Collab";
|
||||
|
||||
polyfill();
|
||||
@@ -346,8 +342,6 @@ const ExcalidrawWrapper = () => {
|
||||
|
||||
const [langCode, setLangCode] = useAppLangCode();
|
||||
|
||||
const editorInterface = useEditorInterface();
|
||||
|
||||
// initial state
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -669,8 +663,8 @@ const ExcalidrawWrapper = () => {
|
||||
debugRenderer(
|
||||
debugCanvasRef.current,
|
||||
appState,
|
||||
elements,
|
||||
window.devicePixelRatio,
|
||||
() => forceRefresh((prev) => !prev),
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -854,22 +848,14 @@ const ExcalidrawWrapper = () => {
|
||||
if (isMobile || !collabAPI || isCollabDisabled) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="excalidraw-ui-top-right">
|
||||
{excalidrawAPI?.getEditorInterface().formFactor === "desktop" && (
|
||||
<ExcalidrawPlusPromoBanner
|
||||
isSignedIn={isExcalidrawPlusSignedUser}
|
||||
/>
|
||||
)}
|
||||
|
||||
<div className="top-right-ui">
|
||||
{collabError.message && <CollabError collabError={collabError} />}
|
||||
<LiveCollaborationTrigger
|
||||
isCollaborating={isCollaborating}
|
||||
onSelect={() =>
|
||||
setShareDialogState({ isOpen: true, type: "share" })
|
||||
}
|
||||
editorInterface={editorInterface}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
@@ -955,8 +941,6 @@ const ExcalidrawWrapper = () => {
|
||||
}}
|
||||
/>
|
||||
|
||||
<AppSidebar />
|
||||
|
||||
{errorMessage && (
|
||||
<ErrorDialog onClose={() => setErrorMessage("")}>
|
||||
{errorMessage}
|
||||
@@ -1159,6 +1143,7 @@ const ExcalidrawWrapper = () => {
|
||||
ref={debugCanvasRef}
|
||||
/>
|
||||
)}
|
||||
{/* <FreedrawDebugSliders /> */}
|
||||
</Excalidraw>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { isExcalidrawPlusSignedUser } from "../app_constants";
|
||||
|
||||
import { DebugFooter, isVisualDebuggerEnabled } from "./DebugCanvas";
|
||||
import { EncryptedIcon } from "./EncryptedIcon";
|
||||
import { ExcalidrawPlusAppLink } from "./ExcalidrawPlusAppLink";
|
||||
|
||||
export const AppFooter = React.memo(
|
||||
({ onChange }: { onChange: () => void }) => {
|
||||
@@ -18,7 +19,11 @@ export const AppFooter = React.memo(
|
||||
}}
|
||||
>
|
||||
{isVisualDebuggerEnabled() && <DebugFooter onChange={onChange} />}
|
||||
{!isExcalidrawPlusSignedUser && <EncryptedIcon />}
|
||||
{isExcalidrawPlusSignedUser ? (
|
||||
<ExcalidrawPlusAppLink />
|
||||
) : (
|
||||
<EncryptedIcon />
|
||||
)}
|
||||
</div>
|
||||
</Footer>
|
||||
);
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
.excalidraw {
|
||||
.app-sidebar-promo-container {
|
||||
padding: 0.75rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
text-align: center;
|
||||
gap: 1rem;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.app-sidebar-promo-image {
|
||||
margin: 1rem 0;
|
||||
|
||||
height: 16.25rem;
|
||||
background-size: contain;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
|
||||
background-image: radial-gradient(
|
||||
circle,
|
||||
transparent 60%,
|
||||
var(--sidebar-bg-color) 100%
|
||||
),
|
||||
var(--image-source);
|
||||
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.app-sidebar-promo-text {
|
||||
padding: 0 2rem;
|
||||
}
|
||||
|
||||
.link-button {
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
import { DefaultSidebar, Sidebar, THEME } from "@excalidraw/excalidraw";
|
||||
import {
|
||||
messageCircleIcon,
|
||||
presentationIcon,
|
||||
} from "@excalidraw/excalidraw/components/icons";
|
||||
import { LinkButton } from "@excalidraw/excalidraw/components/LinkButton";
|
||||
import { useUIAppState } from "@excalidraw/excalidraw/context/ui-appState";
|
||||
|
||||
import "./AppSidebar.scss";
|
||||
|
||||
export const AppSidebar = () => {
|
||||
const { theme, openSidebar } = useUIAppState();
|
||||
|
||||
return (
|
||||
<DefaultSidebar>
|
||||
<DefaultSidebar.TabTriggers>
|
||||
<Sidebar.TabTrigger
|
||||
tab="comments"
|
||||
style={{ opacity: openSidebar?.tab === "comments" ? 1 : 0.4 }}
|
||||
>
|
||||
{messageCircleIcon}
|
||||
</Sidebar.TabTrigger>
|
||||
<Sidebar.TabTrigger
|
||||
tab="presentation"
|
||||
style={{ opacity: openSidebar?.tab === "presentation" ? 1 : 0.4 }}
|
||||
>
|
||||
{presentationIcon}
|
||||
</Sidebar.TabTrigger>
|
||||
</DefaultSidebar.TabTriggers>
|
||||
<Sidebar.Tab tab="comments">
|
||||
<div className="app-sidebar-promo-container">
|
||||
<div
|
||||
className="app-sidebar-promo-image"
|
||||
style={{
|
||||
["--image-source" as any]: `url(/oss_promo_comments_${
|
||||
theme === THEME.DARK ? "dark" : "light"
|
||||
}.jpg)`,
|
||||
opacity: 0.7,
|
||||
}}
|
||||
/>
|
||||
<div className="app-sidebar-promo-text">
|
||||
Make comments with Excalidraw+
|
||||
</div>
|
||||
<LinkButton
|
||||
href={`${
|
||||
import.meta.env.VITE_APP_PLUS_LP
|
||||
}/plus?utm_source=excalidraw&utm_medium=app&utm_content=comments_promo#excalidraw-redirect`}
|
||||
>
|
||||
Sign up now
|
||||
</LinkButton>
|
||||
</div>
|
||||
</Sidebar.Tab>
|
||||
<Sidebar.Tab tab="presentation" className="px-3">
|
||||
<div className="app-sidebar-promo-container">
|
||||
<div
|
||||
className="app-sidebar-promo-image"
|
||||
style={{
|
||||
["--image-source" as any]: `url(/oss_promo_presentations_${
|
||||
theme === THEME.DARK ? "dark" : "light"
|
||||
}.svg)`,
|
||||
backgroundSize: "60%",
|
||||
opacity: 0.4,
|
||||
}}
|
||||
/>
|
||||
<div className="app-sidebar-promo-text">
|
||||
Create presentations with Excalidraw+
|
||||
</div>
|
||||
<LinkButton
|
||||
href={`${
|
||||
import.meta.env.VITE_APP_PLUS_LP
|
||||
}/plus?utm_source=excalidraw&utm_medium=app&utm_content=presentations_promo#excalidraw-redirect`}
|
||||
>
|
||||
Sign up now
|
||||
</LinkButton>
|
||||
</div>
|
||||
</Sidebar.Tab>
|
||||
</DefaultSidebar>
|
||||
);
|
||||
};
|
||||
@@ -8,35 +8,21 @@ import {
|
||||
getNormalizedCanvasDimensions,
|
||||
} from "@excalidraw/excalidraw/renderer/helpers";
|
||||
import { type AppState } from "@excalidraw/excalidraw/types";
|
||||
import { arrayToMap, throttleRAF } from "@excalidraw/common";
|
||||
import { throttleRAF } from "@excalidraw/common";
|
||||
import { useCallback } from "react";
|
||||
|
||||
import {
|
||||
getGlobalFixedPointForBindableElement,
|
||||
isArrowElement,
|
||||
isBindableElement,
|
||||
isFixedPointBinding,
|
||||
} from "@excalidraw/element";
|
||||
|
||||
import {
|
||||
isLineSegment,
|
||||
type GlobalPoint,
|
||||
type LineSegment,
|
||||
isCurve,
|
||||
} from "@excalidraw/math";
|
||||
import { isCurve } from "@excalidraw/math/curve";
|
||||
|
||||
import React from "react";
|
||||
|
||||
import type { Curve } from "@excalidraw/math";
|
||||
import type { DebugElement } from "@excalidraw/common";
|
||||
import type {
|
||||
ElementsMap,
|
||||
ExcalidrawArrowElement,
|
||||
ExcalidrawBindableElement,
|
||||
FixedPointBinding,
|
||||
OrderedExcalidrawElement,
|
||||
PointBinding,
|
||||
} from "@excalidraw/element/types";
|
||||
|
||||
import type { DebugElement } from "@excalidraw/utils/visualdebug";
|
||||
|
||||
import { STORAGE_KEYS } from "../app_constants";
|
||||
|
||||
@@ -89,180 +75,6 @@ const renderOrigin = (context: CanvasRenderingContext2D, zoom: number) => {
|
||||
context.save();
|
||||
};
|
||||
|
||||
const _renderBinding = (
|
||||
context: CanvasRenderingContext2D,
|
||||
binding: FixedPointBinding | PointBinding,
|
||||
elementsMap: ElementsMap,
|
||||
zoom: number,
|
||||
width: number,
|
||||
height: number,
|
||||
color: string,
|
||||
) => {
|
||||
if (isFixedPointBinding(binding)) {
|
||||
if (!binding.fixedPoint) {
|
||||
console.warn("Binding must have a fixedPoint");
|
||||
return;
|
||||
}
|
||||
|
||||
const bindable = elementsMap.get(
|
||||
binding.elementId,
|
||||
) as ExcalidrawBindableElement;
|
||||
const [x, y] = getGlobalFixedPointForBindableElement(
|
||||
binding.fixedPoint,
|
||||
bindable,
|
||||
elementsMap,
|
||||
);
|
||||
|
||||
context.save();
|
||||
context.strokeStyle = color;
|
||||
context.lineWidth = 1;
|
||||
context.beginPath();
|
||||
context.moveTo(x * zoom, y * zoom);
|
||||
context.bezierCurveTo(
|
||||
x * zoom - width,
|
||||
y * zoom - height,
|
||||
x * zoom - width,
|
||||
y * zoom + height,
|
||||
x * zoom,
|
||||
y * zoom,
|
||||
);
|
||||
context.stroke();
|
||||
context.restore();
|
||||
}
|
||||
};
|
||||
|
||||
const _renderBindableBinding = (
|
||||
binding: FixedPointBinding | PointBinding,
|
||||
context: CanvasRenderingContext2D,
|
||||
elementsMap: ElementsMap,
|
||||
zoom: number,
|
||||
width: number,
|
||||
height: number,
|
||||
color: string,
|
||||
) => {
|
||||
if (isFixedPointBinding(binding)) {
|
||||
const bindable = elementsMap.get(
|
||||
binding.elementId,
|
||||
) as ExcalidrawBindableElement;
|
||||
if (!binding.fixedPoint) {
|
||||
console.warn("Binding must have a fixedPoint");
|
||||
return;
|
||||
}
|
||||
|
||||
const [x, y] = getGlobalFixedPointForBindableElement(
|
||||
binding.fixedPoint,
|
||||
bindable,
|
||||
elementsMap,
|
||||
);
|
||||
|
||||
context.save();
|
||||
context.strokeStyle = color;
|
||||
context.lineWidth = 1;
|
||||
context.beginPath();
|
||||
context.moveTo(x * zoom, y * zoom);
|
||||
context.bezierCurveTo(
|
||||
x * zoom + width,
|
||||
y * zoom + height,
|
||||
x * zoom + width,
|
||||
y * zoom - height,
|
||||
x * zoom,
|
||||
y * zoom,
|
||||
);
|
||||
context.stroke();
|
||||
context.restore();
|
||||
}
|
||||
};
|
||||
|
||||
const renderBindings = (
|
||||
context: CanvasRenderingContext2D,
|
||||
elements: readonly OrderedExcalidrawElement[],
|
||||
zoom: number,
|
||||
) => {
|
||||
const elementsMap = arrayToMap(elements);
|
||||
const dim = 16;
|
||||
elements.forEach((element) => {
|
||||
if (element.isDeleted) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isArrowElement(element)) {
|
||||
if (element.startBinding) {
|
||||
if (
|
||||
!elementsMap
|
||||
.get(element.startBinding.elementId)
|
||||
?.boundElements?.find((e) => e.id === element.id)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
_renderBinding(
|
||||
context,
|
||||
element.startBinding as FixedPointBinding,
|
||||
elementsMap,
|
||||
zoom,
|
||||
dim,
|
||||
dim,
|
||||
"red",
|
||||
);
|
||||
}
|
||||
|
||||
if (element.endBinding) {
|
||||
if (
|
||||
!elementsMap
|
||||
.get(element.endBinding.elementId)
|
||||
?.boundElements?.find((e) => e.id === element.id)
|
||||
) {
|
||||
return;
|
||||
}
|
||||
_renderBinding(
|
||||
context,
|
||||
element.endBinding,
|
||||
elementsMap,
|
||||
zoom,
|
||||
dim,
|
||||
dim,
|
||||
"red",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (isBindableElement(element) && element.boundElements?.length) {
|
||||
element.boundElements.forEach((boundElement) => {
|
||||
if (boundElement.type !== "arrow") {
|
||||
return;
|
||||
}
|
||||
|
||||
const arrow = elementsMap.get(
|
||||
boundElement.id,
|
||||
) as ExcalidrawArrowElement;
|
||||
|
||||
if (arrow && arrow.startBinding?.elementId === element.id) {
|
||||
_renderBindableBinding(
|
||||
arrow.startBinding,
|
||||
context,
|
||||
elementsMap,
|
||||
zoom,
|
||||
dim,
|
||||
dim,
|
||||
"green",
|
||||
);
|
||||
}
|
||||
if (arrow && arrow.endBinding?.elementId === element.id) {
|
||||
_renderBindableBinding(
|
||||
arrow.endBinding,
|
||||
context,
|
||||
elementsMap,
|
||||
zoom,
|
||||
dim,
|
||||
dim,
|
||||
"green",
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const render = (
|
||||
frame: DebugElement[],
|
||||
context: CanvasRenderingContext2D,
|
||||
@@ -295,8 +107,8 @@ const render = (
|
||||
const _debugRenderer = (
|
||||
canvas: HTMLCanvasElement,
|
||||
appState: AppState,
|
||||
elements: readonly OrderedExcalidrawElement[],
|
||||
scale: number,
|
||||
refresh: () => void,
|
||||
) => {
|
||||
const [normalizedWidth, normalizedHeight] = getNormalizedCanvasDimensions(
|
||||
canvas,
|
||||
@@ -319,7 +131,6 @@ const _debugRenderer = (
|
||||
);
|
||||
|
||||
renderOrigin(context, appState.zoom.value);
|
||||
renderBindings(context, elements, appState.zoom.value);
|
||||
|
||||
if (
|
||||
window.visualDebug?.currentFrame &&
|
||||
@@ -371,10 +182,10 @@ export const debugRenderer = throttleRAF(
|
||||
(
|
||||
canvas: HTMLCanvasElement,
|
||||
appState: AppState,
|
||||
elements: readonly OrderedExcalidrawElement[],
|
||||
scale: number,
|
||||
refresh: () => void,
|
||||
) => {
|
||||
_debugRenderer(canvas, appState, elements, scale);
|
||||
_debugRenderer(canvas, appState, scale, refresh);
|
||||
},
|
||||
{ trailing: true },
|
||||
);
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { isExcalidrawPlusSignedUser } from "../app_constants";
|
||||
|
||||
export const ExcalidrawPlusAppLink = () => {
|
||||
if (!isExcalidrawPlusSignedUser) {
|
||||
return null;
|
||||
}
|
||||
return (
|
||||
<a
|
||||
href={`${
|
||||
import.meta.env.VITE_APP_PLUS_APP
|
||||
}?utm_source=excalidraw&utm_medium=app&utm_content=signedInUserRedirectButton#excalidraw-redirect`}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
className="plus-button"
|
||||
>
|
||||
Go to Excalidraw+
|
||||
</a>
|
||||
);
|
||||
};
|
||||
@@ -1,22 +0,0 @@
|
||||
export const ExcalidrawPlusPromoBanner = ({
|
||||
isSignedIn,
|
||||
}: {
|
||||
isSignedIn: boolean;
|
||||
}) => {
|
||||
return (
|
||||
<a
|
||||
href={
|
||||
isSignedIn
|
||||
? import.meta.env.VITE_APP_PLUS_APP
|
||||
: `${
|
||||
import.meta.env.VITE_APP_PLUS_LP
|
||||
}/plus?utm_source=excalidraw&utm_medium=app&utm_content=guestBanner#excalidraw-redirect`
|
||||
}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
className="plus-banner"
|
||||
>
|
||||
Excalidraw+
|
||||
</a>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,150 @@
|
||||
import { STROKE_OPTIONS, isFreeDrawElement } from "@excalidraw/element";
|
||||
import { useState, useEffect } from "react";
|
||||
|
||||
import { useUIAppState } from "@excalidraw/excalidraw/context/ui-appState";
|
||||
import { useExcalidrawElements } from "@excalidraw/excalidraw/components/App";
|
||||
|
||||
import { round } from "../../packages/math/src";
|
||||
|
||||
export const FreedrawDebugSliders = () => {
|
||||
const [streamline, setStreamline] = useState<number>(
|
||||
STROKE_OPTIONS.default.streamline,
|
||||
);
|
||||
const [simplify, setSimplify] = useState<number>(
|
||||
STROKE_OPTIONS.default.simplify,
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
if (!window.h) {
|
||||
window.h = {} as any;
|
||||
}
|
||||
if (!window.h.debugFreedraw) {
|
||||
window.h.debugFreedraw = {
|
||||
enabled: true,
|
||||
...STROKE_OPTIONS.default,
|
||||
};
|
||||
}
|
||||
|
||||
setStreamline(window.h.debugFreedraw.streamline);
|
||||
setSimplify(window.h.debugFreedraw.simplify);
|
||||
}, []);
|
||||
|
||||
const handleStreamlineChange = (value: number) => {
|
||||
setStreamline(value);
|
||||
if (window.h && window.h.debugFreedraw) {
|
||||
window.h.debugFreedraw.streamline = value;
|
||||
}
|
||||
};
|
||||
|
||||
const handleSimplifyChange = (value: number) => {
|
||||
setSimplify(value);
|
||||
if (window.h && window.h.debugFreedraw) {
|
||||
window.h.debugFreedraw.simplify = value;
|
||||
}
|
||||
};
|
||||
|
||||
const [enabled, setEnabled] = useState<boolean>(
|
||||
window.h?.debugFreedraw?.enabled ?? true,
|
||||
);
|
||||
|
||||
// counter incrasing each 50ms
|
||||
const [, setCounter] = useState<number>(0);
|
||||
useEffect(() => {
|
||||
const interval = setInterval(() => {
|
||||
setCounter((prev) => prev + 1);
|
||||
}, 50);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, []);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const elements = useExcalidrawElements();
|
||||
const appState = useUIAppState();
|
||||
|
||||
const newFreedrawElement =
|
||||
appState.newElement && isFreeDrawElement(appState.newElement)
|
||||
? appState.newElement
|
||||
: null;
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: "70px",
|
||||
left: "50%",
|
||||
transform: "translateX(-50%)",
|
||||
zIndex: 9999,
|
||||
padding: "10px",
|
||||
borderRadius: "8px",
|
||||
border: "1px solid #ccc",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "8px",
|
||||
fontSize: "12px",
|
||||
fontFamily: "monospace",
|
||||
}}
|
||||
>
|
||||
{newFreedrawElement && (
|
||||
<div>
|
||||
pressures:{" "}
|
||||
{newFreedrawElement.simulatePressure
|
||||
? "simulated"
|
||||
: JSON.stringify(
|
||||
newFreedrawElement.pressures
|
||||
.slice(-4)
|
||||
.map((x) => round(x, 2))
|
||||
.join(" ") || [],
|
||||
)}{" "}
|
||||
({round(window.__lastPressure__ || 0, 2) || "?"})
|
||||
</div>
|
||||
)}
|
||||
<div>
|
||||
<label>
|
||||
{" "}
|
||||
enabled
|
||||
<br />
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={enabled}
|
||||
onChange={(e) => {
|
||||
if (window.h.debugFreedraw) {
|
||||
window.h.debugFreedraw.enabled = e.target.checked;
|
||||
setEnabled(e.target.checked);
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
Streamline: {streamline.toFixed(2)}
|
||||
<br />
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.01"
|
||||
value={streamline}
|
||||
onChange={(e) => handleStreamlineChange(parseFloat(e.target.value))}
|
||||
style={{ width: "150px" }}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<label>
|
||||
Simplify: {simplify.toFixed(2)}
|
||||
<br />
|
||||
<input
|
||||
type="range"
|
||||
min="0"
|
||||
max="1"
|
||||
step="0.01"
|
||||
value={simplify}
|
||||
onChange={(e) => handleSimplifyChange(parseFloat(e.target.value))}
|
||||
style={{ width: "150px" }}
|
||||
/>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
+11
-16
@@ -1,5 +1,3 @@
|
||||
@import "../packages/excalidraw/css/variables.module.scss";
|
||||
|
||||
.excalidraw {
|
||||
--color-primary-contrast-offset: #625ee0; // to offset Chubb illusion
|
||||
|
||||
@@ -7,6 +5,12 @@
|
||||
--color-primary-contrast-offset: #726dff; // to offset Chubb illusion
|
||||
}
|
||||
|
||||
.top-right-ui {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.footer-center {
|
||||
justify-content: flex-end;
|
||||
margin-top: auto;
|
||||
@@ -86,31 +90,22 @@
|
||||
}
|
||||
}
|
||||
|
||||
.plus-banner {
|
||||
.plus-button {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
border: 1px solid var(--color-primary);
|
||||
padding: 0.5rem 0.875rem;
|
||||
padding: 0.5rem 0.75rem;
|
||||
border-radius: var(--border-radius-lg);
|
||||
background-color: var(--island-bg-color);
|
||||
color: var(--color-primary) !important;
|
||||
text-decoration: none !important;
|
||||
|
||||
font-family: var(--ui-font);
|
||||
font-size: 0.8333rem;
|
||||
font-size: 0.75rem;
|
||||
box-sizing: border-box;
|
||||
height: var(--lg-button-size);
|
||||
|
||||
border: none;
|
||||
box-shadow: 0 0 0 1px var(--color-surface-lowest);
|
||||
background-color: var(--color-surface-low);
|
||||
color: var(--button-color, var(--color-on-surface)) !important;
|
||||
|
||||
&:active {
|
||||
box-shadow: 0 0 0 1px var(--color-brand-active);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-primary);
|
||||
color: white !important;
|
||||
@@ -122,7 +117,7 @@
|
||||
}
|
||||
|
||||
.theme--dark {
|
||||
.plus-banner {
|
||||
.plus-button {
|
||||
&:hover {
|
||||
color: black !important;
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
"node": "18.0.0 - 22.x.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"@excalidraw/random-username": "1.0.0",
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import { defaultLang } from "@excalidraw/excalidraw/i18n";
|
||||
import { UI } from "@excalidraw/excalidraw/tests/helpers/ui";
|
||||
import {
|
||||
screen,
|
||||
fireEvent,
|
||||
waitFor,
|
||||
render,
|
||||
} from "@excalidraw/excalidraw/tests/test-utils";
|
||||
|
||||
import ExcalidrawApp from "../App";
|
||||
|
||||
describe("Test LanguageList", () => {
|
||||
it("rerenders UI on language change", async () => {
|
||||
await render(<ExcalidrawApp />);
|
||||
|
||||
// select rectangle tool to show properties menu
|
||||
UI.clickTool("rectangle");
|
||||
// english lang should display `thin` label
|
||||
expect(screen.queryByTitle(/thin/i)).not.toBeNull();
|
||||
fireEvent.click(document.querySelector(".dropdown-menu-button")!);
|
||||
|
||||
fireEvent.change(document.querySelector(".dropdown-select__language")!, {
|
||||
target: { value: "de-DE" },
|
||||
});
|
||||
// switching to german, `thin` label should no longer exist
|
||||
await waitFor(() => expect(screen.queryByTitle(/thin/i)).toBeNull());
|
||||
// reset language
|
||||
fireEvent.change(document.querySelector(".dropdown-select__language")!, {
|
||||
target: { value: defaultLang.code },
|
||||
});
|
||||
// switching back to English
|
||||
await waitFor(() => expect(screen.queryByTitle(/thin/i)).not.toBeNull());
|
||||
});
|
||||
});
|
||||
@@ -17,15 +17,30 @@ describe("Test MobileMenu", () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
await render(<ExcalidrawApp />);
|
||||
h.app.refreshEditorInterface();
|
||||
// @ts-ignore
|
||||
h.app.refreshViewportBreakpoints();
|
||||
// @ts-ignore
|
||||
h.app.refreshEditorBreakpoints();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
restoreOriginalGetBoundingClientRect();
|
||||
});
|
||||
|
||||
it("should set editor interface correctly", () => {
|
||||
expect(h.app.editorInterface.formFactor).toBe("phone");
|
||||
it("should set device correctly", () => {
|
||||
expect(h.app.device).toMatchInlineSnapshot(`
|
||||
{
|
||||
"editor": {
|
||||
"canFitSidebar": false,
|
||||
"isMobile": true,
|
||||
},
|
||||
"isTouchScreen": false,
|
||||
"viewport": {
|
||||
"isLandscape": true,
|
||||
"isMobile": true,
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
it("should initialize with welcome screen and hide once user interacts", async () => {
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@
|
||||
"vitest-canvas-mock": "0.3.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.0.0"
|
||||
"node": "18.0.0 - 22.x.x"
|
||||
},
|
||||
"homepage": ".",
|
||||
"prettier": "@excalidraw/prettier-config",
|
||||
|
||||
@@ -6,6 +6,32 @@ import type { AppProps, AppState } from "@excalidraw/excalidraw/types";
|
||||
|
||||
import { COLOR_PALETTE } from "./colors";
|
||||
|
||||
export const isDarwin = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
|
||||
export const isWindows = /^Win/.test(navigator.platform);
|
||||
export const isAndroid = /\b(android)\b/i.test(navigator.userAgent);
|
||||
export const isFirefox =
|
||||
typeof window !== "undefined" &&
|
||||
"netscape" in window &&
|
||||
navigator.userAgent.indexOf("rv:") > 1 &&
|
||||
navigator.userAgent.indexOf("Gecko") > 1;
|
||||
export const isChrome = navigator.userAgent.indexOf("Chrome") !== -1;
|
||||
export const isSafari =
|
||||
!isChrome && navigator.userAgent.indexOf("Safari") !== -1;
|
||||
export const isIOS =
|
||||
/iPad|iPhone/i.test(navigator.platform) ||
|
||||
// iPadOS 13+
|
||||
(navigator.userAgent.includes("Mac") && "ontouchend" in document);
|
||||
// keeping function so it can be mocked in test
|
||||
export const isBrave = () =>
|
||||
(navigator as any).brave?.isBrave?.name === "isBrave";
|
||||
|
||||
export const isMobile =
|
||||
isIOS ||
|
||||
/android|webos|ipod|blackberry|iemobile|opera mini/i.test(
|
||||
navigator.userAgent,
|
||||
) ||
|
||||
/android|ios|ipod|blackberry|windows phone/i.test(navigator.platform);
|
||||
|
||||
export const supportsResizeObserver =
|
||||
typeof window !== "undefined" && "ResizeObserver" in window;
|
||||
|
||||
@@ -105,7 +131,6 @@ export const CLASSES = {
|
||||
SEARCH_MENU_INPUT_WRAPPER: "layer-ui__search-inputWrapper",
|
||||
CONVERT_ELEMENT_TYPE_POPUP: "ConvertElementTypePopup",
|
||||
SHAPE_ACTIONS_THEME_SCOPE: "shape-actions-theme-scope",
|
||||
FRAME_NAME: "frame-name",
|
||||
};
|
||||
|
||||
export const CJK_HAND_DRAWN_FALLBACK_FONT = "Xiaolai";
|
||||
@@ -324,6 +349,26 @@ export const DEFAULT_UI_OPTIONS: AppProps["UIOptions"] = {
|
||||
},
|
||||
};
|
||||
|
||||
// breakpoints
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// mobile: up to 699px
|
||||
export const MQ_MAX_MOBILE = 599;
|
||||
|
||||
export const MQ_MAX_WIDTH_LANDSCAPE = 1000;
|
||||
export const MQ_MAX_HEIGHT_LANDSCAPE = 500;
|
||||
|
||||
// tablets
|
||||
export const MQ_MIN_TABLET = MQ_MAX_MOBILE + 1; // lower bound (excludes phones)
|
||||
export const MQ_MAX_TABLET = 1400; // upper bound (excludes laptops/desktops)
|
||||
|
||||
// desktop/laptop
|
||||
export const MQ_MIN_WIDTH_DESKTOP = 1440;
|
||||
|
||||
// sidebar
|
||||
export const MQ_RIGHT_SIDEBAR_MIN_WIDTH = 1229;
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
export const MAX_DECIMALS_FOR_SVG_EXPORT = 2;
|
||||
|
||||
export const EXPORT_SCALES = [1, 2, 3];
|
||||
@@ -397,8 +442,9 @@ export const ROUGHNESS = {
|
||||
|
||||
export const STROKE_WIDTH = {
|
||||
thin: 1,
|
||||
bold: 2,
|
||||
extraBold: 4,
|
||||
medium: 2,
|
||||
bold: 4,
|
||||
extraBold: 8,
|
||||
} as const;
|
||||
|
||||
export const DEFAULT_ELEMENT_PROPS: {
|
||||
@@ -414,7 +460,7 @@ export const DEFAULT_ELEMENT_PROPS: {
|
||||
strokeColor: COLOR_PALETTE.black,
|
||||
backgroundColor: COLOR_PALETTE.transparent,
|
||||
fillStyle: "solid",
|
||||
strokeWidth: 2,
|
||||
strokeWidth: STROKE_WIDTH.medium,
|
||||
strokeStyle: "solid",
|
||||
roughness: ROUGHNESS.artist,
|
||||
opacity: 100,
|
||||
|
||||
@@ -1,223 +0,0 @@
|
||||
export type StylesPanelMode = "compact" | "full" | "mobile";
|
||||
|
||||
export type EditorInterface = Readonly<{
|
||||
formFactor: "phone" | "tablet" | "desktop";
|
||||
desktopUIMode: "compact" | "full";
|
||||
userAgent: Readonly<{
|
||||
isMobileDevice: boolean;
|
||||
platform: "ios" | "android" | "other" | "unknown";
|
||||
}>;
|
||||
isTouchScreen: boolean;
|
||||
canFitSidebar: boolean;
|
||||
isLandscape: boolean;
|
||||
}>;
|
||||
|
||||
// storage key
|
||||
const DESKTOP_UI_MODE_STORAGE_KEY = "excalidraw.desktopUIMode";
|
||||
|
||||
// breakpoints
|
||||
// mobile: up to 699px
|
||||
export const MQ_MAX_MOBILE = 599;
|
||||
|
||||
export const MQ_MAX_WIDTH_LANDSCAPE = 1000;
|
||||
export const MQ_MAX_HEIGHT_LANDSCAPE = 500;
|
||||
|
||||
// tablets
|
||||
export const MQ_MIN_TABLET = MQ_MAX_MOBILE + 1; // lower bound (excludes phones)
|
||||
export const MQ_MAX_TABLET = 1400; // upper bound (excludes laptops/desktops)
|
||||
|
||||
// desktop/laptop
|
||||
export const MQ_MIN_WIDTH_DESKTOP = 1440;
|
||||
|
||||
// sidebar
|
||||
export const MQ_RIGHT_SIDEBAR_MIN_WIDTH = 1229;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// user agent detections
|
||||
export const isDarwin = /Mac|iPod|iPhone|iPad/.test(navigator.platform);
|
||||
export const isWindows = /^Win/.test(navigator.platform);
|
||||
export const isAndroid = /\b(android)\b/i.test(navigator.userAgent);
|
||||
export const isFirefox =
|
||||
typeof window !== "undefined" &&
|
||||
"netscape" in window &&
|
||||
navigator.userAgent.indexOf("rv:") > 1 &&
|
||||
navigator.userAgent.indexOf("Gecko") > 1;
|
||||
export const isChrome = navigator.userAgent.indexOf("Chrome") !== -1;
|
||||
export const isSafari =
|
||||
!isChrome && navigator.userAgent.indexOf("Safari") !== -1;
|
||||
export const isIOS =
|
||||
/iPad|iPhone/i.test(navigator.platform) ||
|
||||
// iPadOS 13+
|
||||
(navigator.userAgent.includes("Mac") && "ontouchend" in document);
|
||||
// keeping function so it can be mocked in test
|
||||
export const isBrave = () =>
|
||||
(navigator as any).brave?.isBrave?.name === "isBrave";
|
||||
|
||||
// export const isMobile =
|
||||
// isIOS ||
|
||||
// /android|webos|ipod|blackberry|iemobile|opera mini/i.test(
|
||||
// navigator.userAgent,
|
||||
// ) ||
|
||||
// /android|ios|ipod|blackberry|windows phone/i.test(navigator.platform);
|
||||
|
||||
// utilities
|
||||
export const isMobileBreakpoint = (width: number, height: number) => {
|
||||
return (
|
||||
width <= MQ_MAX_MOBILE ||
|
||||
(height < MQ_MAX_HEIGHT_LANDSCAPE && width < MQ_MAX_WIDTH_LANDSCAPE)
|
||||
);
|
||||
};
|
||||
|
||||
export const isTabletBreakpoint = (
|
||||
editorWidth: number,
|
||||
editorHeight: number,
|
||||
) => {
|
||||
const minSide = Math.min(editorWidth, editorHeight);
|
||||
const maxSide = Math.max(editorWidth, editorHeight);
|
||||
|
||||
return minSide >= MQ_MIN_TABLET && maxSide <= MQ_MAX_TABLET;
|
||||
};
|
||||
|
||||
const isMobileOrTablet = (): boolean => {
|
||||
const ua = navigator.userAgent || "";
|
||||
const platform = navigator.platform || "";
|
||||
const uaData = (navigator as any).userAgentData as
|
||||
| { mobile?: boolean; platform?: string }
|
||||
| undefined;
|
||||
|
||||
// --- 1) chromium: prefer ua client hints -------------------------------
|
||||
if (uaData) {
|
||||
const plat = (uaData.platform || "").toLowerCase();
|
||||
const isDesktopOS =
|
||||
plat === "windows" ||
|
||||
plat === "macos" ||
|
||||
plat === "linux" ||
|
||||
plat === "chrome os";
|
||||
if (uaData.mobile === true) {
|
||||
return true;
|
||||
}
|
||||
if (uaData.mobile === false && plat === "android") {
|
||||
const looksTouchTablet =
|
||||
matchMedia?.("(hover: none)").matches &&
|
||||
matchMedia?.("(pointer: coarse)").matches;
|
||||
return looksTouchTablet;
|
||||
}
|
||||
if (isDesktopOS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// --- 2) ios (includes ipad) --------------------------------------------
|
||||
if (isIOS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// --- 3) android legacy ua fallback -------------------------------------
|
||||
if (isAndroid) {
|
||||
const isAndroidPhone = /Mobile/i.test(ua);
|
||||
const isAndroidTablet = !isAndroidPhone;
|
||||
if (isAndroidPhone || isAndroidTablet) {
|
||||
const looksTouchTablet =
|
||||
matchMedia?.("(hover: none)").matches &&
|
||||
matchMedia?.("(pointer: coarse)").matches;
|
||||
return looksTouchTablet;
|
||||
}
|
||||
}
|
||||
|
||||
// --- 4) last resort desktop exclusion ----------------------------------
|
||||
const looksDesktopPlatform =
|
||||
/Win|Linux|CrOS|Mac/.test(platform) ||
|
||||
/Windows NT|X11|CrOS|Macintosh/.test(ua);
|
||||
if (looksDesktopPlatform) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
export const getFormFactor = (
|
||||
editorWidth: number,
|
||||
editorHeight: number,
|
||||
): EditorInterface["formFactor"] => {
|
||||
if (isMobileBreakpoint(editorWidth, editorHeight)) {
|
||||
return "phone";
|
||||
}
|
||||
|
||||
if (isTabletBreakpoint(editorWidth, editorHeight)) {
|
||||
return "tablet";
|
||||
}
|
||||
|
||||
return "desktop";
|
||||
};
|
||||
|
||||
export const deriveStylesPanelMode = (
|
||||
editorInterface: EditorInterface,
|
||||
): StylesPanelMode => {
|
||||
if (editorInterface.formFactor === "phone") {
|
||||
return "mobile";
|
||||
}
|
||||
|
||||
if (editorInterface.formFactor === "tablet") {
|
||||
return "compact";
|
||||
}
|
||||
|
||||
return editorInterface.desktopUIMode;
|
||||
};
|
||||
|
||||
export const createUserAgentDescriptor = (
|
||||
userAgentString: string,
|
||||
): EditorInterface["userAgent"] => {
|
||||
const normalizedUA = userAgentString ?? "";
|
||||
let platform: EditorInterface["userAgent"]["platform"] = "unknown";
|
||||
|
||||
if (isIOS) {
|
||||
platform = "ios";
|
||||
} else if (isAndroid) {
|
||||
platform = "android";
|
||||
} else if (normalizedUA) {
|
||||
platform = "other";
|
||||
}
|
||||
|
||||
return {
|
||||
isMobileDevice: isMobileOrTablet(),
|
||||
platform,
|
||||
} as const;
|
||||
};
|
||||
|
||||
export const loadDesktopUIModePreference = () => {
|
||||
if (typeof window === "undefined") {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
const stored = window.localStorage.getItem(DESKTOP_UI_MODE_STORAGE_KEY);
|
||||
if (stored === "compact" || stored === "full") {
|
||||
return stored as EditorInterface["desktopUIMode"];
|
||||
}
|
||||
} catch (error) {
|
||||
// ignore storage access issues (e.g., Safari private mode)
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const persistDesktopUIMode = (mode: EditorInterface["desktopUIMode"]) => {
|
||||
if (typeof window === "undefined") {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
window.localStorage.setItem(DESKTOP_UI_MODE_STORAGE_KEY, mode);
|
||||
} catch (error) {
|
||||
// ignore storage access issues (e.g., Safari private mode)
|
||||
}
|
||||
};
|
||||
|
||||
export const setDesktopUIMode = (mode: EditorInterface["desktopUIMode"]) => {
|
||||
if (mode !== "compact" && mode !== "full") {
|
||||
return;
|
||||
}
|
||||
|
||||
persistDesktopUIMode(mode);
|
||||
|
||||
return mode;
|
||||
};
|
||||
@@ -10,5 +10,3 @@ export * from "./random";
|
||||
export * from "./url";
|
||||
export * from "./utils";
|
||||
export * from "./emitter";
|
||||
export * from "./visualdebug";
|
||||
export * from "./editorInterface";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { isDarwin } from "./editorInterface";
|
||||
import { isDarwin } from "./constants";
|
||||
|
||||
import type { ValueOf } from "./utility-types";
|
||||
|
||||
|
||||
@@ -20,6 +20,8 @@ import {
|
||||
ENV,
|
||||
FONT_FAMILY,
|
||||
getFontFamilyFallbacks,
|
||||
isAndroid,
|
||||
isIOS,
|
||||
WINDOWS_EMOJI_FALLBACK_FONT,
|
||||
} from "./constants";
|
||||
|
||||
@@ -1270,3 +1272,59 @@ export const reduceToCommonValue = <T, R = T>(
|
||||
|
||||
return commonValue;
|
||||
};
|
||||
|
||||
export const isMobileOrTablet = (): boolean => {
|
||||
const ua = navigator.userAgent || "";
|
||||
const platform = navigator.platform || "";
|
||||
const uaData = (navigator as any).userAgentData as
|
||||
| { mobile?: boolean; platform?: string }
|
||||
| undefined;
|
||||
|
||||
// --- 1) chromium: prefer ua client hints -------------------------------
|
||||
if (uaData) {
|
||||
const plat = (uaData.platform || "").toLowerCase();
|
||||
const isDesktopOS =
|
||||
plat === "windows" ||
|
||||
plat === "macos" ||
|
||||
plat === "linux" ||
|
||||
plat === "chrome os";
|
||||
if (uaData.mobile === true) {
|
||||
return true;
|
||||
}
|
||||
if (uaData.mobile === false && plat === "android") {
|
||||
const looksTouchTablet =
|
||||
matchMedia?.("(hover: none)").matches &&
|
||||
matchMedia?.("(pointer: coarse)").matches;
|
||||
return looksTouchTablet;
|
||||
}
|
||||
if (isDesktopOS) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// --- 2) ios (includes ipad) --------------------------------------------
|
||||
if (isIOS) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// --- 3) android legacy ua fallback -------------------------------------
|
||||
if (isAndroid) {
|
||||
const isAndroidPhone = /Mobile/i.test(ua);
|
||||
const isAndroidTablet = !isAndroidPhone;
|
||||
if (isAndroidPhone || isAndroidTablet) {
|
||||
const looksTouchTablet =
|
||||
matchMedia?.("(hover: none)").matches &&
|
||||
matchMedia?.("(pointer: coarse)").matches;
|
||||
return looksTouchTablet;
|
||||
}
|
||||
}
|
||||
|
||||
// --- 4) last resort desktop exclusion ----------------------------------
|
||||
const looksDesktopPlatform =
|
||||
/Win|Linux|CrOS|Mac/.test(platform) ||
|
||||
/Windows NT|X11|CrOS|Macintosh/.test(ua);
|
||||
if (looksDesktopPlatform) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
invariant,
|
||||
rescalePoints,
|
||||
sizeOf,
|
||||
STROKE_WIDTH,
|
||||
} from "@excalidraw/common";
|
||||
|
||||
import {
|
||||
@@ -832,9 +833,15 @@ export const getArrowheadPoints = (
|
||||
// This value is selected by minimizing a minimum size with the last segment of the arrowhead
|
||||
const lengthMultiplier =
|
||||
arrowhead === "diamond" || arrowhead === "diamond_outline" ? 0.25 : 0.5;
|
||||
const minSize = Math.min(size, length * lengthMultiplier);
|
||||
const xs = x2 - nx * minSize;
|
||||
const ys = y2 - ny * minSize;
|
||||
// make arrowheads bigger for thick strokes
|
||||
const strokeWidthMultiplier =
|
||||
element.strokeWidth >= STROKE_WIDTH.extraBold ? 1.5 : 1;
|
||||
|
||||
const adjustedSize =
|
||||
Math.min(size, length * lengthMultiplier) * strokeWidthMultiplier;
|
||||
|
||||
const xs = x2 - nx * adjustedSize;
|
||||
const ys = y2 - ny * adjustedSize;
|
||||
|
||||
if (
|
||||
arrowhead === "dot" ||
|
||||
@@ -883,7 +890,7 @@ export const getArrowheadPoints = (
|
||||
const [px, py] = element.points.length > 1 ? element.points[1] : [0, 0];
|
||||
|
||||
[ox, oy] = pointRotateRads(
|
||||
pointFrom(x2 + minSize * 2, y2),
|
||||
pointFrom(x2 + adjustedSize * 2, y2),
|
||||
pointFrom(x2, y2),
|
||||
Math.atan2(py - y2, px - x2) as Radians,
|
||||
);
|
||||
@@ -894,7 +901,7 @@ export const getArrowheadPoints = (
|
||||
: [0, 0];
|
||||
|
||||
[ox, oy] = pointRotateRads(
|
||||
pointFrom(x2 - minSize * 2, y2),
|
||||
pointFrom(x2 - adjustedSize * 2, y2),
|
||||
pointFrom(x2, y2),
|
||||
Math.atan2(y2 - py, x2 - px) as Radians,
|
||||
);
|
||||
|
||||
@@ -11,9 +11,12 @@ import {
|
||||
vectorFromPoint,
|
||||
vectorNormalize,
|
||||
vectorScale,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import {
|
||||
ellipse,
|
||||
ellipseSegmentInterceptPoints,
|
||||
} from "@excalidraw/math";
|
||||
} from "@excalidraw/math/ellipse";
|
||||
|
||||
import type {
|
||||
Curve,
|
||||
|
||||
@@ -2,10 +2,10 @@ import {
|
||||
curvePointDistance,
|
||||
distanceToLineSegment,
|
||||
pointRotateRads,
|
||||
ellipse,
|
||||
ellipseDistanceFromPoint,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import { ellipse, ellipseDistanceFromPoint } from "@excalidraw/math/ellipse";
|
||||
|
||||
import type { GlobalPoint, Radians } from "@excalidraw/math";
|
||||
|
||||
import {
|
||||
|
||||
@@ -0,0 +1,373 @@
|
||||
import { LaserPointer, type Point } from "@excalidraw/laser-pointer";
|
||||
|
||||
import {
|
||||
clamp,
|
||||
lineSegment,
|
||||
pointFrom,
|
||||
pointRotateRads,
|
||||
round,
|
||||
type LocalPoint,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import getStroke from "perfect-freehand";
|
||||
|
||||
import { invariant } from "@excalidraw/common";
|
||||
|
||||
import type { GlobalPoint, Radians } from "@excalidraw/math";
|
||||
|
||||
import { getElementBounds } from "./bounds";
|
||||
|
||||
import type { StrokeOptions } from "perfect-freehand";
|
||||
|
||||
import type {
|
||||
ElementsMap,
|
||||
ExcalidrawFreeDrawElement,
|
||||
PointerType,
|
||||
} from "./types";
|
||||
|
||||
export const STROKE_OPTIONS: Record<
|
||||
PointerType | "default",
|
||||
{ streamline: number; simplify: number }
|
||||
> = {
|
||||
default: {
|
||||
streamline: 0.35,
|
||||
simplify: 0.1,
|
||||
},
|
||||
mouse: {
|
||||
streamline: 0.6,
|
||||
simplify: 0.1,
|
||||
},
|
||||
pen: {
|
||||
// for optimal performance, we use a lower streamline and simplify
|
||||
streamline: 0.2,
|
||||
simplify: 0.1,
|
||||
},
|
||||
touch: {
|
||||
streamline: 0.65,
|
||||
simplify: 0.1,
|
||||
},
|
||||
} as const;
|
||||
|
||||
export const getFreedrawConfig = (eventType: string | null | undefined) => {
|
||||
return (
|
||||
STROKE_OPTIONS[(eventType as PointerType | null) || "default"] ||
|
||||
STROKE_OPTIONS.default
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates simulated pressure based on velocity between consecutive points.
|
||||
* Fast movement (large distances) -> lower pressure
|
||||
* Slow movement (small distances) -> higher pressure
|
||||
*/
|
||||
const calculateVelocityBasedPressure = (
|
||||
points: readonly LocalPoint[],
|
||||
index: number,
|
||||
fixedStrokeWidth: boolean | undefined,
|
||||
maxDistance = 8, // Maximum expected distance for normalization
|
||||
): number => {
|
||||
if (fixedStrokeWidth) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
// First point gets highest pressure
|
||||
// This avoid "a dot followed by a line" effect, •== when first stroke is "slow"
|
||||
if (index === 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const [x1, y1] = points[index - 1];
|
||||
const [x2, y2] = points[index];
|
||||
|
||||
// Calculate distance between consecutive points
|
||||
const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
|
||||
|
||||
// Normalize distance and invert for pressure (0 = fast/low pressure, 1 = slow/high pressure)
|
||||
const normalizedDistance = Math.min(distance / maxDistance, 1);
|
||||
const basePressure = Math.max(0.1, 1 - normalizedDistance * 0.7); // Range: 0.1 to 1.0
|
||||
|
||||
const constantPressure = 0.5;
|
||||
const pressure = constantPressure + (basePressure - constantPressure);
|
||||
|
||||
return Math.max(0.1, Math.min(1.0, pressure));
|
||||
};
|
||||
|
||||
export const getFreedrawStroke = (element: ExcalidrawFreeDrawElement) => {
|
||||
// Compose points as [x, y, pressure]
|
||||
let points: [number, number, number][];
|
||||
if (element.freedrawOptions?.fixedStrokeWidth) {
|
||||
points = element.points.map(
|
||||
([x, y]: LocalPoint): [number, number, number] => [x, y, 1],
|
||||
);
|
||||
} else if (element.simulatePressure) {
|
||||
// Simulate pressure based on velocity between consecutive points
|
||||
points = element.points.map(([x, y]: LocalPoint, i) => [
|
||||
x,
|
||||
y,
|
||||
calculateVelocityBasedPressure(
|
||||
element.points,
|
||||
i,
|
||||
element.freedrawOptions?.fixedStrokeWidth,
|
||||
),
|
||||
]);
|
||||
} else {
|
||||
points = element.points.map(([x, y]: LocalPoint, i) => {
|
||||
const rawPressure = element.pressures?.[i] ?? 0.5;
|
||||
|
||||
const amplifiedPressure = Math.pow(rawPressure, 0.6);
|
||||
const adjustedPressure = amplifiedPressure;
|
||||
|
||||
return [x, y, clamp(adjustedPressure, 0.1, 1.0)];
|
||||
});
|
||||
}
|
||||
|
||||
const streamline =
|
||||
element.freedrawOptions?.streamline ?? STROKE_OPTIONS.default.streamline;
|
||||
const simplify =
|
||||
element.freedrawOptions?.simplify ?? STROKE_OPTIONS.default.simplify;
|
||||
|
||||
const laser = new LaserPointer({
|
||||
size: element.strokeWidth,
|
||||
streamline,
|
||||
simplify,
|
||||
sizeMapping: ({ pressure: t }) => {
|
||||
if (element.freedrawOptions?.fixedStrokeWidth) {
|
||||
return 0.6;
|
||||
}
|
||||
|
||||
if (element.simulatePressure) {
|
||||
return 0.2 + t * 0.6;
|
||||
}
|
||||
|
||||
return 0.2 + t * 0.8;
|
||||
},
|
||||
});
|
||||
|
||||
for (const pt of points) {
|
||||
laser.addPoint(pt);
|
||||
}
|
||||
laser.close();
|
||||
|
||||
return laser.getStrokeOutline();
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates an SVG path for a freedraw element using LaserPointer logic.
|
||||
* Uses actual pressure data if available, otherwise simulates pressure based on velocity.
|
||||
* No streamline, smoothing, or simulation is performed.
|
||||
*/
|
||||
export const getFreeDrawSvgPath = (
|
||||
element: ExcalidrawFreeDrawElement,
|
||||
): string => {
|
||||
// legacy, for backwards compatibility
|
||||
if (element.freedrawOptions === null) {
|
||||
return _legacy_getFreeDrawSvgPath(element);
|
||||
}
|
||||
|
||||
return _transition_getFreeDrawSvgPath(element);
|
||||
|
||||
// return getSvgPathFromStroke(getFreedrawStroke(element));
|
||||
};
|
||||
|
||||
const roundPoint = (A: Point): string => {
|
||||
return `${round(A[0], 4, "round")},${round(A[1], 4, "round")} `;
|
||||
};
|
||||
|
||||
const average = (A: Point, B: Point): string => {
|
||||
return `${round((A[0] + B[0]) / 2, 4, "round")},${round(
|
||||
(A[1] + B[1]) / 2,
|
||||
4,
|
||||
"round",
|
||||
)} `;
|
||||
};
|
||||
|
||||
export const getSvgPathFromStroke = (points: Point[]): string => {
|
||||
const len = points.length;
|
||||
|
||||
if (len < 2) {
|
||||
return "";
|
||||
}
|
||||
|
||||
let a = points[0];
|
||||
let b = points[1];
|
||||
|
||||
if (len === 2) {
|
||||
return `M${roundPoint(a)}L${roundPoint(b)}`;
|
||||
}
|
||||
|
||||
let result = "";
|
||||
|
||||
for (let i = 2, max = len - 1; i < max; i++) {
|
||||
a = points[i];
|
||||
b = points[i + 1];
|
||||
result += average(a, b);
|
||||
}
|
||||
|
||||
return `M${roundPoint(points[0])}Q${roundPoint(points[1])}${average(
|
||||
points[1],
|
||||
points[2],
|
||||
)}${points.length > 3 ? "T" : ""}${result}L${roundPoint(points[len - 1])}`;
|
||||
};
|
||||
|
||||
function _transition_getFreeDrawSvgPath(element: ExcalidrawFreeDrawElement) {
|
||||
const inputPoints = element.simulatePressure
|
||||
? element.points
|
||||
: element.points.length
|
||||
? element.points.map(([x, y], i) => [x, y, element.pressures[i]])
|
||||
: [[0, 0, 0.5]];
|
||||
|
||||
// Consider changing the options for simulated pressure vs real pressure
|
||||
const options: StrokeOptions = {
|
||||
simulatePressure: element.simulatePressure,
|
||||
size: element.strokeWidth,
|
||||
thinning: 0.6,
|
||||
smoothing: 0.5,
|
||||
streamline: 0.5,
|
||||
easing: (t) => {
|
||||
if (element.freedrawOptions?.fixedStrokeWidth) {
|
||||
return 0.5;
|
||||
}
|
||||
|
||||
return Math.sin((t * Math.PI) / 2) * 0.65;
|
||||
}, // https://easings.net/#easeOutSine
|
||||
last: !!element.lastCommittedPoint, // LastCommittedPoint is added on pointerup
|
||||
};
|
||||
|
||||
return _legacy_getSvgPathFromStroke(
|
||||
getStroke(inputPoints as number[][], options),
|
||||
);
|
||||
}
|
||||
|
||||
function _legacy_getFreeDrawSvgPath(element: ExcalidrawFreeDrawElement) {
|
||||
// If input points are empty (should they ever be?) return a dot
|
||||
const inputPoints = element.simulatePressure
|
||||
? element.points
|
||||
: element.points.length
|
||||
? element.points.map(([x, y], i) => [x, y, element.pressures[i]])
|
||||
: [[0, 0, 0.5]];
|
||||
|
||||
// Consider changing the options for simulated pressure vs real pressure
|
||||
const options: StrokeOptions = {
|
||||
simulatePressure: element.simulatePressure,
|
||||
size: element.strokeWidth * 4.25,
|
||||
thinning: 0.6,
|
||||
smoothing: 0.5,
|
||||
streamline: 0.5,
|
||||
easing: (t) => Math.sin((t * Math.PI) / 2), // https://easings.net/#easeOutSine
|
||||
last: !!element.lastCommittedPoint, // LastCommittedPoint is added on pointerup
|
||||
};
|
||||
|
||||
return _legacy_getSvgPathFromStroke(
|
||||
getStroke(inputPoints as number[][], options),
|
||||
);
|
||||
}
|
||||
|
||||
const med = (A: number[], B: number[]) => {
|
||||
return [(A[0] + B[0]) / 2, (A[1] + B[1]) / 2];
|
||||
};
|
||||
|
||||
// Trim SVG path data so number are each two decimal points. This
|
||||
// improves SVG exports, and prevents rendering errors on points
|
||||
// with long decimals.
|
||||
const TO_FIXED_PRECISION = /(\s?[A-Z]?,?-?[0-9]*\.[0-9]{0,2})(([0-9]|e|-)*)/g;
|
||||
|
||||
const _legacy_getSvgPathFromStroke = (points: number[][]): string => {
|
||||
if (!points.length) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const max = points.length - 1;
|
||||
|
||||
return points
|
||||
.reduce(
|
||||
(acc, point, i, arr) => {
|
||||
if (i === max) {
|
||||
acc.push(point, med(point, arr[0]), "L", arr[0], "Z");
|
||||
} else {
|
||||
acc.push(point, med(point, arr[i + 1]));
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
["M", points[0], "Q"],
|
||||
)
|
||||
.join(" ")
|
||||
.replace(TO_FIXED_PRECISION, "$1");
|
||||
};
|
||||
|
||||
export function getFreedrawOutlineAsSegments(
|
||||
element: ExcalidrawFreeDrawElement,
|
||||
points: [number, number][],
|
||||
elementsMap: ElementsMap,
|
||||
) {
|
||||
const bounds = getElementBounds(
|
||||
{
|
||||
...element,
|
||||
angle: 0 as Radians,
|
||||
},
|
||||
elementsMap,
|
||||
);
|
||||
const center = pointFrom<GlobalPoint>(
|
||||
(bounds[0] + bounds[2]) / 2,
|
||||
(bounds[1] + bounds[3]) / 2,
|
||||
);
|
||||
|
||||
invariant(points.length >= 2, "Freepath outline must have at least 2 points");
|
||||
|
||||
return points.slice(2).reduce(
|
||||
(acc, curr) => {
|
||||
acc.push(
|
||||
lineSegment<GlobalPoint>(
|
||||
acc[acc.length - 1][1],
|
||||
pointRotateRads(
|
||||
pointFrom<GlobalPoint>(curr[0] + element.x, curr[1] + element.y),
|
||||
center,
|
||||
element.angle,
|
||||
),
|
||||
),
|
||||
);
|
||||
return acc;
|
||||
},
|
||||
[
|
||||
lineSegment<GlobalPoint>(
|
||||
pointRotateRads(
|
||||
pointFrom<GlobalPoint>(
|
||||
points[0][0] + element.x,
|
||||
points[0][1] + element.y,
|
||||
),
|
||||
center,
|
||||
element.angle,
|
||||
),
|
||||
pointRotateRads(
|
||||
pointFrom<GlobalPoint>(
|
||||
points[1][0] + element.x,
|
||||
points[1][1] + element.y,
|
||||
),
|
||||
center,
|
||||
element.angle,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
export function getFreedrawOutlinePoints(element: ExcalidrawFreeDrawElement) {
|
||||
// If input points are empty (should they ever be?) return a dot
|
||||
const inputPoints = element.simulatePressure
|
||||
? element.points
|
||||
: element.points.length
|
||||
? element.points.map(([x, y], i) => [x, y, element.pressures[i]])
|
||||
: [[0, 0, 0.5]];
|
||||
|
||||
// Consider changing the options for simulated pressure vs real pressure
|
||||
const options: StrokeOptions = {
|
||||
simulatePressure: element.simulatePressure,
|
||||
size: element.strokeWidth * 4.25,
|
||||
thinning: 0.6,
|
||||
smoothing: 0.5,
|
||||
streamline: 0.5,
|
||||
easing: (t) => Math.sin((t * Math.PI) / 2), // https://easings.net/#easeOutSine
|
||||
last: !!element.lastCommittedPoint, // LastCommittedPoint is added on pointerup
|
||||
};
|
||||
|
||||
return getStroke(inputPoints as number[][], options) as [number, number][];
|
||||
}
|
||||
@@ -94,6 +94,7 @@ export * from "./embeddable";
|
||||
export * from "./flowchart";
|
||||
export * from "./fractionalIndex";
|
||||
export * from "./frame";
|
||||
export * from "./freedraw";
|
||||
export * from "./groups";
|
||||
export * from "./heading";
|
||||
export * from "./image";
|
||||
|
||||
@@ -445,6 +445,7 @@ export const newFreeDrawElement = (
|
||||
points?: ExcalidrawFreeDrawElement["points"];
|
||||
simulatePressure: boolean;
|
||||
pressures?: ExcalidrawFreeDrawElement["pressures"];
|
||||
strokeOptions?: ExcalidrawFreeDrawElement["freedrawOptions"];
|
||||
} & ElementConstructorOpts,
|
||||
): NonDeleted<ExcalidrawFreeDrawElement> => {
|
||||
return {
|
||||
@@ -453,6 +454,11 @@ export const newFreeDrawElement = (
|
||||
pressures: opts.pressures || [],
|
||||
simulatePressure: opts.simulatePressure,
|
||||
lastCommittedPoint: null,
|
||||
freedrawOptions: opts.strokeOptions || {
|
||||
fixedStrokeWidth: true,
|
||||
streamline: 0.25,
|
||||
simplify: 0.1,
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -1,14 +1,6 @@
|
||||
import rough from "roughjs/bin/rough";
|
||||
import { getStroke } from "perfect-freehand";
|
||||
|
||||
import {
|
||||
type GlobalPoint,
|
||||
isRightAngleRads,
|
||||
lineSegment,
|
||||
pointFrom,
|
||||
pointRotateRads,
|
||||
type Radians,
|
||||
} from "@excalidraw/math";
|
||||
import { isRightAngleRads } from "@excalidraw/math";
|
||||
|
||||
import {
|
||||
BOUND_TEXT_PADDING,
|
||||
@@ -21,7 +13,6 @@ import {
|
||||
getFontString,
|
||||
isRTL,
|
||||
getVerticalOffset,
|
||||
invariant,
|
||||
} from "@excalidraw/common";
|
||||
|
||||
import type {
|
||||
@@ -40,7 +31,7 @@ import type {
|
||||
InteractiveCanvasRenderConfig,
|
||||
} from "@excalidraw/excalidraw/scene/types";
|
||||
|
||||
import { getElementAbsoluteCoords, getElementBounds } from "./bounds";
|
||||
import { getElementAbsoluteCoords } from "./bounds";
|
||||
import { getUncroppedImageElement } from "./cropElement";
|
||||
import { LinearElementEditor } from "./linearElementEditor";
|
||||
import {
|
||||
@@ -66,6 +57,8 @@ import { getCornerRadius } from "./utils";
|
||||
|
||||
import { ShapeCache } from "./shape";
|
||||
|
||||
import { getFreeDrawSvgPath } from "./freedraw";
|
||||
|
||||
import type {
|
||||
ExcalidrawElement,
|
||||
ExcalidrawTextElement,
|
||||
@@ -78,7 +71,6 @@ import type {
|
||||
ElementsMap,
|
||||
} from "./types";
|
||||
|
||||
import type { StrokeOptions } from "perfect-freehand";
|
||||
import type { RoughCanvas } from "roughjs/bin/canvas";
|
||||
|
||||
// using a stronger invert (100% vs our regular 93%) and saturate
|
||||
@@ -1045,117 +1037,3 @@ export function generateFreeDrawShape(element: ExcalidrawFreeDrawElement) {
|
||||
export function getFreeDrawPath2D(element: ExcalidrawFreeDrawElement) {
|
||||
return pathsCache.get(element);
|
||||
}
|
||||
|
||||
export function getFreeDrawSvgPath(element: ExcalidrawFreeDrawElement) {
|
||||
return getSvgPathFromStroke(getFreedrawOutlinePoints(element));
|
||||
}
|
||||
|
||||
export function getFreedrawOutlineAsSegments(
|
||||
element: ExcalidrawFreeDrawElement,
|
||||
points: [number, number][],
|
||||
elementsMap: ElementsMap,
|
||||
) {
|
||||
const bounds = getElementBounds(
|
||||
{
|
||||
...element,
|
||||
angle: 0 as Radians,
|
||||
},
|
||||
elementsMap,
|
||||
);
|
||||
const center = pointFrom<GlobalPoint>(
|
||||
(bounds[0] + bounds[2]) / 2,
|
||||
(bounds[1] + bounds[3]) / 2,
|
||||
);
|
||||
|
||||
invariant(points.length >= 2, "Freepath outline must have at least 2 points");
|
||||
|
||||
return points.slice(2).reduce(
|
||||
(acc, curr) => {
|
||||
acc.push(
|
||||
lineSegment<GlobalPoint>(
|
||||
acc[acc.length - 1][1],
|
||||
pointRotateRads(
|
||||
pointFrom<GlobalPoint>(curr[0] + element.x, curr[1] + element.y),
|
||||
center,
|
||||
element.angle,
|
||||
),
|
||||
),
|
||||
);
|
||||
return acc;
|
||||
},
|
||||
[
|
||||
lineSegment<GlobalPoint>(
|
||||
pointRotateRads(
|
||||
pointFrom<GlobalPoint>(
|
||||
points[0][0] + element.x,
|
||||
points[0][1] + element.y,
|
||||
),
|
||||
center,
|
||||
element.angle,
|
||||
),
|
||||
pointRotateRads(
|
||||
pointFrom<GlobalPoint>(
|
||||
points[1][0] + element.x,
|
||||
points[1][1] + element.y,
|
||||
),
|
||||
center,
|
||||
element.angle,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
export function getFreedrawOutlinePoints(element: ExcalidrawFreeDrawElement) {
|
||||
// If input points are empty (should they ever be?) return a dot
|
||||
const inputPoints = element.simulatePressure
|
||||
? element.points
|
||||
: element.points.length
|
||||
? element.points.map(([x, y], i) => [x, y, element.pressures[i]])
|
||||
: [[0, 0, 0.5]];
|
||||
|
||||
// Consider changing the options for simulated pressure vs real pressure
|
||||
const options: StrokeOptions = {
|
||||
simulatePressure: element.simulatePressure,
|
||||
size: element.strokeWidth * 4.25,
|
||||
thinning: 0.6,
|
||||
smoothing: 0.5,
|
||||
streamline: 0.5,
|
||||
easing: (t) => Math.sin((t * Math.PI) / 2), // https://easings.net/#easeOutSine
|
||||
last: !!element.lastCommittedPoint, // LastCommittedPoint is added on pointerup
|
||||
};
|
||||
|
||||
return getStroke(inputPoints as number[][], options) as [number, number][];
|
||||
}
|
||||
|
||||
function med(A: number[], B: number[]) {
|
||||
return [(A[0] + B[0]) / 2, (A[1] + B[1]) / 2];
|
||||
}
|
||||
|
||||
// Trim SVG path data so number are each two decimal points. This
|
||||
// improves SVG exports, and prevents rendering errors on points
|
||||
// with long decimals.
|
||||
const TO_FIXED_PRECISION = /(\s?[A-Z]?,?-?[0-9]*\.[0-9]{0,2})(([0-9]|e|-)*)/g;
|
||||
|
||||
function getSvgPathFromStroke(points: number[][]): string {
|
||||
if (!points.length) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const max = points.length - 1;
|
||||
|
||||
return points
|
||||
.reduce(
|
||||
(acc, point, i, arr) => {
|
||||
if (i === max) {
|
||||
acc.push(point, med(point, arr[0]), "L", arr[0], "Z");
|
||||
} else {
|
||||
acc.push(point, med(point, arr[i + 1]));
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
["M", points[0], "Q"],
|
||||
)
|
||||
.join(" ")
|
||||
.replace(TO_FIXED_PRECISION, "$1");
|
||||
}
|
||||
|
||||
@@ -5,20 +5,17 @@ import {
|
||||
type Radians,
|
||||
} from "@excalidraw/math";
|
||||
|
||||
import {
|
||||
SIDE_RESIZING_THRESHOLD,
|
||||
type EditorInterface,
|
||||
} from "@excalidraw/common";
|
||||
import { SIDE_RESIZING_THRESHOLD } from "@excalidraw/common";
|
||||
|
||||
import type { GlobalPoint, LineSegment, LocalPoint } from "@excalidraw/math";
|
||||
|
||||
import type { AppState, Zoom } from "@excalidraw/excalidraw/types";
|
||||
import type { AppState, Device, Zoom } from "@excalidraw/excalidraw/types";
|
||||
|
||||
import { getElementAbsoluteCoords } from "./bounds";
|
||||
import {
|
||||
getTransformHandlesFromCoords,
|
||||
getTransformHandles,
|
||||
getOmitSidesForEditorInterface,
|
||||
getOmitSidesForDevice,
|
||||
canResizeFromSides,
|
||||
} from "./transformHandles";
|
||||
import { isImageElement, isLinearElement } from "./typeChecks";
|
||||
@@ -54,7 +51,7 @@ export const resizeTest = <Point extends GlobalPoint | LocalPoint>(
|
||||
y: number,
|
||||
zoom: Zoom,
|
||||
pointerType: PointerType,
|
||||
editorInterface: EditorInterface,
|
||||
device: Device,
|
||||
): MaybeTransformHandleType => {
|
||||
if (!appState.selectedElementIds[element.id]) {
|
||||
return false;
|
||||
@@ -66,7 +63,7 @@ export const resizeTest = <Point extends GlobalPoint | LocalPoint>(
|
||||
zoom,
|
||||
elementsMap,
|
||||
pointerType,
|
||||
getOmitSidesForEditorInterface(editorInterface),
|
||||
getOmitSidesForDevice(device),
|
||||
);
|
||||
|
||||
if (
|
||||
@@ -89,7 +86,7 @@ export const resizeTest = <Point extends GlobalPoint | LocalPoint>(
|
||||
return filter[0] as TransformHandleType;
|
||||
}
|
||||
|
||||
if (canResizeFromSides(editorInterface)) {
|
||||
if (canResizeFromSides(device)) {
|
||||
const [x1, y1, x2, y2, cx, cy] = getElementAbsoluteCoords(
|
||||
element,
|
||||
elementsMap,
|
||||
@@ -135,7 +132,7 @@ export const getElementWithTransformHandleType = (
|
||||
zoom: Zoom,
|
||||
pointerType: PointerType,
|
||||
elementsMap: ElementsMap,
|
||||
editorInterface: EditorInterface,
|
||||
device: Device,
|
||||
) => {
|
||||
return elements.reduce((result, element) => {
|
||||
if (result) {
|
||||
@@ -149,7 +146,7 @@ export const getElementWithTransformHandleType = (
|
||||
scenePointerY,
|
||||
zoom,
|
||||
pointerType,
|
||||
editorInterface,
|
||||
device,
|
||||
);
|
||||
return transformHandleType ? { element, transformHandleType } : null;
|
||||
}, null as { element: NonDeletedExcalidrawElement; transformHandleType: MaybeTransformHandleType } | null);
|
||||
@@ -163,14 +160,14 @@ export const getTransformHandleTypeFromCoords = <
|
||||
scenePointerY: number,
|
||||
zoom: Zoom,
|
||||
pointerType: PointerType,
|
||||
editorInterface: EditorInterface,
|
||||
device: Device,
|
||||
): MaybeTransformHandleType => {
|
||||
const transformHandles = getTransformHandlesFromCoords(
|
||||
[x1, y1, x2, y2, (x1 + x2) / 2, (y1 + y2) / 2],
|
||||
0 as Radians,
|
||||
zoom,
|
||||
pointerType,
|
||||
getOmitSidesForEditorInterface(editorInterface),
|
||||
getOmitSidesForDevice(device),
|
||||
);
|
||||
|
||||
const found = Object.keys(transformHandles).find((key) => {
|
||||
@@ -186,7 +183,7 @@ export const getTransformHandleTypeFromCoords = <
|
||||
return found as MaybeTransformHandleType;
|
||||
}
|
||||
|
||||
if (canResizeFromSides(editorInterface)) {
|
||||
if (canResizeFromSides(device)) {
|
||||
const cx = (x1 + x2) / 2;
|
||||
const cy = (y1 + y2) / 2;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
assertNever,
|
||||
COLOR_PALETTE,
|
||||
LINE_POLYGON_POINT_MERGE_DISTANCE,
|
||||
STROKE_WIDTH,
|
||||
} from "@excalidraw/common";
|
||||
|
||||
import { RoughGenerator } from "roughjs/bin/generator";
|
||||
@@ -202,7 +203,7 @@ export const generateRoughOptions = (
|
||||
// hachureGap because if not specified, roughjs uses strokeWidth to
|
||||
// calculate them (and we don't want the fills to be modified)
|
||||
fillWeight: element.strokeWidth / 2,
|
||||
hachureGap: element.strokeWidth * 4,
|
||||
hachureGap: Math.min(element.strokeWidth, STROKE_WIDTH.bold) * 4,
|
||||
roughness: adjustRoughness(element),
|
||||
stroke: element.strokeColor,
|
||||
preserveVertices:
|
||||
@@ -806,15 +807,21 @@ const generateElementShape = (
|
||||
generateFreeDrawShape(element);
|
||||
|
||||
if (isPathALoop(element.points)) {
|
||||
// generate rough polygon to fill freedraw shape
|
||||
const simplifiedPoints = simplify(
|
||||
element.points as Mutable<LocalPoint[]>,
|
||||
0.75,
|
||||
);
|
||||
shape = generator.curve(simplifiedPoints as [number, number][], {
|
||||
...generateRoughOptions(element),
|
||||
stroke: "none",
|
||||
});
|
||||
const points =
|
||||
element.freedrawOptions === null
|
||||
? simplify(element.points as LocalPoint[], 0.75)
|
||||
: simplify(element.points as LocalPoint[], 1.5);
|
||||
|
||||
shape =
|
||||
element.freedrawOptions === null
|
||||
? generator.curve(points, {
|
||||
...generateRoughOptions(element),
|
||||
stroke: "none",
|
||||
})
|
||||
: generator.polygon(points, {
|
||||
...generateRoughOptions(element),
|
||||
stroke: "none",
|
||||
});
|
||||
} else {
|
||||
shape = null;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
DEFAULT_TRANSFORM_HANDLE_SPACING,
|
||||
type EditorInterface,
|
||||
isAndroid,
|
||||
isIOS,
|
||||
isMobileOrTablet,
|
||||
} from "@excalidraw/common";
|
||||
|
||||
import { pointFrom, pointRotateRads } from "@excalidraw/math";
|
||||
@@ -8,6 +10,7 @@ import { pointFrom, pointRotateRads } from "@excalidraw/math";
|
||||
import type { Radians } from "@excalidraw/math";
|
||||
|
||||
import type {
|
||||
Device,
|
||||
InteractiveCanvasAppState,
|
||||
Zoom,
|
||||
} from "@excalidraw/excalidraw/types";
|
||||
@@ -109,21 +112,20 @@ const generateTransformHandle = (
|
||||
return [xx - width / 2, yy - height / 2, width, height];
|
||||
};
|
||||
|
||||
export const canResizeFromSides = (editorInterface: EditorInterface) => {
|
||||
if (
|
||||
editorInterface.formFactor === "phone" &&
|
||||
editorInterface.userAgent.isMobileDevice
|
||||
) {
|
||||
export const canResizeFromSides = (device: Device) => {
|
||||
if (device.viewport.isMobile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (device.isTouchScreen && (isAndroid || isIOS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
export const getOmitSidesForEditorInterface = (
|
||||
editorInterface: EditorInterface,
|
||||
) => {
|
||||
if (canResizeFromSides(editorInterface)) {
|
||||
export const getOmitSidesForDevice = (device: Device) => {
|
||||
if (canResizeFromSides(device)) {
|
||||
return DEFAULT_OMIT_SIDES;
|
||||
}
|
||||
|
||||
@@ -328,7 +330,6 @@ export const getTransformHandles = (
|
||||
export const hasBoundingBox = (
|
||||
elements: readonly NonDeletedExcalidrawElement[],
|
||||
appState: InteractiveCanvasAppState,
|
||||
editorInterface: EditorInterface,
|
||||
) => {
|
||||
if (appState.selectedLinearElement?.isEditing) {
|
||||
return false;
|
||||
@@ -347,5 +348,5 @@ export const hasBoundingBox = (
|
||||
|
||||
// on mobile/tablet we currently don't show bbox because of resize issues
|
||||
// (also prob best for simplicity's sake)
|
||||
return element.points.length > 2 && !editorInterface.userAgent.isMobileDevice;
|
||||
return element.points.length > 2 && !isMobileOrTablet();
|
||||
};
|
||||
|
||||
@@ -380,6 +380,11 @@ export type ExcalidrawFreeDrawElement = _ExcalidrawElementBase &
|
||||
pressures: readonly number[];
|
||||
simulatePressure: boolean;
|
||||
lastCommittedPoint: LocalPoint | null;
|
||||
freedrawOptions: {
|
||||
streamline?: number;
|
||||
simplify?: number;
|
||||
fixedStrokeWidth?: boolean;
|
||||
} | null;
|
||||
}>;
|
||||
|
||||
export type FileId = string & { _brand: "FileId" };
|
||||
|
||||
@@ -83,6 +83,7 @@ export const actionChangeViewBackgroundColor = register({
|
||||
elements={elements}
|
||||
appState={appState}
|
||||
updateData={updateData}
|
||||
compactMode={appState.stylesPanelMode === "compact"}
|
||||
/>
|
||||
);
|
||||
},
|
||||
|
||||
@@ -30,8 +30,6 @@ import { getSelectedElements, isSomeElementSelected } from "../scene";
|
||||
import { TrashIcon } from "../components/icons";
|
||||
import { ToolButton } from "../components/ToolButton";
|
||||
|
||||
import { useStylesPanelMode } from "..";
|
||||
|
||||
import { register } from "./register";
|
||||
|
||||
import type { AppClassProperties, AppState } from "../types";
|
||||
@@ -322,25 +320,22 @@ export const actionDeleteSelected = register({
|
||||
keyTest: (event, appState, elements) =>
|
||||
(event.key === KEYS.BACKSPACE || event.key === KEYS.DELETE) &&
|
||||
!event[KEYS.CTRL_OR_CMD],
|
||||
PanelComponent: ({ elements, appState, updateData, app }) => {
|
||||
const isMobile = useStylesPanelMode() === "mobile";
|
||||
|
||||
return (
|
||||
<ToolButton
|
||||
type="button"
|
||||
icon={TrashIcon}
|
||||
title={t("labels.delete")}
|
||||
aria-label={t("labels.delete")}
|
||||
onClick={() => updateData(null)}
|
||||
disabled={
|
||||
!isSomeElementSelected(getNonDeletedElements(elements), appState)
|
||||
}
|
||||
style={{
|
||||
...(isMobile && appState.openPopup !== "compactOtherProperties"
|
||||
? MOBILE_ACTION_BUTTON_BG
|
||||
: {}),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData }) => (
|
||||
<ToolButton
|
||||
type="button"
|
||||
icon={TrashIcon}
|
||||
title={t("labels.delete")}
|
||||
aria-label={t("labels.delete")}
|
||||
onClick={() => updateData(null)}
|
||||
disabled={
|
||||
!isSomeElementSelected(getNonDeletedElements(elements), appState)
|
||||
}
|
||||
style={{
|
||||
...(appState.stylesPanelMode === "mobile" &&
|
||||
appState.openPopup !== "compactOtherProperties"
|
||||
? MOBILE_ACTION_BUTTON_BG
|
||||
: {}),
|
||||
}}
|
||||
/>
|
||||
),
|
||||
});
|
||||
|
||||
@@ -27,8 +27,6 @@ import { t } from "../i18n";
|
||||
import { isSomeElementSelected } from "../scene";
|
||||
import { getShortcutKey } from "../shortcut";
|
||||
|
||||
import { useStylesPanelMode } from "..";
|
||||
|
||||
import { register } from "./register";
|
||||
|
||||
export const actionDuplicateSelection = register({
|
||||
@@ -109,27 +107,24 @@ export const actionDuplicateSelection = register({
|
||||
};
|
||||
},
|
||||
keyTest: (event) => event[KEYS.CTRL_OR_CMD] && event.key === KEYS.D,
|
||||
PanelComponent: ({ elements, appState, updateData, app }) => {
|
||||
const isMobile = useStylesPanelMode() === "mobile";
|
||||
|
||||
return (
|
||||
<ToolButton
|
||||
type="button"
|
||||
icon={DuplicateIcon}
|
||||
title={`${t("labels.duplicateSelection")} — ${getShortcutKey(
|
||||
"CtrlOrCmd+D",
|
||||
)}`}
|
||||
aria-label={t("labels.duplicateSelection")}
|
||||
onClick={() => updateData(null)}
|
||||
disabled={
|
||||
!isSomeElementSelected(getNonDeletedElements(elements), appState)
|
||||
}
|
||||
style={{
|
||||
...(isMobile && appState.openPopup !== "compactOtherProperties"
|
||||
? MOBILE_ACTION_BUTTON_BG
|
||||
: {}),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData }) => (
|
||||
<ToolButton
|
||||
type="button"
|
||||
icon={DuplicateIcon}
|
||||
title={`${t("labels.duplicateSelection")} — ${getShortcutKey(
|
||||
"CtrlOrCmd+D",
|
||||
)}`}
|
||||
aria-label={t("labels.duplicateSelection")}
|
||||
onClick={() => updateData(null)}
|
||||
disabled={
|
||||
!isSomeElementSelected(getNonDeletedElements(elements), appState)
|
||||
}
|
||||
style={{
|
||||
...(appState.stylesPanelMode === "mobile" &&
|
||||
appState.openPopup !== "compactOtherProperties"
|
||||
? MOBILE_ACTION_BUTTON_BG
|
||||
: {}),
|
||||
}}
|
||||
/>
|
||||
),
|
||||
});
|
||||
|
||||
@@ -11,7 +11,7 @@ import { CaptureUpdateAction } from "@excalidraw/element";
|
||||
|
||||
import type { Theme } from "@excalidraw/element/types";
|
||||
|
||||
import { useEditorInterface } from "../components/App";
|
||||
import { useDevice } from "../components/App";
|
||||
import { CheckboxItem } from "../components/CheckboxItem";
|
||||
import { DarkModeToggle } from "../components/DarkModeToggle";
|
||||
import { ProjectName } from "../components/ProjectName";
|
||||
@@ -242,7 +242,7 @@ export const actionSaveFileToDisk = register({
|
||||
icon={saveAs}
|
||||
title={t("buttons.saveAs")}
|
||||
aria-label={t("buttons.saveAs")}
|
||||
showAriaLabel={useEditorInterface().formFactor === "phone"}
|
||||
showAriaLabel={useDevice().editor.isMobile}
|
||||
hidden={!nativeFileSystemSupported}
|
||||
onClick={() => updateData(null)}
|
||||
data-testid="save-as-button"
|
||||
|
||||
@@ -18,8 +18,6 @@ import { HistoryChangedEvent } from "../history";
|
||||
import { useEmitter } from "../hooks/useEmitter";
|
||||
import { t } from "../i18n";
|
||||
|
||||
import { useStylesPanelMode } from "..";
|
||||
|
||||
import type { History } from "../history";
|
||||
import type { AppClassProperties, AppState } from "../types";
|
||||
import type { Action, ActionResult } from "./types";
|
||||
@@ -75,7 +73,7 @@ export const createUndoAction: ActionCreator = (history) => ({
|
||||
),
|
||||
keyTest: (event) =>
|
||||
event[KEYS.CTRL_OR_CMD] && matchKey(event, KEYS.Z) && !event.shiftKey,
|
||||
PanelComponent: ({ appState, updateData, data, app }) => {
|
||||
PanelComponent: ({ appState, updateData, data }) => {
|
||||
const { isUndoStackEmpty } = useEmitter<HistoryChangedEvent>(
|
||||
history.onHistoryChangedEmitter,
|
||||
new HistoryChangedEvent(
|
||||
@@ -83,7 +81,6 @@ export const createUndoAction: ActionCreator = (history) => ({
|
||||
history.isRedoStackEmpty,
|
||||
),
|
||||
);
|
||||
const isMobile = useStylesPanelMode() === "mobile";
|
||||
|
||||
return (
|
||||
<ToolButton
|
||||
@@ -95,7 +92,9 @@ export const createUndoAction: ActionCreator = (history) => ({
|
||||
disabled={isUndoStackEmpty}
|
||||
data-testid="button-undo"
|
||||
style={{
|
||||
...(isMobile ? MOBILE_ACTION_BUTTON_BG : {}),
|
||||
...(appState.stylesPanelMode === "mobile"
|
||||
? MOBILE_ACTION_BUTTON_BG
|
||||
: {}),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
@@ -115,7 +114,7 @@ export const createRedoAction: ActionCreator = (history) => ({
|
||||
keyTest: (event) =>
|
||||
(event[KEYS.CTRL_OR_CMD] && event.shiftKey && matchKey(event, KEYS.Z)) ||
|
||||
(isWindows && event.ctrlKey && !event.shiftKey && matchKey(event, KEYS.Y)),
|
||||
PanelComponent: ({ appState, updateData, data, app }) => {
|
||||
PanelComponent: ({ appState, updateData, data }) => {
|
||||
const { isRedoStackEmpty } = useEmitter(
|
||||
history.onHistoryChangedEmitter,
|
||||
new HistoryChangedEvent(
|
||||
@@ -123,7 +122,6 @@ export const createRedoAction: ActionCreator = (history) => ({
|
||||
history.isRedoStackEmpty,
|
||||
),
|
||||
);
|
||||
const isMobile = useStylesPanelMode() === "mobile";
|
||||
|
||||
return (
|
||||
<ToolButton
|
||||
@@ -135,7 +133,9 @@ export const createRedoAction: ActionCreator = (history) => ({
|
||||
disabled={isRedoStackEmpty}
|
||||
data-testid="button-redo"
|
||||
style={{
|
||||
...(isMobile ? MOBILE_ACTION_BUTTON_BG : {}),
|
||||
...(appState.stylesPanelMode === "mobile"
|
||||
? MOBILE_ACTION_BUTTON_BG
|
||||
: {}),
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@@ -145,26 +145,27 @@ describe("element locking", () => {
|
||||
queryByTestId(document.body, `strokeWidth-thin`),
|
||||
).not.toBeChecked();
|
||||
expect(
|
||||
queryByTestId(document.body, `strokeWidth-bold`),
|
||||
queryByTestId(document.body, `strokeWidth-medium`),
|
||||
).not.toBeChecked();
|
||||
expect(
|
||||
queryByTestId(document.body, `strokeWidth-extraBold`),
|
||||
queryByTestId(document.body, `strokeWidth-bold`),
|
||||
).not.toBeChecked();
|
||||
});
|
||||
|
||||
it("should show properties of different element types when selected", () => {
|
||||
const rect = API.createElement({
|
||||
type: "rectangle",
|
||||
strokeWidth: STROKE_WIDTH.bold,
|
||||
strokeWidth: STROKE_WIDTH.medium,
|
||||
});
|
||||
const text = API.createElement({
|
||||
type: "text",
|
||||
fontFamily: FONT_FAMILY["Comic Shanns"],
|
||||
strokeWidth: undefined,
|
||||
});
|
||||
API.setElements([rect, text]);
|
||||
API.setSelectedElements([rect, text]);
|
||||
|
||||
expect(queryByTestId(document.body, `strokeWidth-bold`)).toBeChecked();
|
||||
expect(queryByTestId(document.body, `strokeWidth-medium`)).toBeChecked();
|
||||
expect(queryByTestId(document.body, `font-family-code`)).toHaveClass(
|
||||
"active",
|
||||
);
|
||||
|
||||
@@ -43,6 +43,7 @@ import {
|
||||
isArrowElement,
|
||||
isBoundToContainer,
|
||||
isElbowArrow,
|
||||
isFreeDrawElement,
|
||||
isLinearElement,
|
||||
isLineElement,
|
||||
isTextElement,
|
||||
@@ -57,8 +58,6 @@ import {
|
||||
toggleLinePolygonState,
|
||||
} from "@excalidraw/element";
|
||||
|
||||
import { deriveStylesPanelMode } from "@excalidraw/common";
|
||||
|
||||
import type { LocalPoint } from "@excalidraw/math";
|
||||
|
||||
import type {
|
||||
@@ -82,6 +81,9 @@ import { RadioSelection } from "../components/RadioSelection";
|
||||
import { ColorPicker } from "../components/ColorPicker/ColorPicker";
|
||||
import { FontPicker } from "../components/FontPicker/FontPicker";
|
||||
import { IconPicker } from "../components/IconPicker";
|
||||
// TODO barnabasmolnar/editor-redesign
|
||||
// TextAlignTopIcon, TextAlignBottomIcon,TextAlignMiddleIcon,
|
||||
// ArrowHead icons
|
||||
import { Range } from "../components/Range";
|
||||
import {
|
||||
ArrowheadArrowIcon,
|
||||
@@ -124,6 +126,9 @@ import {
|
||||
ArrowheadCrowfootIcon,
|
||||
ArrowheadCrowfootOneIcon,
|
||||
ArrowheadCrowfootOneOrManyIcon,
|
||||
strokeWidthFixedIcon,
|
||||
strokeWidthVariableIcon,
|
||||
StrokeWidthMediumIcon,
|
||||
} from "../components/icons";
|
||||
|
||||
import { Fonts } from "../fonts";
|
||||
@@ -148,15 +153,6 @@ import type { AppClassProperties, AppState, Primitive } from "../types";
|
||||
|
||||
const FONT_SIZE_RELATIVE_INCREASE_STEP = 0.1;
|
||||
|
||||
const getStylesPanelInfo = (app: AppClassProperties) => {
|
||||
const stylesPanelMode = deriveStylesPanelMode(app.editorInterface);
|
||||
return {
|
||||
stylesPanelMode,
|
||||
isCompact: stylesPanelMode !== "full",
|
||||
isMobile: stylesPanelMode === "mobile",
|
||||
} as const;
|
||||
};
|
||||
|
||||
export const changeProperty = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
@@ -335,35 +331,35 @@ export const actionChangeStrokeColor = register({
|
||||
: CaptureUpdateAction.EVENTUALLY,
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, app, data }) => {
|
||||
const { stylesPanelMode } = getStylesPanelInfo(app);
|
||||
|
||||
return (
|
||||
<>
|
||||
{stylesPanelMode === "full" && (
|
||||
<h3 aria-hidden="true">{t("labels.stroke")}</h3>
|
||||
PanelComponent: ({ elements, appState, updateData, app, data }) => (
|
||||
<>
|
||||
{appState.stylesPanelMode === "full" && (
|
||||
<h3 aria-hidden="true">{t("labels.stroke")}</h3>
|
||||
)}
|
||||
<ColorPicker
|
||||
topPicks={DEFAULT_ELEMENT_STROKE_PICKS}
|
||||
palette={DEFAULT_ELEMENT_STROKE_COLOR_PALETTE}
|
||||
type="elementStroke"
|
||||
label={t("labels.stroke")}
|
||||
color={getFormValue(
|
||||
elements,
|
||||
app,
|
||||
(element) => element.strokeColor,
|
||||
true,
|
||||
(hasSelection) =>
|
||||
!hasSelection ? appState.currentItemStrokeColor : null,
|
||||
)}
|
||||
<ColorPicker
|
||||
topPicks={DEFAULT_ELEMENT_STROKE_PICKS}
|
||||
palette={DEFAULT_ELEMENT_STROKE_COLOR_PALETTE}
|
||||
type="elementStroke"
|
||||
label={t("labels.stroke")}
|
||||
color={getFormValue(
|
||||
elements,
|
||||
app,
|
||||
(element) => element.strokeColor,
|
||||
true,
|
||||
(hasSelection) =>
|
||||
!hasSelection ? appState.currentItemStrokeColor : null,
|
||||
)}
|
||||
onChange={(color) => updateData({ currentItemStrokeColor: color })}
|
||||
elements={elements}
|
||||
appState={appState}
|
||||
updateData={updateData}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
},
|
||||
onChange={(color) => updateData({ currentItemStrokeColor: color })}
|
||||
elements={elements}
|
||||
appState={appState}
|
||||
updateData={updateData}
|
||||
compactMode={
|
||||
appState.stylesPanelMode === "compact" ||
|
||||
appState.stylesPanelMode === "mobile"
|
||||
}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
});
|
||||
|
||||
export const actionChangeBackgroundColor = register({
|
||||
@@ -418,37 +414,35 @@ export const actionChangeBackgroundColor = register({
|
||||
captureUpdate: CaptureUpdateAction.IMMEDIATELY,
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, app, data }) => {
|
||||
const { stylesPanelMode } = getStylesPanelInfo(app);
|
||||
|
||||
return (
|
||||
<>
|
||||
{stylesPanelMode === "full" && (
|
||||
<h3 aria-hidden="true">{t("labels.background")}</h3>
|
||||
PanelComponent: ({ elements, appState, updateData, app, data }) => (
|
||||
<>
|
||||
{appState.stylesPanelMode === "full" && (
|
||||
<h3 aria-hidden="true">{t("labels.background")}</h3>
|
||||
)}
|
||||
<ColorPicker
|
||||
topPicks={DEFAULT_ELEMENT_BACKGROUND_PICKS}
|
||||
palette={DEFAULT_ELEMENT_BACKGROUND_COLOR_PALETTE}
|
||||
type="elementBackground"
|
||||
label={t("labels.background")}
|
||||
color={getFormValue(
|
||||
elements,
|
||||
app,
|
||||
(element) => element.backgroundColor,
|
||||
true,
|
||||
(hasSelection) =>
|
||||
!hasSelection ? appState.currentItemBackgroundColor : null,
|
||||
)}
|
||||
<ColorPicker
|
||||
topPicks={DEFAULT_ELEMENT_BACKGROUND_PICKS}
|
||||
palette={DEFAULT_ELEMENT_BACKGROUND_COLOR_PALETTE}
|
||||
type="elementBackground"
|
||||
label={t("labels.background")}
|
||||
color={getFormValue(
|
||||
elements,
|
||||
app,
|
||||
(element) => element.backgroundColor,
|
||||
true,
|
||||
(hasSelection) =>
|
||||
!hasSelection ? appState.currentItemBackgroundColor : null,
|
||||
)}
|
||||
onChange={(color) =>
|
||||
updateData({ currentItemBackgroundColor: color })
|
||||
}
|
||||
elements={elements}
|
||||
appState={appState}
|
||||
updateData={updateData}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
},
|
||||
onChange={(color) => updateData({ currentItemBackgroundColor: color })}
|
||||
elements={elements}
|
||||
appState={appState}
|
||||
updateData={updateData}
|
||||
compactMode={
|
||||
appState.stylesPanelMode === "compact" ||
|
||||
appState.stylesPanelMode === "mobile"
|
||||
}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
});
|
||||
|
||||
export const actionChangeFillStyle = register({
|
||||
@@ -459,9 +453,7 @@ export const actionChangeFillStyle = register({
|
||||
trackEvent(
|
||||
"element",
|
||||
"changeFillStyle",
|
||||
`${value} (${
|
||||
app.editorInterface.formFactor === "phone" ? "mobile" : "desktop"
|
||||
})`,
|
||||
`${value} (${app.device.editor.isMobile ? "mobile" : "desktop"})`,
|
||||
);
|
||||
return {
|
||||
elements: changeProperty(elements, appState, (el) =>
|
||||
@@ -533,6 +525,33 @@ export const actionChangeFillStyle = register({
|
||||
},
|
||||
});
|
||||
|
||||
const WIDTHS = [
|
||||
{
|
||||
value: STROKE_WIDTH.thin,
|
||||
text: t("labels.thin"),
|
||||
icon: StrokeWidthBaseIcon,
|
||||
testId: "strokeWidth-thin",
|
||||
},
|
||||
{
|
||||
value: STROKE_WIDTH.medium,
|
||||
text: t("labels.medium"),
|
||||
icon: StrokeWidthMediumIcon,
|
||||
testId: "strokeWidth-medium",
|
||||
},
|
||||
{
|
||||
value: STROKE_WIDTH.bold,
|
||||
text: t("labels.bold"),
|
||||
icon: StrokeWidthBoldIcon,
|
||||
testId: "strokeWidth-bold",
|
||||
},
|
||||
{
|
||||
value: STROKE_WIDTH.extraBold,
|
||||
text: t("labels.extraBold"),
|
||||
icon: StrokeWidthExtraBoldIcon,
|
||||
testId: "strokeWidth-extraBold",
|
||||
},
|
||||
];
|
||||
|
||||
export const actionChangeStrokeWidth = register({
|
||||
name: "changeStrokeWidth",
|
||||
label: "labels.strokeWidth",
|
||||
@@ -554,26 +573,7 @@ export const actionChangeStrokeWidth = register({
|
||||
<div className="buttonList">
|
||||
<RadioSelection
|
||||
group="stroke-width"
|
||||
options={[
|
||||
{
|
||||
value: STROKE_WIDTH.thin,
|
||||
text: t("labels.thin"),
|
||||
icon: StrokeWidthBaseIcon,
|
||||
testId: "strokeWidth-thin",
|
||||
},
|
||||
{
|
||||
value: STROKE_WIDTH.bold,
|
||||
text: t("labels.bold"),
|
||||
icon: StrokeWidthBoldIcon,
|
||||
testId: "strokeWidth-bold",
|
||||
},
|
||||
{
|
||||
value: STROKE_WIDTH.extraBold,
|
||||
text: t("labels.extraBold"),
|
||||
icon: StrokeWidthExtraBoldIcon,
|
||||
testId: "strokeWidth-extraBold",
|
||||
},
|
||||
]}
|
||||
options={WIDTHS}
|
||||
value={getFormValue(
|
||||
elements,
|
||||
app,
|
||||
@@ -696,6 +696,70 @@ export const actionChangeStrokeStyle = register({
|
||||
),
|
||||
});
|
||||
|
||||
export const actionChangePressureSensitivity = register({
|
||||
name: "changeStrokeType",
|
||||
label: "labels.strokeType",
|
||||
trackEvent: false,
|
||||
perform: (elements, appState, value) => {
|
||||
const updatedElements = changeProperty(elements, appState, (el) => {
|
||||
if (isFreeDrawElement(el)) {
|
||||
return newElementWith(el, {
|
||||
freedrawOptions: {
|
||||
...el.freedrawOptions,
|
||||
fixedStrokeWidth: value,
|
||||
},
|
||||
});
|
||||
}
|
||||
return el;
|
||||
});
|
||||
|
||||
return {
|
||||
elements: updatedElements,
|
||||
appState: { ...appState, currentItemFixedStrokeWidth: value },
|
||||
captureUpdate: CaptureUpdateAction.IMMEDIATELY,
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ app, appState, updateData }) => {
|
||||
const selectedElements = app.scene.getSelectedElements(app.state);
|
||||
const freedraws = selectedElements.filter(isFreeDrawElement);
|
||||
|
||||
const currentValue =
|
||||
freedraws.length > 0
|
||||
? reduceToCommonValue(
|
||||
freedraws,
|
||||
(element) => element.freedrawOptions?.fixedStrokeWidth,
|
||||
) ?? null
|
||||
: appState.currentItemFixedStrokeWidth;
|
||||
|
||||
return (
|
||||
<fieldset>
|
||||
<legend>{t("labels.strokeType")}</legend>
|
||||
<div className="buttonList">
|
||||
<RadioSelection
|
||||
group="pressure-sensitivity"
|
||||
options={[
|
||||
{
|
||||
value: true,
|
||||
text: t("labels.strokeWidthFixed"),
|
||||
icon: strokeWidthFixedIcon,
|
||||
testId: "pressure-fixed",
|
||||
},
|
||||
{
|
||||
value: false,
|
||||
text: t("labels.strokeWidthVariable"),
|
||||
icon: strokeWidthVariableIcon,
|
||||
testId: "pressure-variable",
|
||||
},
|
||||
]}
|
||||
value={currentValue}
|
||||
onChange={(value) => updateData(value)}
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
);
|
||||
},
|
||||
});
|
||||
|
||||
export const actionChangeOpacity = register({
|
||||
name: "changeOpacity",
|
||||
label: "labels.opacity",
|
||||
@@ -727,81 +791,78 @@ export const actionChangeFontSize = register({
|
||||
perform: (elements, appState, value, app) => {
|
||||
return changeFontSize(elements, appState, app, () => value, value);
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, app, data }) => {
|
||||
const { isCompact } = getStylesPanelInfo(app);
|
||||
|
||||
return (
|
||||
<fieldset>
|
||||
<legend>{t("labels.fontSize")}</legend>
|
||||
<div className="buttonList">
|
||||
<RadioSelection
|
||||
group="font-size"
|
||||
options={[
|
||||
{
|
||||
value: 16,
|
||||
text: t("labels.small"),
|
||||
icon: FontSizeSmallIcon,
|
||||
testId: "fontSize-small",
|
||||
},
|
||||
{
|
||||
value: 20,
|
||||
text: t("labels.medium"),
|
||||
icon: FontSizeMediumIcon,
|
||||
testId: "fontSize-medium",
|
||||
},
|
||||
{
|
||||
value: 28,
|
||||
text: t("labels.large"),
|
||||
icon: FontSizeLargeIcon,
|
||||
testId: "fontSize-large",
|
||||
},
|
||||
{
|
||||
value: 36,
|
||||
text: t("labels.veryLarge"),
|
||||
icon: FontSizeExtraLargeIcon,
|
||||
testId: "fontSize-veryLarge",
|
||||
},
|
||||
]}
|
||||
value={getFormValue(
|
||||
elements,
|
||||
app,
|
||||
(element) => {
|
||||
if (isTextElement(element)) {
|
||||
return element.fontSize;
|
||||
}
|
||||
const boundTextElement = getBoundTextElement(
|
||||
element,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
);
|
||||
if (boundTextElement) {
|
||||
return boundTextElement.fontSize;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
(element) =>
|
||||
isTextElement(element) ||
|
||||
getBoundTextElement(
|
||||
element,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
) !== null,
|
||||
(hasSelection) =>
|
||||
hasSelection
|
||||
? null
|
||||
: appState.currentItemFontSize || DEFAULT_FONT_SIZE,
|
||||
)}
|
||||
onChange={(value) => {
|
||||
withCaretPositionPreservation(
|
||||
() => updateData(value),
|
||||
isCompact,
|
||||
!!appState.editingTextElement,
|
||||
data?.onPreventClose,
|
||||
PanelComponent: ({ elements, appState, updateData, app, data }) => (
|
||||
<fieldset>
|
||||
<legend>{t("labels.fontSize")}</legend>
|
||||
<div className="buttonList">
|
||||
<RadioSelection
|
||||
group="font-size"
|
||||
options={[
|
||||
{
|
||||
value: 16,
|
||||
text: t("labels.small"),
|
||||
icon: FontSizeSmallIcon,
|
||||
testId: "fontSize-small",
|
||||
},
|
||||
{
|
||||
value: 20,
|
||||
text: t("labels.medium"),
|
||||
icon: FontSizeMediumIcon,
|
||||
testId: "fontSize-medium",
|
||||
},
|
||||
{
|
||||
value: 28,
|
||||
text: t("labels.large"),
|
||||
icon: FontSizeLargeIcon,
|
||||
testId: "fontSize-large",
|
||||
},
|
||||
{
|
||||
value: 36,
|
||||
text: t("labels.veryLarge"),
|
||||
icon: FontSizeExtraLargeIcon,
|
||||
testId: "fontSize-veryLarge",
|
||||
},
|
||||
]}
|
||||
value={getFormValue(
|
||||
elements,
|
||||
app,
|
||||
(element) => {
|
||||
if (isTextElement(element)) {
|
||||
return element.fontSize;
|
||||
}
|
||||
const boundTextElement = getBoundTextElement(
|
||||
element,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
);
|
||||
},
|
||||
if (boundTextElement) {
|
||||
return boundTextElement.fontSize;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
(element) =>
|
||||
isTextElement(element) ||
|
||||
getBoundTextElement(
|
||||
element,
|
||||
app.scene.getNonDeletedElementsMap(),
|
||||
) !== null,
|
||||
(hasSelection) =>
|
||||
hasSelection
|
||||
? null
|
||||
: appState.currentItemFontSize || DEFAULT_FONT_SIZE,
|
||||
)}
|
||||
onChange={(value) => {
|
||||
withCaretPositionPreservation(
|
||||
() => updateData(value),
|
||||
appState.stylesPanelMode === "compact" ||
|
||||
appState.stylesPanelMode === "mobile",
|
||||
!!appState.editingTextElement,
|
||||
data?.onPreventClose,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</fieldset>
|
||||
),
|
||||
});
|
||||
|
||||
export const actionDecreaseFontSize = register({
|
||||
@@ -1063,7 +1124,6 @@ export const actionChangeFontFamily = register({
|
||||
// relying on state batching as multiple `FontPicker` handlers could be called in rapid succession and we want to combine them
|
||||
const [batchedData, setBatchedData] = useState<ChangeFontFamilyData>({});
|
||||
const isUnmounted = useRef(true);
|
||||
const { stylesPanelMode, isCompact } = getStylesPanelInfo(app);
|
||||
|
||||
const selectedFontFamily = useMemo(() => {
|
||||
const getFontFamily = (
|
||||
@@ -1136,14 +1196,14 @@ export const actionChangeFontFamily = register({
|
||||
|
||||
return (
|
||||
<>
|
||||
{stylesPanelMode === "full" && (
|
||||
{appState.stylesPanelMode === "full" && (
|
||||
<legend>{t("labels.fontFamily")}</legend>
|
||||
)}
|
||||
<FontPicker
|
||||
isOpened={appState.openPopup === "fontFamily"}
|
||||
selectedFontFamily={selectedFontFamily}
|
||||
hoveredFontFamily={appState.currentHoveredFontFamily}
|
||||
compactMode={stylesPanelMode !== "full"}
|
||||
compactMode={appState.stylesPanelMode !== "full"}
|
||||
onSelect={(fontFamily) => {
|
||||
withCaretPositionPreservation(
|
||||
() => {
|
||||
@@ -1155,7 +1215,8 @@ export const actionChangeFontFamily = register({
|
||||
// defensive clear so immediate close won't abuse the cached elements
|
||||
cachedElementsRef.current.clear();
|
||||
},
|
||||
isCompact,
|
||||
appState.stylesPanelMode === "compact" ||
|
||||
appState.stylesPanelMode === "mobile",
|
||||
!!appState.editingTextElement,
|
||||
);
|
||||
}}
|
||||
@@ -1230,7 +1291,11 @@ export const actionChangeFontFamily = register({
|
||||
cachedElementsRef.current.clear();
|
||||
|
||||
// Refocus text editor when font picker closes if we were editing text
|
||||
if (isCompact && appState.editingTextElement) {
|
||||
if (
|
||||
(appState.stylesPanelMode === "compact" ||
|
||||
appState.stylesPanelMode === "mobile") &&
|
||||
appState.editingTextElement
|
||||
) {
|
||||
restoreCaretPosition(null); // Just refocus without saved position
|
||||
}
|
||||
}
|
||||
@@ -1277,7 +1342,6 @@ export const actionChangeTextAlign = register({
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, app, data }) => {
|
||||
const elementsMap = app.scene.getNonDeletedElementsMap();
|
||||
const { isCompact } = getStylesPanelInfo(app);
|
||||
|
||||
return (
|
||||
<fieldset>
|
||||
@@ -1330,7 +1394,8 @@ export const actionChangeTextAlign = register({
|
||||
onChange={(value) => {
|
||||
withCaretPositionPreservation(
|
||||
() => updateData(value),
|
||||
isCompact,
|
||||
appState.stylesPanelMode === "compact" ||
|
||||
appState.stylesPanelMode === "mobile",
|
||||
!!appState.editingTextElement,
|
||||
data?.onPreventClose,
|
||||
);
|
||||
@@ -1377,7 +1442,6 @@ export const actionChangeVerticalAlign = register({
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, app, data }) => {
|
||||
const { isCompact } = getStylesPanelInfo(app);
|
||||
return (
|
||||
<fieldset>
|
||||
<div className="buttonList">
|
||||
@@ -1430,7 +1494,8 @@ export const actionChangeVerticalAlign = register({
|
||||
onChange={(value) => {
|
||||
withCaretPositionPreservation(
|
||||
() => updateData(value),
|
||||
isCompact,
|
||||
appState.stylesPanelMode === "compact" ||
|
||||
appState.stylesPanelMode === "mobile",
|
||||
!!appState.editingTextElement,
|
||||
data?.onPreventClose,
|
||||
);
|
||||
|
||||
@@ -25,11 +25,8 @@ export const actionToggleZenMode = register({
|
||||
};
|
||||
},
|
||||
checked: (appState) => appState.zenModeEnabled,
|
||||
predicate: (elements, appState, appProps, app) => {
|
||||
return (
|
||||
app.editorInterface.formFactor !== "phone" &&
|
||||
typeof appProps.zenModeEnabled === "undefined"
|
||||
);
|
||||
predicate: (elements, appState, appProps) => {
|
||||
return typeof appProps.zenModeEnabled === "undefined";
|
||||
},
|
||||
keyTest: (event) =>
|
||||
!event[KEYS.CTRL_OR_CMD] && event.altKey && event.code === CODES.Z,
|
||||
|
||||
@@ -13,6 +13,7 @@ export {
|
||||
actionChangeStrokeWidth,
|
||||
actionChangeFillStyle,
|
||||
actionChangeSloppiness,
|
||||
actionChangePressureSensitivity,
|
||||
actionChangeOpacity,
|
||||
actionChangeFontSize,
|
||||
actionChangeFontFamily,
|
||||
|
||||
@@ -37,9 +37,7 @@ const trackAction = (
|
||||
trackEvent(
|
||||
action.trackEvent.category,
|
||||
action.trackEvent.action || action.name,
|
||||
`${source} (${
|
||||
app.editorInterface.formFactor === "phone" ? "mobile" : "desktop"
|
||||
})`,
|
||||
`${source} (${app.device.editor.isMobile ? "mobile" : "desktop"})`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,6 +69,7 @@ export type ActionName =
|
||||
| "changeStrokeStyle"
|
||||
| "changeArrowhead"
|
||||
| "changeArrowType"
|
||||
| "changeStrokeType"
|
||||
| "changeArrowProperties"
|
||||
| "changeOpacity"
|
||||
| "changeFontSize"
|
||||
|
||||
@@ -34,6 +34,7 @@ export const getDefaultAppState = (): Omit<
|
||||
currentItemFontFamily: DEFAULT_FONT_FAMILY,
|
||||
currentItemFontSize: DEFAULT_FONT_SIZE,
|
||||
currentItemOpacity: DEFAULT_ELEMENT_PROPS.opacity,
|
||||
currentItemFixedStrokeWidth: true,
|
||||
currentItemRoughness: DEFAULT_ELEMENT_PROPS.roughness,
|
||||
currentItemStartArrowhead: null,
|
||||
currentItemStrokeColor: DEFAULT_ELEMENT_PROPS.strokeColor,
|
||||
@@ -127,6 +128,7 @@ export const getDefaultAppState = (): Omit<
|
||||
searchMatches: null,
|
||||
lockedMultiSelections: {},
|
||||
activeLockedId: null,
|
||||
stylesPanelMode: "full",
|
||||
};
|
||||
};
|
||||
|
||||
@@ -166,6 +168,11 @@ const APP_STATE_STORAGE_CONF = (<
|
||||
server: false,
|
||||
},
|
||||
currentItemOpacity: { browser: true, export: false, server: false },
|
||||
currentItemFixedStrokeWidth: {
|
||||
browser: true,
|
||||
export: false,
|
||||
server: false,
|
||||
},
|
||||
currentItemRoughness: { browser: true, export: false, server: false },
|
||||
currentItemStartArrowhead: { browser: true, export: false, server: false },
|
||||
currentItemStrokeColor: { browser: true, export: false, server: false },
|
||||
@@ -252,6 +259,7 @@ const APP_STATE_STORAGE_CONF = (<
|
||||
searchMatches: { browser: false, export: false, server: false },
|
||||
lockedMultiSelections: { browser: true, export: true, server: true },
|
||||
activeLockedId: { browser: false, export: false, server: false },
|
||||
stylesPanelMode: { browser: false, export: false, server: false },
|
||||
});
|
||||
|
||||
const _clearAppStateForStorage = <
|
||||
|
||||
@@ -49,17 +49,11 @@ import { getFormValue } from "../actions/actionProperties";
|
||||
|
||||
import { useTextEditorFocus } from "../hooks/useTextEditorFocus";
|
||||
|
||||
import { actionToggleViewMode } from "../actions/actionToggleViewMode";
|
||||
|
||||
import { getToolbarTools } from "./shapes";
|
||||
|
||||
import "./Actions.scss";
|
||||
|
||||
import {
|
||||
useEditorInterface,
|
||||
useStylesPanelMode,
|
||||
useExcalidrawContainer,
|
||||
} from "./App";
|
||||
import { useDevice, useExcalidrawContainer } from "./App";
|
||||
import Stack from "./Stack";
|
||||
import { ToolButton } from "./ToolButton";
|
||||
import { ToolPopover } from "./ToolPopover";
|
||||
@@ -81,7 +75,6 @@ import {
|
||||
adjustmentsIcon,
|
||||
DotsHorizontalIcon,
|
||||
SelectionIcon,
|
||||
pencilIcon,
|
||||
} from "./icons";
|
||||
|
||||
import { Island } from "./Island";
|
||||
@@ -158,7 +151,7 @@ export const SelectedShapeActions = ({
|
||||
const isEditingTextOrNewElement = Boolean(
|
||||
appState.editingTextElement || appState.newElement,
|
||||
);
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
const isRTL = document.documentElement.getAttribute("dir") === "rtl";
|
||||
|
||||
const showFillIcons =
|
||||
@@ -202,8 +195,12 @@ export const SelectedShapeActions = ({
|
||||
renderAction("changeStrokeWidth")}
|
||||
|
||||
{(appState.activeTool.type === "freedraw" ||
|
||||
targetElements.some((element) => element.type === "freedraw")) &&
|
||||
renderAction("changeStrokeShape")}
|
||||
targetElements.some((element) => element.type === "freedraw")) && (
|
||||
<>
|
||||
{renderAction("changeStrokeShape")}
|
||||
{renderAction("changeStrokeType")}
|
||||
</>
|
||||
)}
|
||||
|
||||
{(hasStrokeStyle(appState.activeTool.type) ||
|
||||
targetElements.some((element) => hasStrokeStyle(element.type))) && (
|
||||
@@ -299,10 +296,8 @@ export const SelectedShapeActions = ({
|
||||
<fieldset>
|
||||
<legend>{t("labels.actions")}</legend>
|
||||
<div className="buttonList">
|
||||
{editorInterface.formFactor !== "phone" &&
|
||||
renderAction("duplicateSelection")}
|
||||
{editorInterface.formFactor !== "phone" &&
|
||||
renderAction("deleteSelectedElements")}
|
||||
{!device.editor.isMobile && renderAction("duplicateSelection")}
|
||||
{!device.editor.isMobile && renderAction("deleteSelectedElements")}
|
||||
{renderAction("group")}
|
||||
{renderAction("ungroup")}
|
||||
{showLinkIcon && renderAction("hyperlink")}
|
||||
@@ -1050,9 +1045,6 @@ export const ShapesSwitcher = ({
|
||||
UIOptions: AppProps["UIOptions"];
|
||||
}) => {
|
||||
const [isExtraToolsMenuOpen, setIsExtraToolsMenuOpen] = useState(false);
|
||||
const stylesPanelMode = useStylesPanelMode();
|
||||
const isFullStylesPanel = stylesPanelMode === "full";
|
||||
const isCompactStylesPanel = stylesPanelMode === "compact";
|
||||
|
||||
const SELECTION_TOOLS = [
|
||||
{
|
||||
@@ -1070,7 +1062,7 @@ export const ShapesSwitcher = ({
|
||||
const frameToolSelected = activeTool.type === "frame";
|
||||
const laserToolSelected = activeTool.type === "laser";
|
||||
const lassoToolSelected =
|
||||
isFullStylesPanel &&
|
||||
app.state.stylesPanelMode === "full" &&
|
||||
activeTool.type === "lasso" &&
|
||||
app.state.preferredSelectionTool.type !== "lasso";
|
||||
|
||||
@@ -1103,7 +1095,7 @@ export const ShapesSwitcher = ({
|
||||
// use a ToolPopover for selection/lasso toggle as well
|
||||
if (
|
||||
(value === "selection" || value === "lasso") &&
|
||||
isCompactStylesPanel
|
||||
app.state.stylesPanelMode === "compact"
|
||||
) {
|
||||
return (
|
||||
<ToolPopover
|
||||
@@ -1237,7 +1229,7 @@ export const ShapesSwitcher = ({
|
||||
>
|
||||
{t("toolBar.laser")}
|
||||
</DropdownMenu.Item>
|
||||
{isFullStylesPanel && (
|
||||
{app.state.stylesPanelMode === "full" && (
|
||||
<DropdownMenu.Item
|
||||
onSelect={() => app.setActiveTool({ type: "lasso" })}
|
||||
icon={LassoIcon}
|
||||
@@ -1307,7 +1299,7 @@ export const UndoRedoActions = ({
|
||||
</div>
|
||||
);
|
||||
|
||||
export const ExitZenModeButton = ({
|
||||
export const ExitZenModeAction = ({
|
||||
actionManager,
|
||||
showExitZenModeBtn,
|
||||
}: {
|
||||
@@ -1324,17 +1316,3 @@ export const ExitZenModeButton = ({
|
||||
{t("buttons.exitZenMode")}
|
||||
</button>
|
||||
);
|
||||
|
||||
export const ExitViewModeButton = ({
|
||||
actionManager,
|
||||
}: {
|
||||
actionManager: ActionManager;
|
||||
}) => (
|
||||
<button
|
||||
type="button"
|
||||
className="disable-view-mode"
|
||||
onClick={() => actionManager.executeAction(actionToggleViewMode)}
|
||||
>
|
||||
{pencilIcon}
|
||||
</button>
|
||||
);
|
||||
|
||||
@@ -37,6 +37,7 @@ import {
|
||||
FRAME_STYLE,
|
||||
IMAGE_MIME_TYPES,
|
||||
IMAGE_RENDER_TIMEOUT,
|
||||
isBrave,
|
||||
LINE_CONFIRM_THRESHOLD,
|
||||
MAX_ALLOWED_FILE_BYTES,
|
||||
MIME_TYPES,
|
||||
@@ -54,11 +55,13 @@ import {
|
||||
ZOOM_STEP,
|
||||
POINTER_EVENTS,
|
||||
TOOL_TYPE,
|
||||
isIOS,
|
||||
supportsResizeObserver,
|
||||
DEFAULT_COLLISION_THRESHOLD,
|
||||
DEFAULT_TEXT_ALIGN,
|
||||
ARROW_TYPE,
|
||||
DEFAULT_REDUCED_GLOBAL_ALPHA,
|
||||
isSafari,
|
||||
isLocalLink,
|
||||
normalizeLink,
|
||||
toValidURL,
|
||||
@@ -95,16 +98,12 @@ import {
|
||||
Emitter,
|
||||
MINIMUM_ARROW_SIZE,
|
||||
DOUBLE_TAP_POSITION_THRESHOLD,
|
||||
createUserAgentDescriptor,
|
||||
getFormFactor,
|
||||
deriveStylesPanelMode,
|
||||
isIOS,
|
||||
isBrave,
|
||||
isSafari,
|
||||
type EditorInterface,
|
||||
type StylesPanelMode,
|
||||
loadDesktopUIModePreference,
|
||||
setDesktopUIMode,
|
||||
isMobileOrTablet,
|
||||
MQ_MAX_MOBILE,
|
||||
MQ_MIN_TABLET,
|
||||
MQ_MAX_TABLET,
|
||||
MQ_MAX_HEIGHT_LANDSCAPE,
|
||||
MQ_MAX_WIDTH_LANDSCAPE,
|
||||
} from "@excalidraw/common";
|
||||
|
||||
import {
|
||||
@@ -237,6 +236,8 @@ import {
|
||||
hitElementBoundingBox,
|
||||
isLineElement,
|
||||
isSimpleArrow,
|
||||
STROKE_OPTIONS,
|
||||
getFreedrawConfig,
|
||||
StoreDelta,
|
||||
type ApplyToOptions,
|
||||
positionElementsOnGrid,
|
||||
@@ -461,6 +462,7 @@ import type {
|
||||
LibraryItems,
|
||||
PointerDownState,
|
||||
SceneData,
|
||||
Device,
|
||||
FrameNameBoundsCache,
|
||||
SidebarName,
|
||||
SidebarTabName,
|
||||
@@ -481,20 +483,19 @@ import type { Action, ActionResult } from "../actions/types";
|
||||
const AppContext = React.createContext<AppClassProperties>(null!);
|
||||
const AppPropsContext = React.createContext<AppProps>(null!);
|
||||
|
||||
const editorInterfaceContextInitialValue: EditorInterface = {
|
||||
formFactor: "desktop",
|
||||
desktopUIMode: "full",
|
||||
userAgent: createUserAgentDescriptor(
|
||||
typeof navigator !== "undefined" ? navigator.userAgent : "",
|
||||
),
|
||||
const deviceContextInitialValue = {
|
||||
viewport: {
|
||||
isMobile: false,
|
||||
isLandscape: false,
|
||||
},
|
||||
editor: {
|
||||
isMobile: false,
|
||||
canFitSidebar: false,
|
||||
},
|
||||
isTouchScreen: false,
|
||||
canFitSidebar: false,
|
||||
isLandscape: true,
|
||||
};
|
||||
const EditorInterfaceContext = React.createContext<EditorInterface>(
|
||||
editorInterfaceContextInitialValue,
|
||||
);
|
||||
EditorInterfaceContext.displayName = "EditorInterfaceContext";
|
||||
const DeviceContext = React.createContext<Device>(deviceContextInitialValue);
|
||||
DeviceContext.displayName = "DeviceContext";
|
||||
|
||||
export const ExcalidrawContainerContext = React.createContext<{
|
||||
container: HTMLDivElement | null;
|
||||
@@ -530,10 +531,7 @@ ExcalidrawActionManagerContext.displayName = "ExcalidrawActionManagerContext";
|
||||
|
||||
export const useApp = () => useContext(AppContext);
|
||||
export const useAppProps = () => useContext(AppPropsContext);
|
||||
export const useEditorInterface = () =>
|
||||
useContext<EditorInterface>(EditorInterfaceContext);
|
||||
export const useStylesPanelMode = () =>
|
||||
deriveStylesPanelMode(useEditorInterface());
|
||||
export const useDevice = () => useContext<Device>(DeviceContext);
|
||||
export const useExcalidrawContainer = () =>
|
||||
useContext(ExcalidrawContainerContext);
|
||||
export const useExcalidrawElements = () =>
|
||||
@@ -581,10 +579,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
rc: RoughCanvas;
|
||||
unmounted: boolean = false;
|
||||
actionManager: ActionManager;
|
||||
editorInterface: EditorInterface = editorInterfaceContextInitialValue;
|
||||
private stylesPanelMode: StylesPanelMode = deriveStylesPanelMode(
|
||||
editorInterfaceContextInitialValue,
|
||||
);
|
||||
device: Device = deviceContextInitialValue;
|
||||
|
||||
private excalidrawContainerRef = React.createRef<HTMLDivElement>();
|
||||
|
||||
@@ -700,9 +695,6 @@ class App extends React.Component<AppProps, AppState> {
|
||||
height: window.innerHeight,
|
||||
};
|
||||
|
||||
this.refreshEditorInterface();
|
||||
this.stylesPanelMode = deriveStylesPanelMode(this.editorInterface);
|
||||
|
||||
this.id = nanoid();
|
||||
this.library = new Library(this);
|
||||
this.actionManager = new ActionManager(
|
||||
@@ -749,7 +741,6 @@ class App extends React.Component<AppProps, AppState> {
|
||||
setActiveTool: this.setActiveTool,
|
||||
setCursor: this.setCursor,
|
||||
resetCursor: this.resetCursor,
|
||||
getEditorInterface: () => this.editorInterface,
|
||||
updateFrameRendering: this.updateFrameRendering,
|
||||
toggleSidebar: this.toggleSidebar,
|
||||
onChange: (cb) => this.onChangeEmitter.on(cb),
|
||||
@@ -1476,7 +1467,6 @@ class App extends React.Component<AppProps, AppState> {
|
||||
return (
|
||||
<div
|
||||
id={this.getFrameNameDOMId(f)}
|
||||
className={CLASSES.FRAME_NAME}
|
||||
key={f.id}
|
||||
style={{
|
||||
position: "absolute",
|
||||
@@ -1579,7 +1569,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
"excalidraw--view-mode":
|
||||
this.state.viewModeEnabled ||
|
||||
this.state.openDialog?.name === "elementLinkSelector",
|
||||
"excalidraw--mobile": this.editorInterface.formFactor === "phone",
|
||||
"excalidraw--mobile": this.device.editor.isMobile,
|
||||
})}
|
||||
style={{
|
||||
["--ui-pointerEvents" as any]: shouldBlockPointerEvents
|
||||
@@ -1601,7 +1591,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
<ExcalidrawContainerContext.Provider
|
||||
value={this.excalidrawContainerValue}
|
||||
>
|
||||
<EditorInterfaceContext.Provider value={this.editorInterface}>
|
||||
<DeviceContext.Provider value={this.device}>
|
||||
<ExcalidrawSetAppStateContext.Provider value={this.setAppState}>
|
||||
<ExcalidrawAppStateContext.Provider value={this.state}>
|
||||
<ExcalidrawElementsContext.Provider
|
||||
@@ -1814,7 +1804,6 @@ class App extends React.Component<AppProps, AppState> {
|
||||
/>
|
||||
)}
|
||||
<InteractiveCanvas
|
||||
app={this}
|
||||
containerRef={this.excalidrawContainerRef}
|
||||
canvas={this.interactiveCanvas}
|
||||
elementsMap={elementsMap}
|
||||
@@ -1830,7 +1819,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
renderScrollbars={
|
||||
this.props.renderScrollbars === true
|
||||
}
|
||||
editorInterface={this.editorInterface}
|
||||
device={this.device}
|
||||
renderInteractiveSceneCallback={
|
||||
this.renderInteractiveSceneCallback
|
||||
}
|
||||
@@ -1866,7 +1855,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
</ExcalidrawElementsContext.Provider>
|
||||
</ExcalidrawAppStateContext.Provider>
|
||||
</ExcalidrawSetAppStateContext.Provider>
|
||||
</EditorInterfaceContext.Provider>
|
||||
</DeviceContext.Provider>
|
||||
</ExcalidrawContainerContext.Provider>
|
||||
</AppPropsContext.Provider>
|
||||
</AppContext.Provider>
|
||||
@@ -2383,8 +2372,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
|
||||
if (!scene.appState.preferredSelectionTool.initialized) {
|
||||
scene.appState.preferredSelectionTool = {
|
||||
type:
|
||||
this.editorInterface.formFactor === "phone" ? "lasso" : "selection",
|
||||
type: this.device.editor.isMobile ? "lasso" : "selection",
|
||||
initialized: true,
|
||||
};
|
||||
}
|
||||
@@ -2444,14 +2432,44 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}
|
||||
};
|
||||
|
||||
private getFormFactor = (editorWidth: number, editorHeight: number) => {
|
||||
private isMobileBreakpoint = (width: number, height: number) => {
|
||||
return (
|
||||
this.props.UIOptions.formFactor ??
|
||||
getFormFactor(editorWidth, editorHeight)
|
||||
width <= MQ_MAX_MOBILE ||
|
||||
(height < MQ_MAX_HEIGHT_LANDSCAPE && width < MQ_MAX_WIDTH_LANDSCAPE)
|
||||
);
|
||||
};
|
||||
|
||||
public refreshEditorInterface = () => {
|
||||
private isTabletBreakpoint = (editorWidth: number, editorHeight: number) => {
|
||||
const minSide = Math.min(editorWidth, editorHeight);
|
||||
const maxSide = Math.max(editorWidth, editorHeight);
|
||||
|
||||
return minSide >= MQ_MIN_TABLET && maxSide <= MQ_MAX_TABLET;
|
||||
};
|
||||
|
||||
private refreshViewportBreakpoints = () => {
|
||||
const container = this.excalidrawContainerRef.current;
|
||||
if (!container) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { width: editorWidth, height: editorHeight } =
|
||||
container.getBoundingClientRect();
|
||||
|
||||
const prevViewportState = this.device.viewport;
|
||||
|
||||
const nextViewportState = updateObject(prevViewportState, {
|
||||
isLandscape: editorWidth > editorHeight,
|
||||
isMobile: this.isMobileBreakpoint(editorWidth, editorHeight),
|
||||
});
|
||||
|
||||
if (prevViewportState !== nextViewportState) {
|
||||
this.device = { ...this.device, viewport: nextViewportState };
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
private refreshEditorBreakpoints = () => {
|
||||
const container = this.excalidrawContainerRef.current;
|
||||
if (!container) {
|
||||
return;
|
||||
@@ -2460,56 +2478,47 @@ class App extends React.Component<AppProps, AppState> {
|
||||
const { width: editorWidth, height: editorHeight } =
|
||||
container.getBoundingClientRect();
|
||||
|
||||
const storedDesktopUIMode = loadDesktopUIModePreference();
|
||||
const userAgentDescriptor = createUserAgentDescriptor(
|
||||
typeof navigator !== "undefined" ? navigator.userAgent : "",
|
||||
);
|
||||
// allow host app to control formFactor and desktopUIMode via props
|
||||
const sidebarBreakpoint =
|
||||
this.props.UIOptions.dockedSidebarBreakpoint != null
|
||||
? this.props.UIOptions.dockedSidebarBreakpoint
|
||||
: MQ_RIGHT_SIDEBAR_MIN_WIDTH;
|
||||
const nextEditorInterface = updateObject(this.editorInterface, {
|
||||
desktopUIMode:
|
||||
this.props.UIOptions.desktopUIMode ??
|
||||
storedDesktopUIMode ??
|
||||
this.editorInterface.desktopUIMode,
|
||||
formFactor: this.getFormFactor(editorWidth, editorHeight),
|
||||
userAgent: userAgentDescriptor,
|
||||
|
||||
const prevEditorState = this.device.editor;
|
||||
|
||||
const nextEditorState = updateObject(prevEditorState, {
|
||||
isMobile: this.isMobileBreakpoint(editorWidth, editorHeight),
|
||||
canFitSidebar: editorWidth > sidebarBreakpoint,
|
||||
isLandscape: editorWidth > editorHeight,
|
||||
});
|
||||
|
||||
this.editorInterface = nextEditorInterface;
|
||||
this.reconcileStylesPanelMode(nextEditorInterface);
|
||||
};
|
||||
const stylesPanelMode =
|
||||
// NOTE: we could also remove the isMobileOrTablet check here and
|
||||
// always switch to compact mode when the editor is narrow (e.g. < MQ_MIN_WIDTH_DESKTOP)
|
||||
// but not too narrow (> MQ_MAX_WIDTH_MOBILE)
|
||||
this.isTabletBreakpoint(editorWidth, editorHeight) && isMobileOrTablet()
|
||||
? "compact"
|
||||
: this.isMobileBreakpoint(editorWidth, editorHeight)
|
||||
? "mobile"
|
||||
: "full";
|
||||
|
||||
private reconcileStylesPanelMode = (nextEditorInterface: EditorInterface) => {
|
||||
const nextStylesPanelMode = deriveStylesPanelMode(nextEditorInterface);
|
||||
if (nextStylesPanelMode === this.stylesPanelMode) {
|
||||
return;
|
||||
// also check if we need to update the app state
|
||||
this.setState((prevState) => ({
|
||||
stylesPanelMode,
|
||||
// reset to box selection mode if the UI changes to full
|
||||
// where you'd not be able to change the mode yourself currently
|
||||
preferredSelectionTool:
|
||||
stylesPanelMode === "full"
|
||||
? {
|
||||
type: "selection",
|
||||
initialized: true,
|
||||
}
|
||||
: prevState.preferredSelectionTool,
|
||||
}));
|
||||
|
||||
if (prevEditorState !== nextEditorState) {
|
||||
this.device = { ...this.device, editor: nextEditorState };
|
||||
return true;
|
||||
}
|
||||
|
||||
const prevStylesPanelMode = this.stylesPanelMode;
|
||||
this.stylesPanelMode = nextStylesPanelMode;
|
||||
|
||||
if (prevStylesPanelMode !== "full" && nextStylesPanelMode === "full") {
|
||||
this.setState((prevState) => ({
|
||||
preferredSelectionTool: {
|
||||
type: "selection",
|
||||
initialized: true,
|
||||
},
|
||||
}));
|
||||
}
|
||||
};
|
||||
|
||||
/** TO BE USED LATER */
|
||||
private setDesktopUIMode = (mode: EditorInterface["desktopUIMode"]) => {
|
||||
const nextMode = setDesktopUIMode(mode);
|
||||
this.editorInterface = updateObject(this.editorInterface, {
|
||||
desktopUIMode: nextMode,
|
||||
});
|
||||
this.reconcileStylesPanelMode(this.editorInterface);
|
||||
return false;
|
||||
};
|
||||
|
||||
private clearImageShapeCache(filesMap?: BinaryFiles) {
|
||||
@@ -2581,9 +2590,19 @@ class App extends React.Component<AppProps, AppState> {
|
||||
this.focusContainer();
|
||||
}
|
||||
|
||||
if (
|
||||
// bounding rects don't work in tests so updating
|
||||
// the state on init would result in making the test enviro run
|
||||
// in mobile breakpoint (0 width/height), making everything fail
|
||||
!isTestEnv()
|
||||
) {
|
||||
this.refreshViewportBreakpoints();
|
||||
this.refreshEditorBreakpoints();
|
||||
}
|
||||
|
||||
if (supportsResizeObserver && this.excalidrawContainerRef.current) {
|
||||
this.resizeObserver = new ResizeObserver(() => {
|
||||
this.refreshEditorInterface();
|
||||
this.refreshEditorBreakpoints();
|
||||
this.updateDOMRect();
|
||||
});
|
||||
this.resizeObserver?.observe(this.excalidrawContainerRef.current);
|
||||
@@ -2637,8 +2656,11 @@ class App extends React.Component<AppProps, AppState> {
|
||||
this.scene
|
||||
.getElementsIncludingDeleted()
|
||||
.forEach((element) => ShapeCache.delete(element));
|
||||
this.refreshEditorInterface();
|
||||
this.refreshViewportBreakpoints();
|
||||
this.updateDOMRect();
|
||||
if (!supportsResizeObserver) {
|
||||
this.refreshEditorBreakpoints();
|
||||
}
|
||||
this.setState({});
|
||||
});
|
||||
|
||||
@@ -2797,6 +2819,13 @@ class App extends React.Component<AppProps, AppState> {
|
||||
this.setState({ showWelcomeScreen: true });
|
||||
}
|
||||
|
||||
if (
|
||||
prevProps.UIOptions.dockedSidebarBreakpoint !==
|
||||
this.props.UIOptions.dockedSidebarBreakpoint
|
||||
) {
|
||||
this.refreshEditorBreakpoints();
|
||||
}
|
||||
|
||||
const hasFollowedPersonLeft =
|
||||
prevState.userToFollow &&
|
||||
!this.state.collaborators.has(prevState.userToFollow.socketId);
|
||||
@@ -3151,8 +3180,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
this.addElementsFromPasteOrLibrary({
|
||||
elements,
|
||||
files: data.files || null,
|
||||
position:
|
||||
this.editorInterface.formFactor === "desktop" ? "cursor" : "center",
|
||||
position: isMobileOrTablet() ? "center" : "cursor",
|
||||
retainSeed: isPlainPaste,
|
||||
});
|
||||
return;
|
||||
@@ -3177,8 +3205,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
this.addElementsFromPasteOrLibrary({
|
||||
elements,
|
||||
files,
|
||||
position:
|
||||
this.editorInterface.formFactor === "desktop" ? "cursor" : "center",
|
||||
position: isMobileOrTablet() ? "center" : "cursor",
|
||||
});
|
||||
|
||||
return;
|
||||
@@ -3404,7 +3431,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
// from library, not when pasting from clipboard. Alas.
|
||||
openSidebar:
|
||||
this.state.openSidebar &&
|
||||
this.editorInterface.canFitSidebar &&
|
||||
this.device.editor.canFitSidebar &&
|
||||
editorJotaiStore.get(isSidebarDockedAtom)
|
||||
? this.state.openSidebar
|
||||
: null,
|
||||
@@ -3602,7 +3629,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
!isPlainPaste &&
|
||||
textElements.length > 1 &&
|
||||
PLAIN_PASTE_TOAST_SHOWN === false &&
|
||||
this.editorInterface.formFactor !== "phone"
|
||||
!this.device.editor.isMobile
|
||||
) {
|
||||
this.setToast({
|
||||
message: t("toast.pasteAsSingleElement", {
|
||||
@@ -3634,9 +3661,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
trackEvent(
|
||||
"toolbar",
|
||||
"toggleLock",
|
||||
`${source} (${
|
||||
this.editorInterface.formFactor === "phone" ? "mobile" : "desktop"
|
||||
})`,
|
||||
`${source} (${this.device.editor.isMobile ? "mobile" : "desktop"})`,
|
||||
);
|
||||
}
|
||||
this.setState((prevState) => {
|
||||
@@ -3988,7 +4013,12 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}
|
||||
|
||||
if (appState) {
|
||||
this.setState(appState as Pick<AppState, K> | null);
|
||||
this.setState({
|
||||
...appState,
|
||||
// keep existing stylesPanelMode as it needs to be preserved
|
||||
// or set at startup
|
||||
stylesPanelMode: this.state.stylesPanelMode,
|
||||
} as Pick<AppState, K> | null);
|
||||
}
|
||||
|
||||
if (elements) {
|
||||
@@ -4566,9 +4596,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
"toolbar",
|
||||
shape,
|
||||
`keyboard (${
|
||||
this.editorInterface.formFactor === "phone"
|
||||
? "mobile"
|
||||
: "desktop"
|
||||
this.device.editor.isMobile ? "mobile" : "desktop"
|
||||
})`,
|
||||
);
|
||||
}
|
||||
@@ -5074,7 +5102,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
// caret (i.e. deselect). There's not much use for always selecting
|
||||
// the text on edit anyway (and users can select-all from contextmenu
|
||||
// if needed)
|
||||
autoSelect: !this.editorInterface.isTouchScreen,
|
||||
autoSelect: !this.device.isTouchScreen,
|
||||
});
|
||||
// deselect all other elements when inserting text
|
||||
this.deselectElements();
|
||||
@@ -5237,7 +5265,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
if (
|
||||
considerBoundingBox &&
|
||||
this.state.selectedElementIds[element.id] &&
|
||||
hasBoundingBox([element], this.state, this.editorInterface)
|
||||
hasBoundingBox([element], this.state)
|
||||
) {
|
||||
// if hitting the bounding box, return early
|
||||
// but if not, we should check for other cases as well (e.g. frame name)
|
||||
@@ -5707,7 +5735,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
this.scene.getNonDeletedElementsMap(),
|
||||
this.state,
|
||||
pointFrom(scenePointer.x, scenePointer.y),
|
||||
this.editorInterface.formFactor === "phone",
|
||||
this.device.editor.isMobile,
|
||||
)
|
||||
) {
|
||||
return element;
|
||||
@@ -5742,7 +5770,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
elementsMap,
|
||||
this.state,
|
||||
pointFrom(lastPointerDownCoords.x, lastPointerDownCoords.y),
|
||||
this.editorInterface.formFactor === "phone",
|
||||
this.device.editor.isMobile,
|
||||
);
|
||||
const lastPointerUpCoords = viewportCoordsToSceneCoords(
|
||||
this.lastPointerUpEvent!,
|
||||
@@ -5753,7 +5781,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
elementsMap,
|
||||
this.state,
|
||||
pointFrom(lastPointerUpCoords.x, lastPointerUpCoords.y),
|
||||
this.editorInterface.formFactor === "phone",
|
||||
this.device.editor.isMobile,
|
||||
);
|
||||
if (lastPointerDownHittingLinkIcon && lastPointerUpHittingLinkIcon) {
|
||||
hideHyperlinkToolip();
|
||||
@@ -6145,8 +6173,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
// better way of showing them is found
|
||||
!(
|
||||
isLinearElement(selectedElements[0]) &&
|
||||
(this.editorInterface.userAgent.isMobileDevice ||
|
||||
selectedElements[0].points.length === 2)
|
||||
(isMobileOrTablet() || selectedElements[0].points.length === 2)
|
||||
)
|
||||
) {
|
||||
const elementWithTransformHandleType =
|
||||
@@ -6158,7 +6185,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
this.state.zoom,
|
||||
event.pointerType,
|
||||
this.scene.getNonDeletedElementsMap(),
|
||||
this.editorInterface,
|
||||
this.device,
|
||||
);
|
||||
if (
|
||||
elementWithTransformHandleType &&
|
||||
@@ -6182,7 +6209,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
scenePointerY,
|
||||
this.state.zoom,
|
||||
event.pointerType,
|
||||
this.editorInterface,
|
||||
this.device,
|
||||
);
|
||||
if (transformHandleType) {
|
||||
setCursor(
|
||||
@@ -6568,12 +6595,10 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}
|
||||
|
||||
if (
|
||||
!this.editorInterface.isTouchScreen &&
|
||||
!this.device.isTouchScreen &&
|
||||
["pen", "touch"].includes(event.pointerType)
|
||||
) {
|
||||
this.editorInterface = updateObject(this.editorInterface, {
|
||||
isTouchScreen: true,
|
||||
});
|
||||
this.device = updateObject(this.device, { isTouchScreen: true });
|
||||
}
|
||||
|
||||
if (isPanning) {
|
||||
@@ -6707,13 +6732,12 @@ class App extends React.Component<AppProps, AppState> {
|
||||
|
||||
// block dragging after lasso selection on PCs until the next pointer down
|
||||
// (on mobile or tablet, we want to allow user to drag immediately)
|
||||
pointerDownState.drag.blockDragging =
|
||||
this.editorInterface.formFactor === "desktop";
|
||||
pointerDownState.drag.blockDragging = !isMobileOrTablet();
|
||||
}
|
||||
|
||||
// only for mobile or tablet, if we hit an element, select it immediately like normal selection
|
||||
if (
|
||||
this.editorInterface.formFactor !== "desktop" &&
|
||||
isMobileOrTablet() &&
|
||||
pointerDownState.hit.element &&
|
||||
!hitSelectedElement
|
||||
) {
|
||||
@@ -6897,7 +6921,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
const clicklength =
|
||||
event.timeStamp - (this.lastPointerDownEvent?.timeStamp ?? 0);
|
||||
|
||||
if (this.editorInterface.formFactor === "phone" && clicklength < 300) {
|
||||
if (this.device.editor.isMobile && clicklength < 300) {
|
||||
const hitElement = this.getElementAtPosition(
|
||||
scenePointer.x,
|
||||
scenePointer.y,
|
||||
@@ -6916,7 +6940,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.editorInterface.isTouchScreen) {
|
||||
if (this.device.isTouchScreen) {
|
||||
const hitElement = this.getElementAtPosition(
|
||||
scenePointer.x,
|
||||
scenePointer.y,
|
||||
@@ -6946,7 +6970,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
) {
|
||||
this.handleEmbeddableCenterClick(this.hitLinkElement);
|
||||
} else {
|
||||
this.redirectToLink(event, this.editorInterface.isTouchScreen);
|
||||
this.redirectToLink(event, this.device.isTouchScreen);
|
||||
}
|
||||
} else if (this.state.viewModeEnabled) {
|
||||
this.setState({
|
||||
@@ -7271,8 +7295,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
!isElbowArrow(selectedElements[0]) &&
|
||||
!(
|
||||
isLinearElement(selectedElements[0]) &&
|
||||
(this.editorInterface.userAgent.isMobileDevice ||
|
||||
selectedElements[0].points.length === 2)
|
||||
(isMobileOrTablet() || selectedElements[0].points.length === 2)
|
||||
) &&
|
||||
!(
|
||||
this.state.selectedLinearElement &&
|
||||
@@ -7288,7 +7311,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
this.state.zoom,
|
||||
event.pointerType,
|
||||
this.scene.getNonDeletedElementsMap(),
|
||||
this.editorInterface,
|
||||
this.device,
|
||||
);
|
||||
if (elementWithTransformHandleType != null) {
|
||||
if (
|
||||
@@ -7317,7 +7340,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
pointerDownState.origin.y,
|
||||
this.state.zoom,
|
||||
event.pointerType,
|
||||
this.editorInterface,
|
||||
this.device,
|
||||
);
|
||||
}
|
||||
if (pointerDownState.resize.handleType) {
|
||||
@@ -7728,7 +7751,12 @@ class App extends React.Component<AppProps, AppState> {
|
||||
y: gridY,
|
||||
});
|
||||
|
||||
const simulatePressure = event.pressure === 0.5;
|
||||
const simulatePressure =
|
||||
event.pressure === 0.5 || event.pressure === 0 || event.pressure === 1;
|
||||
|
||||
window.__lastPressure__ = event.pressure;
|
||||
|
||||
const freedrawConfig = getFreedrawConfig(event.pointerType);
|
||||
|
||||
const element = newFreeDrawElement({
|
||||
type: elementType,
|
||||
@@ -7743,6 +7771,17 @@ class App extends React.Component<AppProps, AppState> {
|
||||
opacity: this.state.currentItemOpacity,
|
||||
roundness: null,
|
||||
simulatePressure,
|
||||
strokeOptions: {
|
||||
fixedStrokeWidth: this.state.currentItemFixedStrokeWidth,
|
||||
streamline:
|
||||
(window.h?.debugFreedraw?.enabled
|
||||
? window.h?.debugFreedraw?.streamline
|
||||
: null) ?? freedrawConfig.streamline,
|
||||
simplify:
|
||||
(window.h?.debugFreedraw?.enabled
|
||||
? window.h?.debugFreedraw?.simplify
|
||||
: null) ?? freedrawConfig.simplify,
|
||||
},
|
||||
locked: false,
|
||||
frameId: topLayerFrame ? topLayerFrame.id : null,
|
||||
points: [pointFrom<LocalPoint>(0, 0)],
|
||||
@@ -8519,10 +8558,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
if (
|
||||
this.state.activeTool.type === "lasso" &&
|
||||
this.lassoTrail.hasCurrentTrail &&
|
||||
!(
|
||||
this.editorInterface.formFactor !== "desktop" &&
|
||||
pointerDownState.hit.element
|
||||
) &&
|
||||
!(isMobileOrTablet() && pointerDownState.hit.element) &&
|
||||
!this.state.activeTool.fromSelection
|
||||
) {
|
||||
return;
|
||||
@@ -8848,15 +8884,6 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}));
|
||||
|
||||
this.scene.replaceAllElements(elementsWithIndices);
|
||||
selectedElements.forEach((element) => {
|
||||
if (
|
||||
isBindableElement(element) &&
|
||||
element.boundElements?.some((other) => other.type === "arrow")
|
||||
) {
|
||||
updateBoundElements(element, this.scene);
|
||||
}
|
||||
});
|
||||
|
||||
this.maybeCacheVisibleGaps(event, selectedElements, true);
|
||||
this.maybeCacheReferenceSnapPoints(event, selectedElements, true);
|
||||
});
|
||||
@@ -9379,7 +9406,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
newElement &&
|
||||
!multiElement
|
||||
) {
|
||||
if (this.editorInterface.isTouchScreen) {
|
||||
if (this.device.isTouchScreen) {
|
||||
const FIXED_DELTA_X = Math.min(
|
||||
(this.state.width * 0.7) / this.state.zoom.value,
|
||||
100,
|
||||
@@ -11197,7 +11224,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
}
|
||||
|
||||
const zIndexActions: ContextMenuItems =
|
||||
this.editorInterface.formFactor === "desktop"
|
||||
this.state.stylesPanelMode === "full"
|
||||
? [
|
||||
CONTEXT_MENU_SEPARATOR,
|
||||
actionSendBackward,
|
||||
@@ -11253,13 +11280,12 @@ class App extends React.Component<AppProps, AppState> {
|
||||
(
|
||||
event: WheelEvent | React.WheelEvent<HTMLDivElement | HTMLCanvasElement>,
|
||||
) => {
|
||||
// if not scrolling on canvas/wysiwyg, ignore
|
||||
if (
|
||||
!(
|
||||
event.target instanceof HTMLCanvasElement ||
|
||||
event.target instanceof HTMLTextAreaElement ||
|
||||
event.target instanceof HTMLIFrameElement ||
|
||||
(event.target instanceof HTMLElement &&
|
||||
event.target.classList.contains(CLASSES.FRAME_NAME))
|
||||
event.target instanceof HTMLIFrameElement
|
||||
)
|
||||
) {
|
||||
// prevent zooming the browser (but allow scrolling DOM)
|
||||
@@ -11468,6 +11494,7 @@ class App extends React.Component<AppProps, AppState> {
|
||||
// -----------------------------------------------------------------------------
|
||||
declare global {
|
||||
interface Window {
|
||||
__lastPressure__?: number;
|
||||
h: {
|
||||
scene: Scene;
|
||||
elements: readonly ExcalidrawElement[];
|
||||
@@ -11476,6 +11503,11 @@ declare global {
|
||||
app: InstanceType<typeof App>;
|
||||
history: History;
|
||||
store: Store;
|
||||
debugFreedraw?: {
|
||||
streamline: number;
|
||||
simplify: number;
|
||||
enabled: boolean;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -11484,6 +11516,12 @@ export const createTestHook = () => {
|
||||
if (isTestEnv() || isDevEnv()) {
|
||||
window.h = window.h || ({} as Window["h"]);
|
||||
|
||||
// Initialize debug freedraw parameters
|
||||
window.h.debugFreedraw = {
|
||||
enabled: true,
|
||||
...(window.h.debugFreedraw || STROKE_OPTIONS.default),
|
||||
};
|
||||
|
||||
Object.defineProperties(window.h, {
|
||||
elements: {
|
||||
configurable: true,
|
||||
|
||||
@@ -6,7 +6,7 @@ import { KEYS } from "@excalidraw/common";
|
||||
import { getShortcutKey } from "../..//shortcut";
|
||||
import { useAtom } from "../../editor-jotai";
|
||||
import { t } from "../../i18n";
|
||||
import { useEditorInterface } from "../App";
|
||||
import { useDevice } from "../App";
|
||||
import { activeEyeDropperAtom } from "../EyeDropper";
|
||||
import { eyeDropperIcon } from "../icons";
|
||||
|
||||
@@ -30,7 +30,7 @@ export const ColorInput = ({
|
||||
colorPickerType,
|
||||
placeholder,
|
||||
}: ColorInputProps) => {
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
const [innerValue, setInnerValue] = useState(color);
|
||||
const [activeSection, setActiveColorPickerSection] = useAtom(
|
||||
activeColorPickerSectionAtom,
|
||||
@@ -99,7 +99,7 @@ export const ColorInput = ({
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
{/* TODO reenable on mobile with a better UX */}
|
||||
{editorInterface.formFactor !== "phone" && (
|
||||
{!device.editor.isMobile && (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
|
||||
@@ -15,7 +15,7 @@ import type { ExcalidrawElement } from "@excalidraw/element/types";
|
||||
|
||||
import { useAtom } from "../../editor-jotai";
|
||||
import { t } from "../../i18n";
|
||||
import { useExcalidrawContainer, useStylesPanelMode } from "../App";
|
||||
import { useExcalidrawContainer } from "../App";
|
||||
import { ButtonSeparator } from "../ButtonSeparator";
|
||||
import { activeEyeDropperAtom } from "../EyeDropper";
|
||||
import { PropertiesPopover } from "../PropertiesPopover";
|
||||
@@ -73,6 +73,7 @@ interface ColorPickerProps {
|
||||
palette?: ColorPaletteCustom | null;
|
||||
topPicks?: ColorTuple;
|
||||
updateData: (formData?: any) => void;
|
||||
compactMode?: boolean;
|
||||
}
|
||||
|
||||
const ColorPickerPopupContent = ({
|
||||
@@ -99,9 +100,6 @@ const ColorPickerPopupContent = ({
|
||||
getOpenPopup: () => AppState["openPopup"];
|
||||
}) => {
|
||||
const { container } = useExcalidrawContainer();
|
||||
const stylesPanelMode = useStylesPanelMode();
|
||||
const isCompactMode = stylesPanelMode !== "full";
|
||||
const isMobileMode = stylesPanelMode === "mobile";
|
||||
const [, setActiveColorPickerSection] = useAtom(activeColorPickerSectionAtom);
|
||||
|
||||
const [eyeDropperState, setEyeDropperState] = useAtom(activeEyeDropperAtom);
|
||||
@@ -218,8 +216,11 @@ const ColorPickerPopupContent = ({
|
||||
type={type}
|
||||
elements={elements}
|
||||
updateData={updateData}
|
||||
showTitle={isCompactMode}
|
||||
showHotKey={!isMobileMode}
|
||||
showTitle={
|
||||
appState.stylesPanelMode === "compact" ||
|
||||
appState.stylesPanelMode === "mobile"
|
||||
}
|
||||
showHotKey={appState.stylesPanelMode !== "mobile"}
|
||||
>
|
||||
{colorInputJSX}
|
||||
</Picker>
|
||||
@@ -234,6 +235,7 @@ const ColorPickerTrigger = ({
|
||||
label,
|
||||
color,
|
||||
type,
|
||||
stylesPanelMode,
|
||||
mode = "background",
|
||||
onToggle,
|
||||
editingTextElement,
|
||||
@@ -241,13 +243,11 @@ const ColorPickerTrigger = ({
|
||||
color: string | null;
|
||||
label: string;
|
||||
type: ColorPickerType;
|
||||
stylesPanelMode?: AppState["stylesPanelMode"];
|
||||
mode?: "background" | "stroke";
|
||||
onToggle: () => void;
|
||||
editingTextElement?: boolean;
|
||||
}) => {
|
||||
const stylesPanelMode = useStylesPanelMode();
|
||||
const isCompactMode = stylesPanelMode !== "full";
|
||||
const isMobileMode = stylesPanelMode === "mobile";
|
||||
const handleClick = (e: React.MouseEvent) => {
|
||||
// use pointerdown so we run before outside-close logic
|
||||
e.preventDefault();
|
||||
@@ -268,8 +268,9 @@ const ColorPickerTrigger = ({
|
||||
"is-transparent": !color || color === "transparent",
|
||||
"has-outline":
|
||||
!color || !isColorDark(color, COLOR_OUTLINE_CONTRAST_THRESHOLD),
|
||||
"compact-sizing": isCompactMode,
|
||||
"mobile-border": isMobileMode,
|
||||
"compact-sizing":
|
||||
stylesPanelMode === "compact" || stylesPanelMode === "mobile",
|
||||
"mobile-border": stylesPanelMode === "mobile",
|
||||
})}
|
||||
aria-label={label}
|
||||
style={color ? { "--swatch-color": color } : undefined}
|
||||
@@ -282,20 +283,22 @@ const ColorPickerTrigger = ({
|
||||
onClick={handleClick}
|
||||
>
|
||||
<div className="color-picker__button-outline">{!color && slashIcon}</div>
|
||||
{isCompactMode && color && mode === "stroke" && (
|
||||
<div className="color-picker__button-background">
|
||||
<span
|
||||
style={{
|
||||
color:
|
||||
color && isColorDark(color, COLOR_OUTLINE_CONTRAST_THRESHOLD)
|
||||
? "#fff"
|
||||
: "#111",
|
||||
}}
|
||||
>
|
||||
{strokeIcon}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{(stylesPanelMode === "compact" || stylesPanelMode === "mobile") &&
|
||||
color &&
|
||||
mode === "stroke" && (
|
||||
<div className="color-picker__button-background">
|
||||
<span
|
||||
style={{
|
||||
color:
|
||||
color && isColorDark(color, COLOR_OUTLINE_CONTRAST_THRESHOLD)
|
||||
? "#fff"
|
||||
: "#111",
|
||||
}}
|
||||
>
|
||||
{strokeIcon}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</Popover.Trigger>
|
||||
);
|
||||
};
|
||||
@@ -315,8 +318,10 @@ export const ColorPicker = ({
|
||||
useEffect(() => {
|
||||
openRef.current = appState.openPopup;
|
||||
}, [appState.openPopup]);
|
||||
const stylesPanelMode = useStylesPanelMode();
|
||||
const isCompactMode = stylesPanelMode !== "full";
|
||||
const compactMode =
|
||||
type !== "canvasBackground" &&
|
||||
(appState.stylesPanelMode === "compact" ||
|
||||
appState.stylesPanelMode === "mobile");
|
||||
|
||||
return (
|
||||
<div>
|
||||
@@ -324,10 +329,10 @@ export const ColorPicker = ({
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
className={clsx("color-picker-container", {
|
||||
"color-picker-container--no-top-picks": isCompactMode,
|
||||
"color-picker-container--no-top-picks": compactMode,
|
||||
})}
|
||||
>
|
||||
{!isCompactMode && (
|
||||
{!compactMode && (
|
||||
<TopPicks
|
||||
activeColor={color}
|
||||
onChange={onChange}
|
||||
@@ -335,7 +340,7 @@ export const ColorPicker = ({
|
||||
topPicks={topPicks}
|
||||
/>
|
||||
)}
|
||||
{!isCompactMode && <ButtonSeparator />}
|
||||
{!compactMode && <ButtonSeparator />}
|
||||
<Popover.Root
|
||||
open={appState.openPopup === type}
|
||||
onOpenChange={(open) => {
|
||||
@@ -349,6 +354,7 @@ export const ColorPicker = ({
|
||||
color={color}
|
||||
label={label}
|
||||
type={type}
|
||||
stylesPanelMode={appState.stylesPanelMode}
|
||||
mode={type === "elementStroke" ? "stroke" : "background"}
|
||||
editingTextElement={!!appState.editingTextElement}
|
||||
onToggle={() => {
|
||||
|
||||
@@ -903,7 +903,7 @@ function CommandPaletteInner({
|
||||
ref={inputRef}
|
||||
/>
|
||||
|
||||
{app.editorInterface.formFactor !== "phone" && (
|
||||
{!app.device.viewport.isMobile && (
|
||||
<div className="shortcuts-wrapper">
|
||||
<CommandShortcutHint shortcut="↑↓">
|
||||
{t("commandPalette.shortcuts.select")}
|
||||
@@ -937,7 +937,7 @@ function CommandPaletteInner({
|
||||
onClick={(event) => executeCommand(lastUsed, event)}
|
||||
disabled={!isCommandAvailable(lastUsed)}
|
||||
onMouseMove={() => setCurrentCommand(lastUsed)}
|
||||
showShortcut={app.editorInterface.formFactor !== "phone"}
|
||||
showShortcut={!app.device.viewport.isMobile}
|
||||
appState={uiAppState}
|
||||
/>
|
||||
</div>
|
||||
@@ -955,7 +955,7 @@ function CommandPaletteInner({
|
||||
isSelected={command.label === currentCommand?.label}
|
||||
onClick={(event) => executeCommand(command, event)}
|
||||
onMouseMove={() => setCurrentCommand(command)}
|
||||
showShortcut={app.editorInterface.formFactor !== "phone"}
|
||||
showShortcut={!app.device.viewport.isMobile}
|
||||
appState={uiAppState}
|
||||
size={category === "Library" ? "large" : "small"}
|
||||
/>
|
||||
|
||||
@@ -9,7 +9,7 @@ import { t } from "../i18n";
|
||||
|
||||
import {
|
||||
useExcalidrawContainer,
|
||||
useEditorInterface,
|
||||
useDevice,
|
||||
useExcalidrawSetAppState,
|
||||
} from "./App";
|
||||
import { Island } from "./Island";
|
||||
@@ -51,7 +51,7 @@ export const Dialog = (props: DialogProps) => {
|
||||
const [islandNode, setIslandNode] = useCallbackRefState<HTMLDivElement>();
|
||||
const [lastActiveElement] = useState(document.activeElement);
|
||||
const { id } = useExcalidrawContainer();
|
||||
const isFullscreen = useEditorInterface().formFactor === "phone";
|
||||
const isFullscreen = useDevice().viewport.isMobile;
|
||||
|
||||
useEffect(() => {
|
||||
if (!islandNode) {
|
||||
|
||||
@@ -20,7 +20,7 @@ export type ButtonColor =
|
||||
export type ButtonSize = "medium" | "large";
|
||||
|
||||
export type FilledButtonProps = {
|
||||
label?: string;
|
||||
label: string;
|
||||
|
||||
children?: React.ReactNode;
|
||||
onClick?: (event: React.MouseEvent) => void;
|
||||
|
||||
@@ -20,12 +20,7 @@ import type { ValueOf } from "@excalidraw/common/utility-types";
|
||||
|
||||
import { Fonts } from "../../fonts";
|
||||
import { t } from "../../i18n";
|
||||
import {
|
||||
useApp,
|
||||
useAppProps,
|
||||
useExcalidrawContainer,
|
||||
useStylesPanelMode,
|
||||
} from "../App";
|
||||
import { useApp, useAppProps, useExcalidrawContainer } from "../App";
|
||||
import { PropertiesPopover } from "../PropertiesPopover";
|
||||
import { QuickSearch } from "../QuickSearch";
|
||||
import { ScrollableList } from "../ScrollableList";
|
||||
@@ -98,7 +93,6 @@ export const FontPickerList = React.memo(
|
||||
const app = useApp();
|
||||
const { fonts } = app;
|
||||
const { showDeprecatedFonts } = useAppProps();
|
||||
const stylesPanelMode = useStylesPanelMode();
|
||||
|
||||
const [searchTerm, setSearchTerm] = useState("");
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
@@ -344,7 +338,7 @@ export const FontPickerList = React.memo(
|
||||
onKeyDown={onKeyDown}
|
||||
preventAutoFocusOnTouch={!!app.state.editingTextElement}
|
||||
>
|
||||
{stylesPanelMode === "full" && (
|
||||
{app.state.stylesPanelMode === "full" && (
|
||||
<QuickSearch
|
||||
ref={inputRef}
|
||||
placeholder={t("quickSearch.placeholder")}
|
||||
|
||||
@@ -11,8 +11,6 @@ import {
|
||||
|
||||
import { isNodeInFlowchart } from "@excalidraw/element";
|
||||
|
||||
import type { EditorInterface } from "@excalidraw/common";
|
||||
|
||||
import { t } from "../i18n";
|
||||
import { getShortcutKey } from "../shortcut";
|
||||
import { isEraserActive } from "../appState";
|
||||
@@ -20,12 +18,12 @@ import { isGridModeEnabled } from "../snapping";
|
||||
|
||||
import "./HintViewer.scss";
|
||||
|
||||
import type { AppClassProperties, UIAppState } from "../types";
|
||||
import type { AppClassProperties, Device, UIAppState } from "../types";
|
||||
|
||||
interface HintViewerProps {
|
||||
appState: UIAppState;
|
||||
isMobile: boolean;
|
||||
editorInterface: EditorInterface;
|
||||
device: Device;
|
||||
app: AppClassProperties;
|
||||
}
|
||||
|
||||
@@ -37,7 +35,7 @@ const getTaggedShortcutKey = (key: string | string[]) =>
|
||||
const getHints = ({
|
||||
appState,
|
||||
isMobile,
|
||||
editorInterface,
|
||||
device,
|
||||
app,
|
||||
}: HintViewerProps): null | string | string[] => {
|
||||
const { activeTool, isResizing, isRotating, lastPointerDownWith } = appState;
|
||||
@@ -53,7 +51,7 @@ const getHints = ({
|
||||
});
|
||||
}
|
||||
|
||||
if (appState.openSidebar && !editorInterface.canFitSidebar) {
|
||||
if (appState.openSidebar && !device.editor.canFitSidebar) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -227,13 +225,13 @@ const getHints = ({
|
||||
export const HintViewer = ({
|
||||
appState,
|
||||
isMobile,
|
||||
editorInterface,
|
||||
device,
|
||||
app,
|
||||
}: HintViewerProps) => {
|
||||
const hints = getHints({
|
||||
appState,
|
||||
isMobile,
|
||||
editorInterface,
|
||||
device,
|
||||
app,
|
||||
});
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { atom, useAtom } from "../editor-jotai";
|
||||
import { getLanguage, t } from "../i18n";
|
||||
|
||||
import Collapsible from "./Stats/Collapsible";
|
||||
import { useEditorInterface, useExcalidrawContainer } from "./App";
|
||||
import { useDevice, useExcalidrawContainer } from "./App";
|
||||
|
||||
import "./IconPicker.scss";
|
||||
|
||||
@@ -38,7 +38,7 @@ function Picker<T>({
|
||||
onClose: () => void;
|
||||
numberOfOptionsToAlwaysShow?: number;
|
||||
}) {
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
const { container } = useExcalidrawContainer();
|
||||
|
||||
const handleKeyDown = (event: React.KeyboardEvent) => {
|
||||
@@ -153,7 +153,7 @@ function Picker<T>({
|
||||
);
|
||||
};
|
||||
|
||||
const isMobile = editorInterface.formFactor === "phone";
|
||||
const isMobile = device.editor.isMobile;
|
||||
|
||||
return (
|
||||
<Popover.Content
|
||||
|
||||
@@ -120,53 +120,4 @@
|
||||
margin-bottom: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.disable-view-mode {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
border: 1px solid var(--color-primary);
|
||||
padding: 0.5rem;
|
||||
border-radius: var(--border-radius-lg);
|
||||
background-color: var(--island-bg-color);
|
||||
text-decoration: none !important;
|
||||
|
||||
font-family: var(--ui-font);
|
||||
font-size: 0.8333rem;
|
||||
box-sizing: border-box;
|
||||
|
||||
width: var(--mobile-action-button-size, var(--default-button-size));
|
||||
height: var(--mobile-action-button-size, var(--default-button-size));
|
||||
|
||||
border: none;
|
||||
box-shadow: 0 0 0 1px var(--color-surface-lowest);
|
||||
background-color: var(--color-surface-low);
|
||||
color: var(--button-color, var(--color-on-surface)) !important;
|
||||
|
||||
&:active {
|
||||
box-shadow: 0 0 0 1px var(--color-brand-active);
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-primary);
|
||||
color: white !important;
|
||||
}
|
||||
&:active {
|
||||
background-color: var(--color-primary-darker);
|
||||
}
|
||||
|
||||
svg {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.theme--dark {
|
||||
.plus-banner {
|
||||
&:hover {
|
||||
color: black !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import React from "react";
|
||||
import {
|
||||
CLASSES,
|
||||
DEFAULT_SIDEBAR,
|
||||
MQ_MIN_WIDTH_DESKTOP,
|
||||
TOOL_TYPE,
|
||||
arrayToMap,
|
||||
capitalizeString,
|
||||
@@ -45,9 +46,9 @@ import Footer from "./footer/Footer";
|
||||
import { isSidebarDockedAtom } from "./Sidebar/Sidebar";
|
||||
import MainMenu from "./main-menu/MainMenu";
|
||||
import { ActiveConfirmDialog } from "./ActiveConfirmDialog";
|
||||
import { useEditorInterface, useStylesPanelMode } from "./App";
|
||||
import { useDevice } from "./App";
|
||||
import { OverwriteConfirmDialog } from "./OverwriteConfirm/OverwriteConfirm";
|
||||
import { sidebarRightIcon } from "./icons";
|
||||
import { LibraryIcon } from "./icons";
|
||||
import { DefaultSidebar } from "./DefaultSidebar";
|
||||
import { TTDDialog } from "./TTDDialog/TTDDialog";
|
||||
import { Stats } from "./Stats";
|
||||
@@ -160,28 +161,27 @@ const LayerUI = ({
|
||||
isCollaborating,
|
||||
generateLinkForSelection,
|
||||
}: LayerUIProps) => {
|
||||
const editorInterface = useEditorInterface();
|
||||
const stylesPanelMode = useStylesPanelMode();
|
||||
const isCompactStylesPanel = stylesPanelMode === "compact";
|
||||
const device = useDevice();
|
||||
const tunnels = useInitializeTunnels();
|
||||
|
||||
const spacing = isCompactStylesPanel
|
||||
? {
|
||||
menuTopGap: 4,
|
||||
toolbarColGap: 4,
|
||||
toolbarRowGap: 1,
|
||||
toolbarInnerRowGap: 0.5,
|
||||
islandPadding: 1,
|
||||
collabMarginLeft: 8,
|
||||
}
|
||||
: {
|
||||
menuTopGap: 6,
|
||||
toolbarColGap: 4,
|
||||
toolbarRowGap: 1,
|
||||
toolbarInnerRowGap: 1,
|
||||
islandPadding: 1,
|
||||
collabMarginLeft: 8,
|
||||
};
|
||||
const spacing =
|
||||
appState.stylesPanelMode === "compact"
|
||||
? {
|
||||
menuTopGap: 4,
|
||||
toolbarColGap: 4,
|
||||
toolbarRowGap: 1,
|
||||
toolbarInnerRowGap: 0.5,
|
||||
islandPadding: 1,
|
||||
collabMarginLeft: 8,
|
||||
}
|
||||
: {
|
||||
menuTopGap: 6,
|
||||
toolbarColGap: 4,
|
||||
toolbarRowGap: 1,
|
||||
toolbarInnerRowGap: 1,
|
||||
islandPadding: 1,
|
||||
collabMarginLeft: 8,
|
||||
};
|
||||
|
||||
const TunnelsJotaiProvider = tunnels.tunnelsJotai.Provider;
|
||||
|
||||
@@ -236,7 +236,7 @@ const LayerUI = ({
|
||||
);
|
||||
|
||||
const renderSelectedShapeActions = () => {
|
||||
const isCompactMode = isCompactStylesPanel;
|
||||
const isCompactMode = appState.stylesPanelMode === "compact";
|
||||
|
||||
return (
|
||||
<Section
|
||||
@@ -308,7 +308,7 @@ const LayerUI = ({
|
||||
<div
|
||||
className={clsx("selected-shape-actions-container", {
|
||||
"selected-shape-actions-container--compact":
|
||||
isCompactStylesPanel,
|
||||
appState.stylesPanelMode === "compact",
|
||||
})}
|
||||
>
|
||||
{shouldRenderSelectedShapeActions && renderSelectedShapeActions()}
|
||||
@@ -333,13 +333,14 @@ const LayerUI = ({
|
||||
padding={spacing.islandPadding}
|
||||
className={clsx("App-toolbar", {
|
||||
"zen-mode": appState.zenModeEnabled,
|
||||
"App-toolbar--compact": isCompactStylesPanel,
|
||||
"App-toolbar--compact":
|
||||
appState.stylesPanelMode === "compact",
|
||||
})}
|
||||
>
|
||||
<HintViewer
|
||||
appState={appState}
|
||||
isMobile={editorInterface.formFactor === "phone"}
|
||||
editorInterface={editorInterface}
|
||||
isMobile={device.editor.isMobile}
|
||||
device={device}
|
||||
app={app}
|
||||
/>
|
||||
{heading}
|
||||
@@ -405,7 +406,8 @@ const LayerUI = ({
|
||||
"layer-ui__wrapper__top-right zen-mode-transition",
|
||||
{
|
||||
"transition-right": appState.zenModeEnabled,
|
||||
"layer-ui__wrapper__top-right--compact": isCompactStylesPanel,
|
||||
"layer-ui__wrapper__top-right--compact":
|
||||
appState.stylesPanelMode === "compact",
|
||||
},
|
||||
)}
|
||||
>
|
||||
@@ -415,10 +417,7 @@ const LayerUI = ({
|
||||
userToFollow={appState.userToFollow?.socketId || null}
|
||||
/>
|
||||
)}
|
||||
{renderTopRightUI?.(
|
||||
editorInterface.formFactor === "phone",
|
||||
appState,
|
||||
)}
|
||||
{renderTopRightUI?.(device.editor.isMobile, appState)}
|
||||
{!appState.viewModeEnabled &&
|
||||
appState.openDialog?.name !== "elementLinkSelector" &&
|
||||
// hide button when sidebar docked
|
||||
@@ -449,9 +448,7 @@ const LayerUI = ({
|
||||
trackEvent(
|
||||
"sidebar",
|
||||
`toggleDock (${docked ? "dock" : "undock"})`,
|
||||
`(${
|
||||
editorInterface.formFactor === "phone" ? "mobile" : "desktop"
|
||||
})`,
|
||||
`(${device.editor.isMobile ? "mobile" : "desktop"})`,
|
||||
);
|
||||
}}
|
||||
/>
|
||||
@@ -472,21 +469,23 @@ const LayerUI = ({
|
||||
<DefaultMainMenu UIOptions={UIOptions} />
|
||||
<DefaultSidebar.Trigger
|
||||
__fallback
|
||||
icon={sidebarRightIcon}
|
||||
icon={LibraryIcon}
|
||||
title={capitalizeString(t("toolBar.library"))}
|
||||
onToggle={(open) => {
|
||||
if (open) {
|
||||
trackEvent(
|
||||
"sidebar",
|
||||
`${DEFAULT_SIDEBAR.name} (open)`,
|
||||
`button (${
|
||||
editorInterface.formFactor === "phone" ? "mobile" : "desktop"
|
||||
})`,
|
||||
`button (${device.editor.isMobile ? "mobile" : "desktop"})`,
|
||||
);
|
||||
}
|
||||
}}
|
||||
tab={DEFAULT_SIDEBAR.defaultTab}
|
||||
/>
|
||||
>
|
||||
{appState.stylesPanelMode === "full" &&
|
||||
appState.width >= MQ_MIN_WIDTH_DESKTOP &&
|
||||
t("toolBar.library")}
|
||||
</DefaultSidebar.Trigger>
|
||||
<DefaultOverwriteConfirmDialog />
|
||||
{appState.openDialog?.name === "ttd" && <TTDDialog __fallback />}
|
||||
{/* ------------------------------------------------------------------ */}
|
||||
@@ -497,7 +496,7 @@ const LayerUI = ({
|
||||
{appState.errorMessage}
|
||||
</ErrorDialog>
|
||||
)}
|
||||
{eyeDropperState && editorInterface.formFactor !== "phone" && (
|
||||
{eyeDropperState && !device.editor.isMobile && (
|
||||
<EyeDropper
|
||||
colorPickerType={eyeDropperState.colorPickerType}
|
||||
onCancel={() => {
|
||||
@@ -576,7 +575,7 @@ const LayerUI = ({
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{editorInterface.formFactor === "phone" && (
|
||||
{device.editor.isMobile && (
|
||||
<MobileMenu
|
||||
app={app}
|
||||
appState={appState}
|
||||
@@ -594,14 +593,14 @@ const LayerUI = ({
|
||||
UIOptions={UIOptions}
|
||||
/>
|
||||
)}
|
||||
{editorInterface.formFactor !== "phone" && (
|
||||
{!device.editor.isMobile && (
|
||||
<>
|
||||
<div
|
||||
className="layer-ui__wrapper"
|
||||
style={
|
||||
appState.openSidebar &&
|
||||
isSidebarDocked &&
|
||||
editorInterface.canFitSidebar
|
||||
device.editor.canFitSidebar
|
||||
? { width: `calc(100% - var(--right-sidebar-width))` }
|
||||
: {}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import "./LibraryMenuItems.scss";
|
||||
|
||||
import { TextField } from "./TextField";
|
||||
|
||||
import { useEditorInterface } from "./App";
|
||||
import { useDevice } from "./App";
|
||||
|
||||
import { Button } from "./Button";
|
||||
|
||||
@@ -75,7 +75,7 @@ export default function LibraryMenuItems({
|
||||
selectedItems: LibraryItem["id"][];
|
||||
onSelectItems: (id: LibraryItem["id"][]) => void;
|
||||
}) {
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
const libraryContainerRef = useRef<HTMLDivElement>(null);
|
||||
const scrollPosition = useScrollPosition<HTMLDivElement>(libraryContainerRef);
|
||||
|
||||
@@ -392,7 +392,7 @@ export default function LibraryMenuItems({
|
||||
ref={searchInputRef}
|
||||
type="search"
|
||||
className={clsx("library-menu-items-container__search", {
|
||||
hideCancelButton: editorInterface.formFactor !== "phone",
|
||||
hideCancelButton: !device.editor.isMobile,
|
||||
})}
|
||||
placeholder={t("library.search.inputPlaceholder")}
|
||||
value={searchInputValue}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { memo, useRef, useState } from "react";
|
||||
|
||||
import { useLibraryItemSvg } from "../hooks/useLibraryItemSvg";
|
||||
|
||||
import { useEditorInterface } from "./App";
|
||||
import { useDevice } from "./App";
|
||||
import { CheckboxItem } from "./CheckboxItem";
|
||||
import { PlusIcon } from "./icons";
|
||||
|
||||
@@ -36,7 +36,7 @@ export const LibraryUnit = memo(
|
||||
const svg = useLibraryItemSvg(id, elements, svgCache, ref);
|
||||
|
||||
const [isHovered, setIsHovered] = useState(false);
|
||||
const isMobile = useEditorInterface().formFactor === "phone";
|
||||
const isMobile = useDevice().editor.isMobile;
|
||||
const adder = isPending && (
|
||||
<div className="library-unit__adder">{PlusIcon}</div>
|
||||
);
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import { FilledButton } from "./FilledButton";
|
||||
|
||||
export const LinkButton = ({
|
||||
children,
|
||||
href,
|
||||
}: {
|
||||
href: string;
|
||||
children: React.ReactNode;
|
||||
}) => {
|
||||
return (
|
||||
<a href={href} target="_blank" rel="noopener" className="link-button">
|
||||
<FilledButton>{children}</FilledButton>
|
||||
</a>
|
||||
);
|
||||
};
|
||||
@@ -7,14 +7,12 @@ import { t } from "../i18n";
|
||||
import { calculateScrollCenter } from "../scene";
|
||||
import { SCROLLBAR_WIDTH, SCROLLBAR_MARGIN } from "../scene/scrollbars";
|
||||
|
||||
import { ExitViewModeButton, MobileShapeActions } from "./Actions";
|
||||
import { MobileShapeActions } from "./Actions";
|
||||
import { MobileToolBar } from "./MobileToolBar";
|
||||
import { FixedSideContainer } from "./FixedSideContainer";
|
||||
|
||||
import { Island } from "./Island";
|
||||
|
||||
import { PenModeButton } from "./PenModeButton";
|
||||
|
||||
import type { ActionManager } from "../actions/manager";
|
||||
import type {
|
||||
AppClassProperties,
|
||||
@@ -60,7 +58,6 @@ export const MobileMenu = ({
|
||||
renderWelcomeScreen,
|
||||
UIOptions,
|
||||
app,
|
||||
onPenModeToggle,
|
||||
}: MobileMenuProps) => {
|
||||
const {
|
||||
WelcomeScreenCenterTunnel,
|
||||
@@ -68,29 +65,8 @@ export const MobileMenu = ({
|
||||
DefaultSidebarTriggerTunnel,
|
||||
} = useTunnels();
|
||||
const renderAppTopBar = () => {
|
||||
if (appState.openDialog?.name === "elementLinkSelector") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const topRightUI = (
|
||||
<div className="excalidraw-ui-top-right">
|
||||
{renderTopRightUI?.(true, appState) ??
|
||||
(!appState.viewModeEnabled && (
|
||||
<>
|
||||
<PenModeButton
|
||||
checked={appState.penMode}
|
||||
onChange={() => onPenModeToggle(null)}
|
||||
title={t("toolBar.penMode")}
|
||||
isMobile
|
||||
penDetected={appState.penDetected}
|
||||
/>
|
||||
<DefaultSidebarTriggerTunnel.Out />
|
||||
</>
|
||||
))}
|
||||
{appState.viewModeEnabled && (
|
||||
<ExitViewModeButton actionManager={actionManager} />
|
||||
)}
|
||||
</div>
|
||||
const topRightUI = renderTopRightUI?.(true, appState) ?? (
|
||||
<DefaultSidebarTriggerTunnel.Out />
|
||||
);
|
||||
|
||||
const topLeftUI = (
|
||||
@@ -100,6 +76,13 @@ export const MobileMenu = ({
|
||||
</div>
|
||||
);
|
||||
|
||||
if (
|
||||
appState.viewModeEnabled ||
|
||||
appState.openDialog?.name === "elementLinkSelector"
|
||||
) {
|
||||
return <div className="App-toolbar-content">{topLeftUI}</div>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="App-toolbar-content"
|
||||
@@ -134,43 +117,41 @@ export const MobileMenu = ({
|
||||
{renderWelcomeScreen && <WelcomeScreenCenterTunnel.Out />}
|
||||
</div>
|
||||
|
||||
{!appState.viewModeEnabled && (
|
||||
<div
|
||||
className="App-bottom-bar"
|
||||
style={{
|
||||
marginBottom: SCROLLBAR_WIDTH + SCROLLBAR_MARGIN,
|
||||
}}
|
||||
>
|
||||
<MobileShapeActions
|
||||
appState={appState}
|
||||
elementsMap={app.scene.getNonDeletedElementsMap()}
|
||||
renderAction={actionManager.renderAction}
|
||||
app={app}
|
||||
setAppState={setAppState}
|
||||
/>
|
||||
<div
|
||||
className="App-bottom-bar"
|
||||
style={{
|
||||
marginBottom: SCROLLBAR_WIDTH + SCROLLBAR_MARGIN,
|
||||
}}
|
||||
>
|
||||
<MobileShapeActions
|
||||
appState={appState}
|
||||
elementsMap={app.scene.getNonDeletedElementsMap()}
|
||||
renderAction={actionManager.renderAction}
|
||||
app={app}
|
||||
setAppState={setAppState}
|
||||
/>
|
||||
|
||||
<Island className="App-toolbar">
|
||||
{!appState.viewModeEnabled &&
|
||||
appState.openDialog?.name !== "elementLinkSelector" &&
|
||||
renderToolbar()}
|
||||
{appState.scrolledOutside &&
|
||||
!appState.openMenu &&
|
||||
!appState.openSidebar && (
|
||||
<button
|
||||
type="button"
|
||||
className="scroll-back-to-content"
|
||||
onClick={() => {
|
||||
setAppState((appState) => ({
|
||||
...calculateScrollCenter(elements, appState),
|
||||
}));
|
||||
}}
|
||||
>
|
||||
{t("buttons.scrollBackToContent")}
|
||||
</button>
|
||||
)}
|
||||
</Island>
|
||||
</div>
|
||||
)}
|
||||
<Island className="App-toolbar">
|
||||
{!appState.viewModeEnabled &&
|
||||
appState.openDialog?.name !== "elementLinkSelector" &&
|
||||
renderToolbar()}
|
||||
{appState.scrolledOutside &&
|
||||
!appState.openMenu &&
|
||||
!appState.openSidebar && (
|
||||
<button
|
||||
type="button"
|
||||
className="scroll-back-to-content"
|
||||
onClick={() => {
|
||||
setAppState((appState) => ({
|
||||
...calculateScrollCenter(elements, appState),
|
||||
}));
|
||||
}}
|
||||
>
|
||||
{t("buttons.scrollBackToContent")}
|
||||
</button>
|
||||
)}
|
||||
</Island>
|
||||
</div>
|
||||
|
||||
<FixedSideContainer side="top" className="App-top-bar">
|
||||
{renderAppTopBar()}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useState, useEffect } from "react";
|
||||
import { useState, useEffect, useRef } from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
import { KEYS, capitalizeString } from "@excalidraw/common";
|
||||
@@ -101,6 +101,8 @@ export const MobileToolBar = ({
|
||||
"arrow" | "line"
|
||||
>("arrow");
|
||||
|
||||
const toolbarRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
// keep lastActiveGenericShape in sync with active tool if user switches via other UI
|
||||
useEffect(() => {
|
||||
if (
|
||||
@@ -141,8 +143,8 @@ export const MobileToolBar = ({
|
||||
}
|
||||
};
|
||||
|
||||
const [toolbarWidth, setToolbarWidth] = useState(0);
|
||||
|
||||
const toolbarWidth =
|
||||
toolbarRef.current?.getBoundingClientRect()?.width ?? 0 - 8;
|
||||
const WIDTH = 36;
|
||||
const GAP = 4;
|
||||
|
||||
@@ -162,9 +164,6 @@ export const MobileToolBar = ({
|
||||
"laser",
|
||||
"magicframe",
|
||||
].filter((tool) => {
|
||||
if (showTextToolOutside && tool === "text") {
|
||||
return false;
|
||||
}
|
||||
if (showImageToolOutside && tool === "image") {
|
||||
return false;
|
||||
}
|
||||
@@ -175,30 +174,21 @@ export const MobileToolBar = ({
|
||||
});
|
||||
const extraToolSelected = extraTools.includes(activeTool.type);
|
||||
const extraIcon = extraToolSelected
|
||||
? activeTool.type === "text"
|
||||
? TextIcon
|
||||
: activeTool.type === "image"
|
||||
? ImageIcon
|
||||
: activeTool.type === "frame"
|
||||
? activeTool.type === "frame"
|
||||
? frameToolIcon
|
||||
: activeTool.type === "embeddable"
|
||||
? EmbedIcon
|
||||
: activeTool.type === "laser"
|
||||
? laserPointerToolIcon
|
||||
: activeTool.type === "text"
|
||||
? TextIcon
|
||||
: activeTool.type === "magicframe"
|
||||
? MagicIcon
|
||||
: extraToolsIcon
|
||||
: extraToolsIcon;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="mobile-toolbar"
|
||||
ref={(div) => {
|
||||
if (div) {
|
||||
setToolbarWidth(div.getBoundingClientRect().width);
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div className="mobile-toolbar" ref={toolbarRef}>
|
||||
{/* Hand Tool */}
|
||||
<HandButton
|
||||
checked={isHandToolActive(app.state)}
|
||||
|
||||
@@ -4,7 +4,7 @@ import React, { type ReactNode } from "react";
|
||||
|
||||
import { isInteractive } from "@excalidraw/common";
|
||||
|
||||
import { useEditorInterface } from "./App";
|
||||
import { useDevice } from "./App";
|
||||
import { Island } from "./Island";
|
||||
|
||||
interface PropertiesPopoverProps {
|
||||
@@ -39,9 +39,9 @@ export const PropertiesPopover = React.forwardRef<
|
||||
},
|
||||
ref,
|
||||
) => {
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
const isMobilePortrait =
|
||||
editorInterface.formFactor === "phone" && !editorInterface.isLandscape;
|
||||
device.editor.isMobile && !device.viewport.isLandscape;
|
||||
|
||||
return (
|
||||
<Popover.Portal container={container}>
|
||||
@@ -56,8 +56,7 @@ export const PropertiesPopover = React.forwardRef<
|
||||
collisionBoundary={container ?? undefined}
|
||||
style={{
|
||||
zIndex: "var(--zIndex-ui-styles-popup)",
|
||||
marginLeft:
|
||||
editorInterface.formFactor === "phone" ? "0.5rem" : undefined,
|
||||
marginLeft: device.editor.isMobile ? "0.5rem" : undefined,
|
||||
}}
|
||||
onPointerLeave={onPointerLeave}
|
||||
onKeyDown={onKeyDown}
|
||||
@@ -65,7 +64,7 @@ export const PropertiesPopover = React.forwardRef<
|
||||
onPointerDownOutside={onPointerDownOutside}
|
||||
onOpenAutoFocus={(e) => {
|
||||
// prevent auto-focus on touch devices to avoid keyboard popup
|
||||
if (preventAutoFocusOnTouch && editorInterface.isTouchScreen) {
|
||||
if (preventAutoFocusOnTouch && device.isTouchScreen) {
|
||||
e.preventDefault();
|
||||
}
|
||||
}}
|
||||
|
||||
@@ -20,7 +20,7 @@ import {
|
||||
import { useUIAppState } from "../../context/ui-appState";
|
||||
import { atom, useSetAtom } from "../../editor-jotai";
|
||||
import { useOutsideClick } from "../../hooks/useOutsideClick";
|
||||
import { useEditorInterface, useExcalidrawSetAppState } from "../App";
|
||||
import { useDevice, useExcalidrawSetAppState } from "../App";
|
||||
import { Island } from "../Island";
|
||||
|
||||
import { SidebarHeader } from "./SidebarHeader";
|
||||
@@ -96,7 +96,7 @@ export const SidebarInner = forwardRef(
|
||||
return islandRef.current!;
|
||||
});
|
||||
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
|
||||
const closeLibrary = useCallback(() => {
|
||||
const isDialogOpen = !!document.querySelector(".Dialog");
|
||||
@@ -117,11 +117,11 @@ export const SidebarInner = forwardRef(
|
||||
if ((event.target as Element).closest(".sidebar-trigger")) {
|
||||
return;
|
||||
}
|
||||
if (!docked || !editorInterface.canFitSidebar) {
|
||||
if (!docked || !device.editor.canFitSidebar) {
|
||||
closeLibrary();
|
||||
}
|
||||
},
|
||||
[closeLibrary, docked, editorInterface.canFitSidebar],
|
||||
[closeLibrary, docked, device.editor.canFitSidebar],
|
||||
),
|
||||
);
|
||||
|
||||
@@ -129,7 +129,7 @@ export const SidebarInner = forwardRef(
|
||||
const handleKeyDown = (event: KeyboardEvent) => {
|
||||
if (
|
||||
event.key === KEYS.ESCAPE &&
|
||||
(!docked || !editorInterface.canFitSidebar)
|
||||
(!docked || !device.editor.canFitSidebar)
|
||||
) {
|
||||
closeLibrary();
|
||||
}
|
||||
@@ -138,7 +138,7 @@ export const SidebarInner = forwardRef(
|
||||
return () => {
|
||||
document.removeEventListener(EVENT.KEYDOWN, handleKeyDown);
|
||||
};
|
||||
}, [closeLibrary, docked, editorInterface.canFitSidebar]);
|
||||
}, [closeLibrary, docked, device.editor.canFitSidebar]);
|
||||
|
||||
return (
|
||||
<Island
|
||||
|
||||
@@ -2,7 +2,7 @@ import clsx from "clsx";
|
||||
import { useContext } from "react";
|
||||
|
||||
import { t } from "../../i18n";
|
||||
import { useEditorInterface } from "../App";
|
||||
import { useDevice } from "../App";
|
||||
import { Button } from "../Button";
|
||||
import { Tooltip } from "../Tooltip";
|
||||
import { CloseIcon, PinIcon } from "../icons";
|
||||
@@ -16,11 +16,11 @@ export const SidebarHeader = ({
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
}) => {
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
const props = useContext(SidebarPropsContext);
|
||||
|
||||
const renderDockButton = !!(
|
||||
editorInterface.canFitSidebar && props.shouldRenderDockButton
|
||||
device.editor.canFitSidebar && props.shouldRenderDockButton
|
||||
);
|
||||
|
||||
return (
|
||||
|
||||
@@ -4,17 +4,7 @@ import {
|
||||
CURSOR_TYPE,
|
||||
isShallowEqual,
|
||||
sceneCoordsToViewportCoords,
|
||||
type EditorInterface,
|
||||
} from "@excalidraw/common";
|
||||
import { AnimationController } from "@excalidraw/excalidraw/renderer/animation";
|
||||
|
||||
import type {
|
||||
InteractiveCanvasRenderConfig,
|
||||
InteractiveSceneRenderAnimationState,
|
||||
InteractiveSceneRenderConfig,
|
||||
RenderableElementsMap,
|
||||
RenderInteractiveSceneCallback,
|
||||
} from "@excalidraw/excalidraw/scene/types";
|
||||
|
||||
import type {
|
||||
NonDeletedExcalidrawElement,
|
||||
@@ -22,13 +12,15 @@ import type {
|
||||
} from "@excalidraw/element/types";
|
||||
|
||||
import { t } from "../../i18n";
|
||||
import { isRenderThrottlingEnabled } from "../../reactUtils";
|
||||
import { renderInteractiveScene } from "../../renderer/interactiveScene";
|
||||
|
||||
import type {
|
||||
AppClassProperties,
|
||||
AppState,
|
||||
InteractiveCanvasAppState,
|
||||
} from "../../types";
|
||||
InteractiveCanvasRenderConfig,
|
||||
RenderableElementsMap,
|
||||
RenderInteractiveSceneCallback,
|
||||
} from "../../scene/types";
|
||||
import type { AppState, Device, InteractiveCanvasAppState } from "../../types";
|
||||
import type { DOMAttributes } from "react";
|
||||
|
||||
type InteractiveCanvasProps = {
|
||||
@@ -43,8 +35,7 @@ type InteractiveCanvasProps = {
|
||||
scale: number;
|
||||
appState: InteractiveCanvasAppState;
|
||||
renderScrollbars: boolean;
|
||||
editorInterface: EditorInterface;
|
||||
app: AppClassProperties;
|
||||
device: Device;
|
||||
renderInteractiveSceneCallback: (
|
||||
data: RenderInteractiveSceneCallback,
|
||||
) => void;
|
||||
@@ -79,11 +70,8 @@ type InteractiveCanvasProps = {
|
||||
>;
|
||||
};
|
||||
|
||||
export const INTERACTIVE_SCENE_ANIMATION_KEY = "animateInteractiveScene";
|
||||
|
||||
const InteractiveCanvas = (props: InteractiveCanvasProps) => {
|
||||
const isComponentMounted = useRef(false);
|
||||
const rendererParams = useRef(null as InteractiveSceneRenderConfig | null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isComponentMounted.current) {
|
||||
@@ -140,58 +128,29 @@ const InteractiveCanvas = (props: InteractiveCanvasProps) => {
|
||||
)) ||
|
||||
"#6965db";
|
||||
|
||||
rendererParams.current = {
|
||||
app: props.app,
|
||||
canvas: props.canvas,
|
||||
elementsMap: props.elementsMap,
|
||||
visibleElements: props.visibleElements,
|
||||
selectedElements: props.selectedElements,
|
||||
allElementsMap: props.allElementsMap,
|
||||
scale: window.devicePixelRatio,
|
||||
appState: props.appState,
|
||||
renderConfig: {
|
||||
remotePointerViewportCoords,
|
||||
remotePointerButton,
|
||||
remoteSelectedElementIds,
|
||||
remotePointerUsernames,
|
||||
remotePointerUserStates,
|
||||
selectionColor,
|
||||
renderScrollbars: props.renderScrollbars,
|
||||
},
|
||||
editorInterface: props.editorInterface,
|
||||
callback: props.renderInteractiveSceneCallback,
|
||||
animationState: {
|
||||
bindingHighlight: undefined,
|
||||
},
|
||||
deltaTime: 0,
|
||||
};
|
||||
|
||||
if (!AnimationController.running(INTERACTIVE_SCENE_ANIMATION_KEY)) {
|
||||
AnimationController.start<InteractiveSceneRenderAnimationState>(
|
||||
INTERACTIVE_SCENE_ANIMATION_KEY,
|
||||
({ deltaTime, state }) => {
|
||||
const nextAnimationState = renderInteractiveScene({
|
||||
...rendererParams.current!,
|
||||
deltaTime,
|
||||
animationState: state,
|
||||
}).animationState;
|
||||
|
||||
if (nextAnimationState) {
|
||||
for (const key in nextAnimationState) {
|
||||
if (
|
||||
nextAnimationState[
|
||||
key as keyof InteractiveSceneRenderAnimationState
|
||||
] !== undefined
|
||||
) {
|
||||
return nextAnimationState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
renderInteractiveScene(
|
||||
{
|
||||
canvas: props.canvas,
|
||||
elementsMap: props.elementsMap,
|
||||
visibleElements: props.visibleElements,
|
||||
selectedElements: props.selectedElements,
|
||||
allElementsMap: props.allElementsMap,
|
||||
scale: window.devicePixelRatio,
|
||||
appState: props.appState,
|
||||
renderConfig: {
|
||||
remotePointerViewportCoords,
|
||||
remotePointerButton,
|
||||
remoteSelectedElementIds,
|
||||
remotePointerUsernames,
|
||||
remotePointerUserStates,
|
||||
selectionColor,
|
||||
renderScrollbars: props.renderScrollbars,
|
||||
},
|
||||
);
|
||||
}
|
||||
device: props.device,
|
||||
callback: props.renderInteractiveSceneCallback,
|
||||
},
|
||||
isRenderThrottlingEnabled(),
|
||||
);
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -35,16 +35,10 @@ const DropdownMenu = ({
|
||||
: MenuContentComp;
|
||||
|
||||
return (
|
||||
<div
|
||||
className="dropdown-menu-container"
|
||||
style={{
|
||||
// remove this div from box layout
|
||||
display: "contents",
|
||||
}}
|
||||
>
|
||||
<>
|
||||
{MenuTriggerComp}
|
||||
{open && MenuContentCompWithPlacement}
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ import { EVENT, KEYS } from "@excalidraw/common";
|
||||
|
||||
import { useOutsideClick } from "../../hooks/useOutsideClick";
|
||||
import { useStable } from "../../hooks/useStable";
|
||||
import { useEditorInterface } from "../App";
|
||||
import { useDevice } from "../App";
|
||||
import { Island } from "../Island";
|
||||
import Stack from "../Stack";
|
||||
|
||||
@@ -29,20 +29,13 @@ const MenuContent = ({
|
||||
style?: React.CSSProperties;
|
||||
placement?: "top" | "bottom";
|
||||
}) => {
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
const menuRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
const callbacksRef = useStable({ onClickOutside });
|
||||
|
||||
useOutsideClick(menuRef, (event) => {
|
||||
// prevents closing if clicking on the trigger button
|
||||
if (
|
||||
!menuRef.current
|
||||
?.closest(".dropdown-menu-container")
|
||||
?.contains(event.target)
|
||||
) {
|
||||
callbacksRef.onClickOutside?.();
|
||||
}
|
||||
useOutsideClick(menuRef, () => {
|
||||
callbacksRef.onClickOutside?.();
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
@@ -66,7 +59,7 @@ const MenuContent = ({
|
||||
}, [callbacksRef]);
|
||||
|
||||
const classNames = clsx(`dropdown-menu ${className}`, {
|
||||
"dropdown-menu--mobile": editorInterface.formFactor === "phone",
|
||||
"dropdown-menu--mobile": device.editor.isMobile,
|
||||
"dropdown-menu--placement-top": placement === "top",
|
||||
}).trim();
|
||||
|
||||
@@ -80,8 +73,13 @@ const MenuContent = ({
|
||||
>
|
||||
{/* the zIndex ensures this menu has higher stacking order,
|
||||
see https://github.com/excalidraw/excalidraw/pull/1445 */}
|
||||
{editorInterface.formFactor === "phone" ? (
|
||||
<Stack.Col className="dropdown-menu-container">{children}</Stack.Col>
|
||||
{device.editor.isMobile ? (
|
||||
<Stack.Col
|
||||
className="dropdown-menu-container"
|
||||
style={{ ["--gap" as any]: 1.25 }}
|
||||
>
|
||||
{children}
|
||||
</Stack.Col>
|
||||
) : (
|
||||
<Island
|
||||
className="dropdown-menu-container"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEditorInterface } from "../App";
|
||||
import { useDevice } from "../App";
|
||||
|
||||
import { Ellipsify } from "../Ellipsify";
|
||||
|
||||
@@ -15,14 +15,14 @@ const MenuItemContent = ({
|
||||
textStyle?: React.CSSProperties;
|
||||
children: React.ReactNode;
|
||||
}) => {
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
return (
|
||||
<>
|
||||
{icon && <div className="dropdown-menu-item__icon">{icon}</div>}
|
||||
<div style={textStyle} className="dropdown-menu-item__text">
|
||||
<Ellipsify>{children}</Ellipsify>
|
||||
</div>
|
||||
{shortcut && editorInterface.formFactor !== "phone" && (
|
||||
{shortcut && !device.editor.isMobile && (
|
||||
<div className="dropdown-menu-item__shortcut">{shortcut}</div>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEditorInterface } from "../App";
|
||||
import { useDevice } from "../App";
|
||||
import { RadioGroup } from "../RadioGroup";
|
||||
|
||||
type Props<T> = {
|
||||
@@ -22,7 +22,7 @@ const DropdownMenuItemContentRadio = <T,>({
|
||||
children,
|
||||
name,
|
||||
}: Props<T>) => {
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
|
||||
return (
|
||||
<>
|
||||
@@ -37,7 +37,7 @@ const DropdownMenuItemContentRadio = <T,>({
|
||||
choices={choices}
|
||||
/>
|
||||
</div>
|
||||
{shortcut && editorInterface.formFactor !== "phone" && (
|
||||
{shortcut && !device.editor.isMobile && (
|
||||
<div className="dropdown-menu-item__shortcut dropdown-menu-item__shortcut--orphaned">
|
||||
{shortcut}
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import clsx from "clsx";
|
||||
|
||||
import { useEditorInterface } from "../App";
|
||||
import { useDevice } from "../App";
|
||||
|
||||
const MenuTrigger = ({
|
||||
className = "",
|
||||
@@ -14,16 +14,17 @@ const MenuTrigger = ({
|
||||
onToggle: () => void;
|
||||
title?: string;
|
||||
} & Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, "onSelect">) => {
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
const classNames = clsx(
|
||||
`dropdown-menu-button ${className}`,
|
||||
"zen-mode-transition",
|
||||
{
|
||||
"dropdown-menu-button--mobile": editorInterface.formFactor === "phone",
|
||||
"dropdown-menu-button--mobile": device.editor.isMobile,
|
||||
},
|
||||
).trim();
|
||||
return (
|
||||
<button
|
||||
data-prevent-outside-click
|
||||
className={classNames}
|
||||
onClick={onToggle}
|
||||
type="button"
|
||||
|
||||
@@ -2,7 +2,7 @@ import clsx from "clsx";
|
||||
|
||||
import { actionShortcuts } from "../../actions";
|
||||
import { useTunnels } from "../../context/tunnels";
|
||||
import { ExitZenModeButton, UndoRedoActions, ZoomActions } from "../Actions";
|
||||
import { ExitZenModeAction, UndoRedoActions, ZoomActions } from "../Actions";
|
||||
import { HelpButton } from "../HelpButton";
|
||||
import { Section } from "../Section";
|
||||
import Stack from "../Stack";
|
||||
@@ -66,7 +66,7 @@ const Footer = ({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<ExitZenModeButton
|
||||
<ExitZenModeAction
|
||||
actionManager={actionManager}
|
||||
showExitZenModeBtn={showExitZenModeBtn}
|
||||
/>
|
||||
|
||||
@@ -41,7 +41,7 @@ import { getTooltipDiv, updateTooltipPosition } from "../../components/Tooltip";
|
||||
|
||||
import { t } from "../../i18n";
|
||||
|
||||
import { useAppProps, useEditorInterface, useExcalidrawAppState } from "../App";
|
||||
import { useAppProps, useDevice, useExcalidrawAppState } from "../App";
|
||||
import { ToolButton } from "../ToolButton";
|
||||
import { FreedrawIcon, TrashIcon, elementLinkIcon } from "../icons";
|
||||
import { getSelectedElements } from "../../scene";
|
||||
@@ -88,7 +88,7 @@ export const Hyperlink = ({
|
||||
const elementsMap = scene.getNonDeletedElementsMap();
|
||||
const appState = useExcalidrawAppState();
|
||||
const appProps = useAppProps();
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
|
||||
const linkVal = element.link || "";
|
||||
|
||||
@@ -189,11 +189,11 @@ export const Hyperlink = ({
|
||||
if (
|
||||
isEditing &&
|
||||
inputRef?.current &&
|
||||
!(editorInterface.formFactor === "phone" || editorInterface.isTouchScreen)
|
||||
!(device.viewport.isMobile || device.isTouchScreen)
|
||||
) {
|
||||
inputRef.current.select();
|
||||
}
|
||||
}, [isEditing, editorInterface.formFactor, editorInterface.isTouchScreen]);
|
||||
}, [isEditing, device.viewport.isMobile, device.isTouchScreen]);
|
||||
|
||||
useEffect(() => {
|
||||
let timeoutId: number | null = null;
|
||||
|
||||
@@ -1160,7 +1160,7 @@ export const StrokeWidthBaseIcon = createIcon(
|
||||
modifiedTablerIconProps,
|
||||
);
|
||||
|
||||
export const StrokeWidthBoldIcon = createIcon(
|
||||
export const StrokeWidthMediumIcon = createIcon(
|
||||
<path
|
||||
d="M5 10h10"
|
||||
stroke="currentColor"
|
||||
@@ -1171,7 +1171,7 @@ export const StrokeWidthBoldIcon = createIcon(
|
||||
modifiedTablerIconProps,
|
||||
);
|
||||
|
||||
export const StrokeWidthExtraBoldIcon = createIcon(
|
||||
export const StrokeWidthBoldIcon = createIcon(
|
||||
<path
|
||||
d="M5 10h10"
|
||||
stroke="currentColor"
|
||||
@@ -1182,6 +1182,17 @@ export const StrokeWidthExtraBoldIcon = createIcon(
|
||||
modifiedTablerIconProps,
|
||||
);
|
||||
|
||||
export const StrokeWidthExtraBoldIcon = createIcon(
|
||||
<path
|
||||
d="M5 10h10"
|
||||
stroke="currentColor"
|
||||
strokeWidth="5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>,
|
||||
modifiedTablerIconProps,
|
||||
);
|
||||
|
||||
export const StrokeStyleSolidIcon = React.memo(({ theme }: { theme: Theme }) =>
|
||||
createIcon(
|
||||
<path
|
||||
@@ -2294,6 +2305,40 @@ export const elementLinkIcon = createIcon(
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const strokeWidthFixedIcon = createIcon(
|
||||
<g>
|
||||
<path
|
||||
d="M4 12 C 5 8, 6 8, 8 12"
|
||||
fill="none"
|
||||
strokeWidth="1"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M8 12 C 9 16, 10 16, 12 12"
|
||||
fill="none"
|
||||
strokeWidth="1"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M12 12 C 14 8, 15 8, 16 12"
|
||||
fill="none"
|
||||
strokeWidth="1"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M16 12 C 17 16, 18 16, 19 12"
|
||||
fill="none"
|
||||
strokeWidth="1"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</g>,
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const resizeIcon = createIcon(
|
||||
<g strokeWidth={1.5}>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
@@ -2303,6 +2348,40 @@ export const resizeIcon = createIcon(
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const strokeWidthVariableIcon = createIcon(
|
||||
<g>
|
||||
<path
|
||||
d="M4 12 C 5 8, 6 8, 8 12"
|
||||
fill="none"
|
||||
stroke-width="1.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M8 12 C 9 16, 10 16, 12 12"
|
||||
fill="none"
|
||||
stroke-width="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M12 12 C 14 8, 15 8, 16 12"
|
||||
fill="none"
|
||||
stroke-width="2.75"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="M16 12 C 17 16, 18 16, 19 12"
|
||||
fill="none"
|
||||
stroke-width="3.25"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</g>,
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const adjustmentsIcon = createIcon(
|
||||
<g strokeWidth={1.5}>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
@@ -2326,50 +2405,3 @@ export const strokeIcon = createIcon(
|
||||
</g>,
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const pencilIcon = createIcon(
|
||||
<g strokeWidth={1.25}>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M4 20h4l10.5 -10.5a2.828 2.828 0 1 0 -4 -4l-10.5 10.5v4" />
|
||||
<path d="M13.5 6.5l4 4" />
|
||||
</g>,
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const chevronLeftIcon = createIcon(
|
||||
<g strokeWidth={1}>
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M11 7l-5 5l5 5" />
|
||||
<path d="M17 7l-5 5l5 5" />
|
||||
</g>,
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const sidebarRightIcon = createIcon(
|
||||
<g strokeWidth="1.75">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M4 4m0 2a2 2 0 0 1 2 -2h12a2 2 0 0 1 2 2v12a2 2 0 0 1 -2 2h-12a2 2 0 0 1 -2 -2z" />
|
||||
<path d="M15 4l0 16" />
|
||||
</g>,
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const messageCircleIcon = createIcon(
|
||||
<g strokeWidth="1.25">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M3 20l1.3 -3.9c-2.324 -3.437 -1.426 -7.872 2.1 -10.374c3.526 -2.501 8.59 -2.296 11.845 .48c3.255 2.777 3.695 7.266 1.029 10.501c-2.666 3.235 -7.615 4.215 -11.574 2.293l-4.7 1" />
|
||||
</g>,
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
export const presentationIcon = createIcon(
|
||||
<g strokeWidth="1.25">
|
||||
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
|
||||
<path d="M3 4l18 0" />
|
||||
<path d="M4 4v10a2 2 0 0 0 2 2h12a2 2 0 0 0 2 -2v-10" />
|
||||
<path d="M12 16l0 4" />
|
||||
<path d="M9 20l6 0" />
|
||||
<path d="M8 12l3 -3l2 2l3 -3" />
|
||||
</g>,
|
||||
tablerIconProps,
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import clsx from "clsx";
|
||||
|
||||
import { MQ_MIN_WIDTH_DESKTOP, type EditorInterface } from "@excalidraw/common";
|
||||
import { isMobileOrTablet, MQ_MIN_WIDTH_DESKTOP } from "@excalidraw/common";
|
||||
|
||||
import { t } from "../../i18n";
|
||||
import { Button } from "../Button";
|
||||
@@ -12,18 +12,15 @@ import "./LiveCollaborationTrigger.scss";
|
||||
const LiveCollaborationTrigger = ({
|
||||
isCollaborating,
|
||||
onSelect,
|
||||
editorInterface,
|
||||
...rest
|
||||
}: {
|
||||
isCollaborating: boolean;
|
||||
onSelect: () => void;
|
||||
editorInterface?: EditorInterface;
|
||||
} & React.ButtonHTMLAttributes<HTMLButtonElement>) => {
|
||||
const appState = useUIAppState();
|
||||
|
||||
const showIconOnly =
|
||||
editorInterface?.formFactor !== "desktop" ||
|
||||
appState.width < MQ_MIN_WIDTH_DESKTOP;
|
||||
isMobileOrTablet() || appState.width < MQ_MIN_WIDTH_DESKTOP;
|
||||
|
||||
return (
|
||||
<Button
|
||||
|
||||
@@ -5,7 +5,7 @@ import { composeEventHandlers } from "@excalidraw/common";
|
||||
import { useTunnels } from "../../context/tunnels";
|
||||
import { useUIAppState } from "../../context/ui-appState";
|
||||
import { t } from "../../i18n";
|
||||
import { useEditorInterface, useExcalidrawSetAppState } from "../App";
|
||||
import { useDevice, useExcalidrawSetAppState } from "../App";
|
||||
import { UserList } from "../UserList";
|
||||
import DropdownMenu from "../dropdownMenu/DropdownMenu";
|
||||
import { withInternalFallback } from "../hoc/withInternalFallback";
|
||||
@@ -27,7 +27,7 @@ const MainMenu = Object.assign(
|
||||
onSelect?: (event: Event) => void;
|
||||
}) => {
|
||||
const { MainMenuTunnel } = useTunnels();
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
const appState = useUIAppState();
|
||||
const setAppState = useExcalidrawSetAppState();
|
||||
|
||||
@@ -53,24 +53,19 @@ const MainMenu = Object.assign(
|
||||
setAppState({ openMenu: null });
|
||||
})}
|
||||
placement="bottom"
|
||||
className={
|
||||
editorInterface.formFactor === "phone"
|
||||
? "main-menu-dropdown"
|
||||
: ""
|
||||
}
|
||||
className={device.editor.isMobile ? "main-menu-dropdown" : ""}
|
||||
>
|
||||
{children}
|
||||
{editorInterface.formFactor === "phone" &&
|
||||
appState.collaborators.size > 0 && (
|
||||
<fieldset className="UserList-Wrapper">
|
||||
<legend>{t("labels.collaborators")}</legend>
|
||||
<UserList
|
||||
mobile={true}
|
||||
collaborators={appState.collaborators}
|
||||
userToFollow={appState.userToFollow?.socketId || null}
|
||||
/>
|
||||
</fieldset>
|
||||
)}
|
||||
{device.editor.isMobile && appState.collaborators.size > 0 && (
|
||||
<fieldset className="UserList-Wrapper">
|
||||
<legend>{t("labels.collaborators")}</legend>
|
||||
<UserList
|
||||
mobile={true}
|
||||
collaborators={appState.collaborators}
|
||||
userToFollow={appState.userToFollow?.socketId || null}
|
||||
/>
|
||||
</fieldset>
|
||||
)}
|
||||
</DropdownMenu.Content>
|
||||
</DropdownMenu>
|
||||
</MainMenuTunnel.In>
|
||||
|
||||
@@ -3,7 +3,7 @@ import { getShortcutFromShortcutName } from "../../actions/shortcuts";
|
||||
import { useTunnels } from "../../context/tunnels";
|
||||
import { useUIAppState } from "../../context/ui-appState";
|
||||
import { t, useI18n } from "../../i18n";
|
||||
import { useEditorInterface, useExcalidrawActionManager } from "../App";
|
||||
import { useDevice, useExcalidrawActionManager } from "../App";
|
||||
import { ExcalidrawLogo } from "../ExcalidrawLogo";
|
||||
import { HelpIcon, LoadIcon, usersIcon } from "../icons";
|
||||
|
||||
@@ -18,12 +18,12 @@ const WelcomeScreenMenuItemContent = ({
|
||||
shortcut?: string | null;
|
||||
children: React.ReactNode;
|
||||
}) => {
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
return (
|
||||
<>
|
||||
<div className="welcome-screen-menu-item__icon">{icon}</div>
|
||||
<div className="welcome-screen-menu-item__text">{children}</div>
|
||||
{shortcut && editorInterface.formFactor !== "phone" && (
|
||||
{shortcut && !device.editor.isMobile && (
|
||||
<div className="welcome-screen-menu-item__shortcut">{shortcut}</div>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -13,10 +13,10 @@
|
||||
--zIndex-hyperlinkContainer: 7;
|
||||
|
||||
--zIndex-ui-bottom: 60;
|
||||
--zIndex-ui-library: 80;
|
||||
--zIndex-ui-context-menu: 90;
|
||||
--zIndex-ui-styles-popup: 100;
|
||||
--zIndex-ui-top: 100;
|
||||
--zIndex-ui-library: 120;
|
||||
|
||||
--zIndex-modal: 1000;
|
||||
--zIndex-popup: 1001;
|
||||
@@ -50,11 +50,6 @@ body.excalidraw-cursor-resize * {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
button {
|
||||
// browser default. Looks kinda good on low-dpi.
|
||||
font-size: 0.8333rem;
|
||||
}
|
||||
|
||||
button,
|
||||
label {
|
||||
@include buttonNoHighlight;
|
||||
@@ -298,8 +293,7 @@ body.excalidraw-cursor-resize * {
|
||||
}
|
||||
}
|
||||
|
||||
.excalidraw-ui-top-left,
|
||||
.excalidraw-ui-top-right {
|
||||
.excalidraw-ui-top-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
@@ -713,11 +707,6 @@ body.excalidraw-cursor-resize * {
|
||||
margin-top: 0rem;
|
||||
}
|
||||
}
|
||||
|
||||
.link-button {
|
||||
display: flex;
|
||||
text-decoration: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.ErrorSplash.excalidraw {
|
||||
|
||||
@@ -304,6 +304,8 @@ export const restoreElement = (
|
||||
lastCommittedPoint: null,
|
||||
simulatePressure: element.simulatePressure,
|
||||
pressures: element.pressures,
|
||||
// legacy, for backwards compatibility
|
||||
freedrawOptions: element.freedrawOptions ?? null,
|
||||
});
|
||||
}
|
||||
case "image":
|
||||
|
||||
@@ -30,7 +30,7 @@ import { getBoundTextElementId } from "@excalidraw/element";
|
||||
|
||||
import type { Bounds } from "@excalidraw/element";
|
||||
|
||||
import type { GlobalPoint, LineSegment } from "@excalidraw/math";
|
||||
import type { GlobalPoint, LineSegment } from "@excalidraw/math/types";
|
||||
import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types";
|
||||
|
||||
import { AnimatedTrail } from "../animated-trail";
|
||||
|
||||
@@ -2,7 +2,7 @@ import { useState, useLayoutEffect } from "react";
|
||||
|
||||
import { THEME } from "@excalidraw/common";
|
||||
|
||||
import { useEditorInterface, useExcalidrawContainer } from "../components/App";
|
||||
import { useDevice, useExcalidrawContainer } from "../components/App";
|
||||
import { useUIAppState } from "../context/ui-appState";
|
||||
|
||||
export const useCreatePortalContainer = (opts?: {
|
||||
@@ -11,7 +11,7 @@ export const useCreatePortalContainer = (opts?: {
|
||||
}) => {
|
||||
const [div, setDiv] = useState<HTMLDivElement | null>(null);
|
||||
|
||||
const editorInterface = useEditorInterface();
|
||||
const device = useDevice();
|
||||
const { theme } = useUIAppState();
|
||||
|
||||
const { container: excalidrawContainer } = useExcalidrawContainer();
|
||||
@@ -20,13 +20,10 @@ export const useCreatePortalContainer = (opts?: {
|
||||
if (div) {
|
||||
div.className = "";
|
||||
div.classList.add("excalidraw", ...(opts?.className?.split(/\s+/) || []));
|
||||
div.classList.toggle(
|
||||
"excalidraw--mobile",
|
||||
editorInterface.formFactor === "phone",
|
||||
);
|
||||
div.classList.toggle("excalidraw--mobile", device.editor.isMobile);
|
||||
div.classList.toggle("theme--dark", theme === THEME.DARK);
|
||||
}
|
||||
}, [div, theme, editorInterface.formFactor, opts?.className]);
|
||||
}, [div, theme, device.editor.isMobile, opts?.className]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
const container = opts?.parentSelector
|
||||
|
||||
@@ -5,7 +5,7 @@ import { EVENT } from "@excalidraw/common";
|
||||
export function useOutsideClick<T extends HTMLElement>(
|
||||
ref: React.RefObject<T | null>,
|
||||
/** if performance is of concern, memoize the callback */
|
||||
callback: (event: Event & { target: T }) => void,
|
||||
callback: (event: Event) => void,
|
||||
/**
|
||||
* Optional callback which is called on every click.
|
||||
*
|
||||
|
||||
@@ -251,7 +251,7 @@ export {
|
||||
loadSceneOrLibraryFromBlob,
|
||||
loadLibraryFromBlob,
|
||||
} from "./data/blob";
|
||||
export { getFreeDrawSvgPath } from "@excalidraw/element";
|
||||
export { getFreeDrawSvgPath } from "@excalidraw/element/freedraw";
|
||||
export { mergeLibraryItems, getLibraryItemsHash } from "./data/library";
|
||||
export { isLinearElement } from "@excalidraw/element";
|
||||
|
||||
@@ -263,9 +263,6 @@ export {
|
||||
DEFAULT_LASER_COLOR,
|
||||
UserIdleState,
|
||||
normalizeLink,
|
||||
sceneCoordsToViewportCoords,
|
||||
viewportCoordsToSceneCoords,
|
||||
getFormFactor,
|
||||
} from "@excalidraw/common";
|
||||
|
||||
export {
|
||||
@@ -278,12 +275,17 @@ export { CaptureUpdateAction } from "@excalidraw/element";
|
||||
|
||||
export { parseLibraryTokensFromUrl, useHandleLibrary } from "./data/library";
|
||||
|
||||
export {
|
||||
sceneCoordsToViewportCoords,
|
||||
viewportCoordsToSceneCoords,
|
||||
} from "@excalidraw/common";
|
||||
|
||||
export { Sidebar } from "./components/Sidebar/Sidebar";
|
||||
export { Button } from "./components/Button";
|
||||
export { Footer };
|
||||
export { MainMenu };
|
||||
export { Ellipsify } from "./components/Ellipsify";
|
||||
export { useEditorInterface, useStylesPanelMode } from "./components/App";
|
||||
export { useDevice } from "./components/App";
|
||||
export { WelcomeScreen };
|
||||
export { LiveCollaborationTrigger };
|
||||
export { Stats } from "./components/Stats";
|
||||
|
||||
@@ -15,7 +15,7 @@ import {
|
||||
intersectElementWithLineSegment,
|
||||
} from "@excalidraw/element";
|
||||
|
||||
import type { ElementsSegmentsMap, GlobalPoint } from "@excalidraw/math";
|
||||
import type { ElementsSegmentsMap, GlobalPoint } from "@excalidraw/math/types";
|
||||
import type { ElementsMap, ExcalidrawElement } from "@excalidraw/element/types";
|
||||
|
||||
export const getLassoSelectedElementIds = (input: {
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"copyAsPng": "نسخ إلى الحافظة بصيغة PNG",
|
||||
"copyAsSvg": "نسخ إلى الحافظة بصيغة SVG",
|
||||
"copyText": "نسخ إلى الحافظة كنص",
|
||||
"copySource": "نسخ المصدر إلى الحافظة",
|
||||
"convertToCode": "تحويل إلى كود",
|
||||
"copySource": "",
|
||||
"convertToCode": "",
|
||||
"bringForward": "جلب للأمام",
|
||||
"sendToBack": "أرسل للخلف",
|
||||
"bringToFront": "أحضر للأمام",
|
||||
@@ -21,9 +21,7 @@
|
||||
"copyStyles": "نسخ الأنماط",
|
||||
"pasteStyles": "لصق الأنماط",
|
||||
"stroke": "الخط",
|
||||
"changeStroke": "تغيير لون القلم",
|
||||
"background": "الخلفية",
|
||||
"changeBackground": "تغيير لون الخلفية",
|
||||
"fill": "التعبئة",
|
||||
"strokeWidth": "سُمك الخط",
|
||||
"strokeStyle": "نمط الخط",
|
||||
@@ -40,20 +38,12 @@
|
||||
"arrowhead_none": "لا شيء",
|
||||
"arrowhead_arrow": "سهم",
|
||||
"arrowhead_bar": "شريط",
|
||||
"arrowhead_circle": "دائرة",
|
||||
"arrowhead_circle_outline": "دائرة (مخططة)",
|
||||
"arrowhead_circle": "",
|
||||
"arrowhead_circle_outline": "",
|
||||
"arrowhead_triangle": "مثلث",
|
||||
"arrowhead_triangle_outline": "مثلث (مخطط)",
|
||||
"arrowhead_diamond": "ألماسة",
|
||||
"arrowhead_diamond_outline": "ألماسة (مخططة)",
|
||||
"arrowhead_crowfoot_many": "Crow's foot (many)",
|
||||
"arrowhead_crowfoot_one": "Crow's foot (one)",
|
||||
"arrowhead_crowfoot_one_or_many": "Crow's foot (one or many)",
|
||||
"more_options": "خيارات إضافية",
|
||||
"arrowtypes": "نوع السهم",
|
||||
"arrowtype_sharp": "سهم حاد",
|
||||
"arrowtype_round": "سهم منحني",
|
||||
"arrowtype_elbowed": "سهم زاوي",
|
||||
"arrowhead_triangle_outline": "",
|
||||
"arrowhead_diamond": "",
|
||||
"arrowhead_diamond_outline": "",
|
||||
"fontSize": "حجم الخط",
|
||||
"fontFamily": "نوع الخط",
|
||||
"addWatermark": "إضافة \"مصنوعة بواسطة Excalidraw\"",
|
||||
@@ -63,7 +53,7 @@
|
||||
"small": "صغير",
|
||||
"medium": "متوسط",
|
||||
"large": "كبير",
|
||||
"veryLarge": "كبير جدًا",
|
||||
"veryLarge": "كبير جدا",
|
||||
"solid": "كامل",
|
||||
"hachure": "خطوط",
|
||||
"zigzag": "متعرج",
|
||||
@@ -77,12 +67,11 @@
|
||||
"architect": "معماري",
|
||||
"artist": "رسام",
|
||||
"cartoonist": "كرتوني",
|
||||
"fileTitle": "اسم الملف",
|
||||
"fileTitle": "إسم الملف",
|
||||
"colorPicker": "منتقي اللون",
|
||||
"canvasColors": "تستخدم على القماش",
|
||||
"canvasBackground": "خلفية اللوحة",
|
||||
"drawingCanvas": "لوحة الرسم",
|
||||
"clearCanvas": "مسح اللوحة",
|
||||
"layers": "الطبقات",
|
||||
"actions": "الإجراءات",
|
||||
"language": "اللغة",
|
||||
@@ -95,31 +84,28 @@
|
||||
"group": "تحديد مجموعة",
|
||||
"ungroup": "إلغاء تحديد مجموعة",
|
||||
"collaborators": "المتعاونون",
|
||||
"toggleGrid": "تبديل الشبكة",
|
||||
"showGrid": "إظهار الشبكة",
|
||||
"addToLibrary": "أضف إلى المكتبة",
|
||||
"removeFromLibrary": "حذف من المكتبة",
|
||||
"libraryLoadingMessage": "جارٍ تحميل المكتبة...",
|
||||
"libraryLoadingMessage": "جارٍ تحميل المكتبة…",
|
||||
"libraries": "تصفح المكتبات",
|
||||
"loadingScene": "جارٍ تحميل المشهد…",
|
||||
"loadScene": "تحميل المشهد من ملف",
|
||||
"loadingScene": "جاري تحميل المشهد…",
|
||||
"align": "محاذاة",
|
||||
"alignTop": "محاذاة إلى الأعلى",
|
||||
"alignBottom": "محاذاة إلى الأسفل",
|
||||
"alignTop": "محاذاة إلى اﻷعلى",
|
||||
"alignBottom": "محاذاة إلى اﻷسفل",
|
||||
"alignLeft": "محاذاة إلى اليسار",
|
||||
"alignRight": "محاذاة إلى اليمين",
|
||||
"centerVertically": "توسيط عمودي",
|
||||
"centerHorizontally": "توسيط أفقي",
|
||||
"distributeHorizontally": "التوزيع الأفقي",
|
||||
"distributeVertically": "التوزيع عموديًا",
|
||||
"flipHorizontal": "قلب أفقي",
|
||||
"flipVertical": "قلب عمودي",
|
||||
"distributeVertically": "التوزيع عمودياً",
|
||||
"flipHorizontal": "قلب عامودي",
|
||||
"flipVertical": "قلب أفقي",
|
||||
"viewMode": "نمط العرض",
|
||||
"share": "مشاركة",
|
||||
"showStroke": "إظهار منتقي لون الخط",
|
||||
"showBackground": "إظهار منتقي لون الخلفية",
|
||||
"showFonts": "إظهار منتقي الخط",
|
||||
"toggleTheme": "تبديل الوضع الفاتح/الداكن",
|
||||
"theme": "السمة",
|
||||
"toggleTheme": "غير النمط",
|
||||
"personalLib": "المكتبة الشخصية",
|
||||
"excalidrawLib": "مكتبتنا",
|
||||
"decreaseFontSize": "تصغير حجم الخط",
|
||||
@@ -129,21 +115,16 @@
|
||||
"createContainerFromText": "نص مغلف في حاوية",
|
||||
"link": {
|
||||
"edit": "تعديل الرابط",
|
||||
"editEmbed": "تعديل الرابط القابل للتضمين",
|
||||
"create": "إضافة رابط",
|
||||
"editEmbed": "تحرير الرابط وإدراجه",
|
||||
"create": "إنشاء رابط",
|
||||
"createEmbed": "إنشاء رابط و إدراجه",
|
||||
"label": "رابط",
|
||||
"labelEmbed": "رابط وإدراج",
|
||||
"empty": "لم يتم تعيين رابط",
|
||||
"hint": "اكتب أو الصق الرابط هنا",
|
||||
"goToElement": "الانتقال إلى العنصر المستهدف"
|
||||
"labelEmbed": "رابط و إدراج",
|
||||
"empty": "لم يتم تعيين رابط"
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "تحرير السطر",
|
||||
"editArrow": "تحرير السهم"
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"exit": "الخروج من المُحرر"
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "قفل",
|
||||
@@ -156,47 +137,13 @@
|
||||
"selectAllElementsInFrame": "تحديد جميع العناصر في الإطار",
|
||||
"removeAllElementsFromFrame": "إزالة جميع العناصر من الإطار",
|
||||
"eyeDropper": "اختيار اللون من القماش",
|
||||
"textToDiagram": "نص إلى رسم بياني",
|
||||
"prompt": "تعليمات",
|
||||
"followUs": "تابعنا",
|
||||
"discordChat": "دردشة ديسكورد",
|
||||
"zoomToFitViewport": "التكبير لتناسب العرض",
|
||||
"zoomToFitSelection": "تكبير للعنصر المحدد",
|
||||
"zoomToFit": "تكبير لتلائم جميع العناصر",
|
||||
"installPWA": "تثبيت Excalidraw محليًا (PWA)",
|
||||
"autoResize": "تمكين تغيير حجم النص تلقائيًا",
|
||||
"imageCropping": "قص الصورة",
|
||||
"unCroppedDimension": "الأبعاد غير المقصوصة",
|
||||
"copyElementLink": "نسخ رابط الكائن",
|
||||
"linkToElement": "رابط إلى الكائن",
|
||||
"wrapSelectionInFrame": "تغليف التحديد في إطار",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "رابط إلى الكائن",
|
||||
"desc": "انقر على شكل على اللوحة أو الصق رابطًا.",
|
||||
"notFound": "لم يتم العثور على الكائن المرتبط على اللوحة."
|
||||
"textToDiagram": "",
|
||||
"prompt": ""
|
||||
},
|
||||
"library": {
|
||||
"noItems": "لا توجد عناصر أضيفت بعد...",
|
||||
"hint_emptyLibrary": "حدد عنصر على القماش لإضافته هنا، أو تثبيت مكتبة من المستودع العام أدناه.",
|
||||
"hint_emptyPrivateLibrary": "حدد عنصر على القماش لإضافته هنا.",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "البحث على اللوحة",
|
||||
"noMatch": "لم يتم العثور على تطابقات...",
|
||||
"singleResult": "نتيجة",
|
||||
"multipleResults": "نتائج",
|
||||
"placeholder": "ابحث عن نص على اللوحة...",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"hint_emptyPrivateLibrary": "حدد عنصر على القماش لإضافته هنا."
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "إعادة تعيين اللوحة",
|
||||
@@ -204,17 +151,16 @@
|
||||
"exportImage": "تصدير الصورة...",
|
||||
"export": "حفظ إلى...",
|
||||
"copyToClipboard": "نسخ إلى الحافظة",
|
||||
"copyLink": "نسخ الرابط",
|
||||
"save": "احفظ للملف الحالي",
|
||||
"saveAs": "حفظ كـ",
|
||||
"load": "فتح",
|
||||
"getShareableLink": "احصل على رابط المشاركة",
|
||||
"close": "إغلاق",
|
||||
"close": "غلق",
|
||||
"selectLanguage": "اختر اللغة",
|
||||
"scrollBackToContent": "الرجوع إلى المحتوى",
|
||||
"zoomIn": "تكبير",
|
||||
"zoomOut": "تصغير",
|
||||
"resetZoom": "إعادة تعيين التكبير",
|
||||
"resetZoom": "إعادة تعيين الشاشة",
|
||||
"menu": "القائمة",
|
||||
"done": "تم",
|
||||
"edit": "تعديل",
|
||||
@@ -225,56 +171,53 @@
|
||||
"fullScreen": "شاشة كاملة",
|
||||
"darkMode": "الوضع المظلم",
|
||||
"lightMode": "الوضع المضيء",
|
||||
"systemMode": "وضع النظام",
|
||||
"zenMode": "وضع التأمل",
|
||||
"objectsSnapMode": "التقاط إلى العناصر",
|
||||
"exitZenMode": "إلغاء وضع التأمل",
|
||||
"objectsSnapMode": "التقط إلى العناصر",
|
||||
"exitZenMode": "إلغاء الوضع الليلى",
|
||||
"cancel": "إلغاء",
|
||||
"saveLibNames": "",
|
||||
"clear": "مسح",
|
||||
"remove": "إزالة",
|
||||
"embed": "تبديل الإدراج",
|
||||
"publishLibrary": "",
|
||||
"submit": "إرسال",
|
||||
"publishLibrary": "انشر",
|
||||
"submit": "أرسل",
|
||||
"confirm": "تأكيد",
|
||||
"embeddableInteractionButton": "اضغط للتفاعل"
|
||||
},
|
||||
"alerts": {
|
||||
"clearReset": "هذا سيُزيل كامل اللوحة. هل أنت متأكد؟",
|
||||
"couldNotCreateShareableLink": "تعذر إنشاء رابط المشاركة.",
|
||||
"couldNotCreateShareableLink": "تعذر إنشاء رابطة المشاركة.",
|
||||
"couldNotCreateShareableLinkTooBig": "تعذر إنشاء رابط قابل للمشاركة: المشهد كبير جدًا",
|
||||
"couldNotLoadInvalidFile": "تعذر التحميل، الملف غير صالح",
|
||||
"importBackendFailed": "فشل الاستيراد من الخادم.",
|
||||
"importBackendFailed": "فشل الاستيراد من الخادوم.",
|
||||
"cannotExportEmptyCanvas": "لا يمكن تصدير لوحة فارغة.",
|
||||
"couldNotCopyToClipboard": "تعذر النسخ إلى الحافظة.",
|
||||
"decryptFailed": "تعذر فك تشفير البيانات.",
|
||||
"uploadedSecurly": "تم تأمين التحميل بتشفير النهاية إلى النهاية، مما يعني أن خادم Excalidraw والأطراف الثالثة لا يمكنها قراءة المحتوى.",
|
||||
"uploadedSecurly": "تم تأمين التحميل بتشفير النهاية إلى النهاية، مما يعني أن خادوم Excalidraw والأطراف الثالثة لا يمكنها قراءة المحتوى.",
|
||||
"loadSceneOverridePrompt": "تحميل الرسم الخارجي سيحل محل المحتوى الموجود لديك. هل ترغب في المتابعة؟",
|
||||
"collabStopOverridePrompt": "إيقاف الجلسة سيؤدي إلى الكتابة فوق رسومك السابقة المخزنة داخليًا. هل أنت متأكد؟\n\n(إذا كنت ترغب في الاحتفاظ برسمك المخزن داخليًا، أغلق علامة تبويب المتصفح بدلاً من ذلك.)",
|
||||
"errorAddingToLibrary": "تعذر إضافة العنصر إلى المكتبة",
|
||||
"collabStopOverridePrompt": "إيقاف الجلسة سيؤدي إلى الكتابة فوق رسومك السابقة المخزنة داخليا. هل أنت متأكد؟\n\n(إذا كنت ترغب في الاحتفاظ برسمك المخزن داخليا، ببساطة أغلق علامة تبويب المتصفح بدلاً من ذلك.)",
|
||||
"errorAddingToLibrary": "تعذر إضافة العنصر للمكتبة",
|
||||
"errorRemovingFromLibrary": "تعذر إزالة العنصر من المكتبة",
|
||||
"confirmAddLibrary": "هذا سيضيف {{numShapes}} شكل إلى مكتبتك. هل أنت متأكد؟",
|
||||
"imageDoesNotContainScene": "يبدو أن هذه الصورة لا تحتوي على أي بيانات مشهد. هل قمت بتمكين تضمين المشهد أثناء التصدير؟",
|
||||
"cannotRestoreFromImage": "تعذر استعادة المشهد من ملف الصورة",
|
||||
"invalidSceneUrl": "تعذر استيراد المشهد من عنوان URL المتوفر. إما أنها مشوهة، أو لا تحتوي على بيانات Excalidraw JSON صالحة.",
|
||||
"resetLibrary": "هذا سيؤدي إلى مسح مكتبتك. هل أنت متأكد؟",
|
||||
"resetLibrary": "هذا سوف يمسح مكتبتك. هل أنت متأكد؟",
|
||||
"removeItemsFromsLibrary": "حذف {{count}} عنصر (عناصر) من المكتبة؟",
|
||||
"invalidEncryptionKey": "مفتاح التشفير يجب أن يكون من 22 حرفًا. التعاون المباشر معطل.",
|
||||
"collabOfflineWarning": "لا يوجد اتصال بالإنترنت.\nلن يتم حفظ التغييرات التي قمت بها!",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"invalidEncryptionKey": "مفتاح التشفير يجب أن يكون من 22 حرفاً. التعاون المباشر معطل.",
|
||||
"collabOfflineWarning": "لا يوجد اتصال بالانترنت.\nلن يتم حفظ التغييرات التي قمت بها!"
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "نوع الملف غير مدعوم.",
|
||||
"imageInsertError": "تعذر إدراج الصورة. حاول مرة أخرى لاحقًا...",
|
||||
"fileTooBig": "الملف كبير جدًا. الحد الأقصى المسموح به للحجم هو {{maxSize}}.",
|
||||
"imageInsertError": "تعذر إدراج الصورة. حاول مرة أخرى لاحقاً...",
|
||||
"fileTooBig": "الملف كبير جداً. الحد الأقصى المسموح به للحجم هو {{maxSize}}.",
|
||||
"svgImageInsertError": "تعذر إدراج صورة SVG. يبدو أن ترميز SVG غير صحيح.",
|
||||
"failedToFetchImage": "فشل تحميل الصورة.",
|
||||
"failedToFetchImage": "",
|
||||
"invalidSVGString": "SVG غير صالح.",
|
||||
"cannotResolveCollabServer": "تعذر الاتصال بخادم التعاون. الرجاء إعادة تحميل الصفحة والمحاولة مرة أخرى.",
|
||||
"importLibraryError": "تعذر تحميل المكتبة",
|
||||
"saveLibraryError": "تعذر حفظ المكتبة. الرجاء حفظ المكتبة الخاصة بك في ملف محلي للتأكد من أنك لا تفقد التغييرات.",
|
||||
"collabSaveFailed": "تعذر الحفظ في قاعدة البيانات. إذا استمرت المشاكل، يُفضل حفظ ملفك محليًا كي لا تفقد عملك.",
|
||||
"collabSaveFailed_sizeExceeded": "تعذر الحفظ في قاعدة البيانات، يبدو أن القماش كبير للغاية، يُفضل حفظ الملف محليًا كي لا تفقد عملك.",
|
||||
"imageToolNotSupported": "تم تعطيل الصور.",
|
||||
"collabSaveFailed": "تعذر الحفظ في قاعدة البيانات. إذا استمرت المشاكل، يفضل أن تحفظ ملفك محليا كي لا تفقد عملك.",
|
||||
"collabSaveFailed_sizeExceeded": "تعذر الحفظ في قاعدة البيانات، يبدو أن القماش كبير للغاية، يفضّل حفظ الملف محليا كي لا تفقد عملك.",
|
||||
"imageToolNotSupported": "",
|
||||
"brave_measure_text_error": {
|
||||
"line1": "يبدو أنك تستخدم متصفح Brave مع إعداد <bold>حظر صارم لتتبع البصمة</bold>.",
|
||||
"line2": "قد يؤدي هذا إلى كسر <bold>عناصر النص</bold> في الرسومات الخاصة بك.",
|
||||
@@ -283,16 +226,15 @@
|
||||
},
|
||||
"libraryElementTypeError": {
|
||||
"embeddable": "لا يمكن إضافة العناصر القابلة للتضمين في المكتبة.",
|
||||
"iframe": "لا يمكن إضافة عناصر IFrame إلى المكتبة.",
|
||||
"image": "سيتم دعم إضافة صور إلى المكتبة قريبًا!"
|
||||
"iframe": "",
|
||||
"image": "سوف يتم دعم إضافة صور إلى المكتبة قريباً!"
|
||||
},
|
||||
"asyncPasteFailedOnRead": "تعذر اللصق (تعذر القراءة من حافظة النظام).",
|
||||
"asyncPasteFailedOnParse": "تعذر اللصق.",
|
||||
"copyToSystemClipboardFailed": "تعذر النسخ إلى الحافظة."
|
||||
"asyncPasteFailedOnRead": "",
|
||||
"asyncPasteFailedOnParse": "",
|
||||
"copyToSystemClipboardFailed": ""
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "تحديد",
|
||||
"lasso": "",
|
||||
"image": "إدراج صورة",
|
||||
"rectangle": "مستطيل",
|
||||
"diamond": "مضلع",
|
||||
@@ -303,33 +245,17 @@
|
||||
"text": "نص",
|
||||
"library": "مكتبة",
|
||||
"lock": "الحفاظ على أداة التحديد نشطة بعد الرسم",
|
||||
"penMode": "وضع القلم - منع اللمس",
|
||||
"penMode": "وضع القلم - امنع اللمس",
|
||||
"link": "إضافة/تحديث الرابط للشكل المحدد",
|
||||
"eraser": "ممحاة",
|
||||
"frame": "أداة الإطار",
|
||||
"magicframe": "Wireframe إلى كود",
|
||||
"magicframe": "",
|
||||
"embeddable": "تضمين ويب",
|
||||
"laser": "مؤشر ليزر",
|
||||
"hand": "يد (أداة الإزاحة)",
|
||||
"extraTools": "المزيد من الأدوات",
|
||||
"mermaidToExcalidraw": "من Mermaid إلى Excalidraw",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "مستطيل",
|
||||
"diamond": "مضلع",
|
||||
"ellipse": "دائرة",
|
||||
"arrow": "سهم",
|
||||
"line": "خط",
|
||||
"freedraw": "رسم حر",
|
||||
"text": "نص",
|
||||
"image": "صورة",
|
||||
"group": "مجموعة",
|
||||
"frame": "إطار",
|
||||
"magicframe": "Wireframe إلى كود",
|
||||
"embeddable": "تضمين ويب",
|
||||
"selection": "تحديد",
|
||||
"iframe": "IFrame"
|
||||
"extraTools": "المزيد من أﻷدوات",
|
||||
"mermaidToExcalidraw": "",
|
||||
"magicSettings": ""
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "إجراءات اللوحة",
|
||||
@@ -337,115 +263,103 @@
|
||||
"shapes": "الأشكال"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"canvasPanning": "لتحريك القماش، اضغط على عجلة الفأرة أو مفتاح المسافة أثناء السحب، أو استخدم أداة اليد",
|
||||
"linearElement": "انقر لبدء نقاط متعددة، اسحب لخط واحد",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "انقر واسحب، أفرج عند الانتهاء",
|
||||
"freeDraw": "انقر واسحب، افرج عند الانتهاء",
|
||||
"text": "نصيحة: يمكنك أيضًا إضافة نص بالنقر المزدوج في أي مكان بأداة الاختيار",
|
||||
"embeddable": "اضغط مع السحب لإنشاء موقع ويب مضمّن",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"text_selected": "انقر نقراً مزدوجاً أو اضغط ادخال لتعديل النص",
|
||||
"text_editing": "اضغط على Esc أو (Ctrl أو Cmd) + Enter لإنهاء التعديل",
|
||||
"linearElementMulti": "انقر فوق النقطة الأخيرة أو اضغط على Esc أو Enter للإنهاء",
|
||||
"lockAngle": "يمكنك تقييد الزاوية بالضغط على SHIFT",
|
||||
"resize": "يمكنك تقييد النسب بالضغط على SHIFT أثناء تغيير الحجم،\nاضغط على ALT لتغيير الحجم من المركز",
|
||||
"resizeImage": "يمكنك تغيير الحجم بحرية بالضغط بأستمرار على SHIFT،\nاضغط بأستمرار على ALT أيضا لتغيير الحجم من المركز",
|
||||
"rotate": "يمكنك تقييد الزوايا من خلال الضغط على SHIFT أثناء الدوران",
|
||||
"lineEditor_info": "اضغط على مفتاح (Ctrl أو Cmd) و انقر بشكل مزدوج، أو اضغط على مفتاحي (Ctrl أو Cmd) و (Enter) لتعديل النقاط",
|
||||
"lineEditor_pointSelected": "اضغط على حذف لإزالة النقطة (النِّقَاط)، Ctrl/Cmd+D للتكرار، أو اسحب للانتقال",
|
||||
"lineEditor_nothingSelected": "اختر نقطة لتعديلها (اضغط على SHIFT لتحديد عدة نِقَاط),\nأو اضغط على ALT و انقر بالفأرة لإضافة نِقَاط جديدة",
|
||||
"placeImage": "انقر لوضع الصورة، أو انقر واسحب لتعيين حجمها يدوياً",
|
||||
"publishLibrary": "نشر مكتبتك",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"bindTextToElement": "اضغط على إدخال لإضافة نص",
|
||||
"deepBoxSelect": "اضغط على Ctrl\\Cmd للاختيار العميق، ولمنع السحب",
|
||||
"eraserRevert": "اضغط على Alt لاستعادة العناصر المعلَّمة للحذف",
|
||||
"firefox_clipboard_write": "يمكن على الأرجح تمكين هذه الميزة عن طريق تعيين علم \"dom.events.asyncClipboard.clipboardItem\" إلى \"true\". لتغيير أعلام المتصفح في Firefox، قم بزيارة صفحة \"about:config\".",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": "اضغط على Ctrl أو Cmd لتعطيل الالتقاط"
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "تعذر عرض المعاينة",
|
||||
"canvasTooBig": "قد تكون اللوحة كبيرة جدًا.",
|
||||
"canvasTooBig": "قد تكون اللوحة كبيرة جداً.",
|
||||
"canvasTooBigTip": "نصيحة: حاول تحريك العناصر البعيدة بشكل أقرب قليلاً."
|
||||
},
|
||||
"errorSplash": {
|
||||
"headingMain": "حدث خطأ. حاول <button>تحديث الصفحة</button>.",
|
||||
"clearCanvasMessage": "إذا لم تعمل إعادة التحميل، حاول مرة أخرى ",
|
||||
"clearCanvasCaveat": "هذا سيؤدي إلى فقدان العمل",
|
||||
"clearCanvasCaveat": " هذا سيؤدي إلى فقدان العمل ",
|
||||
"trackedToSentry": "تم تتبع الخطأ في المعرف {{eventId}} على نظامنا.",
|
||||
"openIssueMessage": "حرصنا على عدم إضافة معلومات المشهد في بلاغ الخطأ. في حال كون مشهدك لا يحمل أي معلومات خاصة، نرجو المتابعة على <button>نظام تتبع الأخطاء</button>. نرجو إضافة المعلومات أدناه بنسخها ولصقها في محتوى البلاغ على GitHub.",
|
||||
"openIssueMessage": "حرصنا على عدم إضافة معلومات المشهد في بلاغ الخطأ. في حال كون مشهدك لا يحمل أي معلومات خاصة نرجو المتابعة على <button>نظام تتبع الأخطاء</button>. نرجو إضافة المعلومات أدناه بنسخها ولصقها في محتوى البلاغ على GitHub.",
|
||||
"sceneContent": "محتوى المشهد:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": "أو"
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "ادعُ الأشخاص للتعاون في الرسم الخاص بك.",
|
||||
"desc_privacy": "لا تقلق، الجلسة مشفرة من النهاية إلى النهاية وخصوصية تمامًا. حتى خادمنا لا يستطيع رؤية ما ترسمه.",
|
||||
"desc_intro": "يمكنك دعوة الآخرين لمشاركتك نفس الجلسة التي تعمل عليها.",
|
||||
"desc_privacy": "لا تقلق، الجلسة تستخدم التشفير من النهاية إلى النهاية، لذلك فإن أي شيء ترسمه سيبقى خاصاً. لن يتمكن حتى الخادوم الخاص بنا من رؤية ما توصلت إليه.",
|
||||
"button_startSession": "بدء الجلسة",
|
||||
"button_stopSession": "إيقاف الجلسة",
|
||||
"desc_inProgressIntro": "تجري الآن جلسة تعاون مباشرة.",
|
||||
"desc_inProgressIntro": "تجري الآن المشاركة الحية.",
|
||||
"desc_shareLink": "شارك هذا الرابط مع أي شخص تريده أن يشاركك الجلسة:",
|
||||
"desc_exitSession": "إيقاف الجلسة سيؤدي إلى قطع الاتصال الخاص بك من الغرفة، ولكن ستتمكن من مواصلة العمل مع المشهد محليًا. لاحظ أن هذا لن يؤثر على الأشخاص الآخرين، وسيظلون قادرين على التعاون في إصدارهم.",
|
||||
"shareTitle": "الانضمام إلى جلسة تعاون مباشرة على Excalidraw"
|
||||
"desc_exitSession": "إيقاف الجلسة سيؤدي إلى قطع الاتصال الخاص بك من الغرفة، ولكن ستتمكن من مواصلة العمل مع المشهد، محليا. لاحظ أن هذا لن يؤثر على الأشخاص الآخرين، و سيظلون قادرين على التعاون في إصدارهم.",
|
||||
"shareTitle": "الانضمام إلى جلسة تعاون حية على Excalidraw"
|
||||
},
|
||||
"errorDialog": {
|
||||
"title": "خطأ"
|
||||
},
|
||||
"exportDialog": {
|
||||
"disk_title": "حفظ الملف على الجهاز",
|
||||
"disk_details": "تصدير بيانات المشهد إلى ملف يمكنك الاستيراد منه لاحقًا.",
|
||||
"disk_button": "حفظ إلى ملف",
|
||||
"disk_title": "حفظ الملف للجهاز",
|
||||
"disk_details": "تصدير بيانات المشهد إلى ملف يمكنك الاستيراد منه لاحقاً.",
|
||||
"disk_button": "إحفظ لملف",
|
||||
"link_title": "رابط قابل للمشاركة",
|
||||
"link_details": "تصدير الملف للمشاهدة فقط.",
|
||||
"link_button": "تصدير كرابط",
|
||||
"link_details": "صدر الملف للمشاهدة فقط.",
|
||||
"link_button": "التصدير كرابط",
|
||||
"excalidrawplus_description": "حفظ المشهد إلى مساحة العمل +Excalidraw الخاصة بك.",
|
||||
"excalidrawplus_button": "تصدير",
|
||||
"excalidrawplus_exportError": "تعذر التص несп في الوقت الحالي إلى +Excalidraw..."
|
||||
"excalidrawplus_exportError": "تعذر التصدير إلى +Excalidraw في الوقت الحالي..."
|
||||
},
|
||||
"helpDialog": {
|
||||
"blog": "اقرأ مدونتنا",
|
||||
"click": "انقر",
|
||||
"deepSelect": "تحديد عميق",
|
||||
"deepBoxSelect": "تحديد عميق داخل المربع، ومنع السحب",
|
||||
"createFlowchart": "إنشاء مخطط تدفق من عنصر عام",
|
||||
"navigateFlowchart": "التنقل في مخطط تدفق",
|
||||
"curvedArrow": "سهم منحني",
|
||||
"curvedLine": "خط منحني",
|
||||
"curvedArrow": "سهم مائل",
|
||||
"curvedLine": "خط مائل",
|
||||
"documentation": "دليل الاستخدام",
|
||||
"doubleClick": "انقر مرتين",
|
||||
"drag": "اسحب",
|
||||
"editor": "المحرر",
|
||||
"editLineArrowPoints": "تحرير نقاط السطر/السهم",
|
||||
"editLineArrowPoints": "تحرير سطر/نقاط سهم",
|
||||
"editText": "تعديل النص / إضافة تسمية",
|
||||
"github": "عثرت على مشكلة؟ أرسل",
|
||||
"github": "عثرت على مشكلة؟ إرسال",
|
||||
"howto": "اتبع التعليمات",
|
||||
"or": "أو",
|
||||
"preventBinding": "منع ارتباط السهم",
|
||||
"preventBinding": "منع ارتبط السهم",
|
||||
"tools": "الأدوات",
|
||||
"shortcuts": "اختصارات لوحة المفاتيح",
|
||||
"textFinish": "إنهاء التعديل (محرر النص)",
|
||||
"textNewLine": "إضافة سطر جديد (محرر النص)",
|
||||
"textNewLine": "أضف سطر جديد (محرر نص)",
|
||||
"title": "المساعدة",
|
||||
"view": "عرض",
|
||||
"zoomToFit": "تكبير للملائمة",
|
||||
"zoomToSelection": "تكبير للعنصر المحدد",
|
||||
"toggleElementLock": "قفل/فتح المحدد",
|
||||
"toggleElementLock": "إغلاق/فتح المحدد",
|
||||
"movePageUpDown": "نقل الصفحة أعلى/أسفل",
|
||||
"movePageLeftRight": "نقل الصفحة يسار/يمين",
|
||||
"cropStart": "بدء قص الصورة",
|
||||
"cropFinish": "إنهاء قص الصورة"
|
||||
"movePageLeftRight": "نقل الصفحة يسار/يمين"
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": "مسح اللوحة"
|
||||
},
|
||||
"publishDialog": {
|
||||
"title": "نشر المكتبة",
|
||||
"itemName": "اسم العنصر",
|
||||
"authorName": "اسم المؤلف",
|
||||
"githubUsername": "اسم المستخدم في GitHub",
|
||||
"itemName": "إسم العنصر",
|
||||
"authorName": "إسم المؤلف",
|
||||
"githubUsername": "اسم المستخدم في جيت هب",
|
||||
"twitterUsername": "اسم المستخدم في تويتر",
|
||||
"libraryName": "اسم المكتبة",
|
||||
"libraryDesc": "وصف المكتبة",
|
||||
@@ -454,24 +368,24 @@
|
||||
"authorName": "اسمك أو اسم المستخدم",
|
||||
"libraryName": "اسم مكتبتك",
|
||||
"libraryDesc": "وصف مكتبتك لمساعدة الناس على فهم استخدامها",
|
||||
"githubHandle": "معرف GitHub (اختياري)، حتى تتمكن من تحرير المكتبة عند إرسالها للمراجعة",
|
||||
"githubHandle": "معالج GitHub (اختياري)، حتى تتمكن من تحرير المكتبة عند إرسالها للمراجعة",
|
||||
"twitterHandle": "اسم مستخدم تويتر (اختياري)، حتى نعرف من الذي سيتم الإشارة إليه عند الترويج عبر تويتر",
|
||||
"website": "رابط إلى موقعك الشخصي أو مكان آخر (اختياري)"
|
||||
"website": "رابط إلى موقعك الشخصي أو في مكان آخر (اختياري)"
|
||||
},
|
||||
"errors": {
|
||||
"required": "مطلوب",
|
||||
"website": "أدخل عنوان URL صالح"
|
||||
},
|
||||
"noteDescription": "تقديم مكتبتك لتضمينها في مستودع المكتبة العامة <link></link> ليستخدمها الآخرون في رسوماتهم.",
|
||||
"noteGuidelines": "تحتاج المكتبة إلى الموافقة أولاً. يرجى قراءة <link>المعايير</link> قبل تقديمها. ستحتاج إلى حساب GitHub للتواصل وإجراء التغييرات عند الطلب، ولكنه ليس مطلوبًا بشكل صارم.",
|
||||
"noteLicense": "تقديمك يعني موافقتك على نشر المكتبة المقدمة تحت <link>ترخيص MIT</link>، مما يعني أن لأي شخص الحق في استخدامها دون قيود.",
|
||||
"noteItems": "يجب أن يكون لكل عنصر مكتبة اسم خاص به ليكون قابلًا للتصفية. سيتم تضمين عناصر المكتبة التالية:",
|
||||
"noteDescription": "تقديم مكتبتك لتضمينها في مستودع المكتبة العامة <link></link> لأشخاص آخرين لاستخدامها في رسومهم.",
|
||||
"noteGuidelines": "تحتاج المكتبة إلى الموافقة أولا. يرجى قراءة <link>المعايير</link> قبل تقديمها. سوف تحتاج إلى حساب GitHub للتواصل وإجراء التغييرات عند الطلب، ولكن ليس مطلوبا بشكل صارم.",
|
||||
"noteLicense": "تقديمك يعني موافقتك على نشر المكتبة المقدمة تحت <link>MIT ترخيص</link>، ما يعني أن لأي أحد الحق في استخدامها دون قيود.",
|
||||
"noteItems": "يجب أن يكون لكل عنصر مكتبة اسمه الخاص حتى يكون قابلاً للتصفية. سيتم تضمين عناصر المكتبة التالية:",
|
||||
"atleastOneLibItem": "يرجى تحديد عنصر مكتبة واحد على الأقل للبدء",
|
||||
"republishWarning": "ملاحظة: بعض العناصر المحددة معينة على أنها نُشرت أو قُدمت من قبل. يجب عليك فقط إعادة إرسال العناصر عند تحديث مكتبة موجودة أو إرسالها."
|
||||
"republishWarning": "ملاحظة: بعض العناصر المحددة معينة على أنه نشرها أو تقديمها من قبل. يجب عليك فقط إعادة إرسال العناصر عند تحديث مكتبة موجودة أو إرسالها."
|
||||
},
|
||||
"publishSuccessDialog": {
|
||||
"title": "تم إرسال المكتبة",
|
||||
"content": "شكرًا لك {{authorName}}. لقد تم إرسال مكتبتك للمراجعة. يمكنك تتبع الحالة"
|
||||
"content": "شكرا لك {{authorName}}. لقد تم إرسال مكتبتك للمراجعة. يمكنك تتبع الحالة"
|
||||
},
|
||||
"confirmDialog": {
|
||||
"resetLibrary": "إعادة ضبط المكتبة",
|
||||
@@ -480,15 +394,15 @@
|
||||
"imageExportDialog": {
|
||||
"header": "تصدير الصورة",
|
||||
"label": {
|
||||
"withBackground": "مع الخلفية",
|
||||
"withBackground": "الخلفية",
|
||||
"onlySelected": "المحدد فقط",
|
||||
"darkMode": "الوضع الداكن",
|
||||
"embedScene": "تضمين المشهد",
|
||||
"scale": "المقياس",
|
||||
"scale": "الحجم",
|
||||
"padding": "الهوامش"
|
||||
},
|
||||
"tooltip": {
|
||||
"embedScene": "سيتم حفظ بيانات المشهد في ملف PNG/SVG المصدر بحيث يمكن استعادة المشهد منه.\nسيزيد هذا من حجم الملف المصدر."
|
||||
"embedScene": "سيتم حفظ بيانات المشهد في ملف PNG/SVG المصدّر بحيث يمكن استعادة المشهد منه.\nسيزيد حجم الملف المصدر."
|
||||
},
|
||||
"title": {
|
||||
"exportToPng": "تصدير بصيغة PNG",
|
||||
@@ -502,20 +416,18 @@
|
||||
}
|
||||
},
|
||||
"encrypted": {
|
||||
"tooltip": "رسوماتك مشفرة من النهاية إلى النهاية، لذا لا يمكن لخوادم Excalidraw رؤيتها أبدًا.",
|
||||
"link": "مشاركة المدونة حول التشفير من النهاية إلى النهاية في Excalidraw"
|
||||
"tooltip": "رسوماتك مشفرة من النهاية إلى النهاية حتى أن خوادم Excalidraw لن تراها أبدا.",
|
||||
"link": "مشاركة المدونة في التشفير من النهاية إلى النهاية في Excalidraw"
|
||||
},
|
||||
"stats": {
|
||||
"angle": "الزاوية",
|
||||
"shapes": "الأشكال",
|
||||
"element": "عنصر",
|
||||
"elements": "العناصر",
|
||||
"height": "الارتفاع",
|
||||
"scene": "المشهد",
|
||||
"selected": "المحدد",
|
||||
"storage": "التخزين",
|
||||
"fullTitle": "خصائص اللوحة والأشكال",
|
||||
"title": "الخصائص",
|
||||
"generalStats": "عام",
|
||||
"elementProperties": "خصائص الشكل",
|
||||
"title": "إحصائيات للمهووسين",
|
||||
"total": "المجموع",
|
||||
"version": "الإصدار",
|
||||
"versionCopy": "انقر للنسخ",
|
||||
@@ -523,19 +435,17 @@
|
||||
"width": "العرض"
|
||||
},
|
||||
"toast": {
|
||||
"addedToLibrary": "تمت الإضافة إلى المكتبة!",
|
||||
"copyStyles": "تم نسخ الأنماط.",
|
||||
"copyToClipboard": "تم النسخ إلى الحافظة.",
|
||||
"addedToLibrary": "تمت الاضافة الى المكتبة!",
|
||||
"copyStyles": "نسخت الانماط.",
|
||||
"copyToClipboard": "نسخ إلى الحافظة.",
|
||||
"copyToClipboardAsPng": "تم نسخ {{exportSelection}} إلى الحافظة بصيغة PNG\n({{exportColorScheme}})",
|
||||
"copyToClipboardAsSvg": "تم نسخ {{exportSelection}} إلى الحافظة بصيغة SVG\n({{exportColorScheme}})",
|
||||
"fileSaved": "تم حفظ الملف.",
|
||||
"fileSavedToFilename": "تم الحفظ باسم {filename}",
|
||||
"fileSavedToFilename": "حفظ باسم {filename}",
|
||||
"canvas": "لوحة الرسم",
|
||||
"selection": "العنصر المحدد",
|
||||
"pasteAsSingleElement": "استخدم {{shortcut}} للصق كعنصر واحد،\nأو لصق في محرر نص موجود",
|
||||
"unableToEmbed": "تضمين هذا الرابط غير مسموح حاليًا. افتح بلاغًا على GitHub لطلب إدراج عنوان URL في القائمة البيضاء",
|
||||
"unrecognizedLinkFormat": "الرابط الذي أدرجته لا يتطابق مع التنسيق المتوقع. الرجاء محاولة لصق النص 'المضمن' المُزوَد من موقع المصدر",
|
||||
"elementLinkCopied": "تم نسخ الرابط إلى الحافظة"
|
||||
"unableToEmbed": "تضمين هذا الرابط غير مسموح حاليًا. افتح بلاغاً على GitHub لطلب عنوان Url القائمة البيضاء",
|
||||
"unrecognizedLinkFormat": "الرابط الذي ضمنته لا يتطابق مع التنسيق المتوقع. الرجاء محاولة لصق النص 'المضمن' المُزوَد من موقع المصدر"
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "شفاف",
|
||||
@@ -556,20 +466,19 @@
|
||||
},
|
||||
"welcomeScreen": {
|
||||
"app": {
|
||||
"center_heading": "جميع بياناتك محفوظة محليًا في المتصفح الخاص بك.",
|
||||
"center_heading_plus": "هل تريد الانتقال إلى Excalidraw+ بدلاً من ذلك؟",
|
||||
"menuHint": "التصدير، التفضيلات، اللغات..."
|
||||
"center_heading": "جميع بياناتك محفوظة محليا في المتصفح الخاص بك.",
|
||||
"center_heading_plus": "هل تريد الذهاب إلى Excalidraw+ بدلاً من ذلك؟",
|
||||
"menuHint": "التصدير والتفضيلات واللغات ..."
|
||||
},
|
||||
"defaults": {
|
||||
"menuHint": "التصدير، التفضيلات، وغيرها...",
|
||||
"center_heading": "الرسم البياني التصويري، ببساطة.",
|
||||
"toolbarHint": "اختر أداة وابدأ الرسم!",
|
||||
"helpHint": "الاختصارات والمساعدة"
|
||||
"menuHint": "التصدير والتفضيلات وغيرها...",
|
||||
"center_heading": "الرسم البياني التصويري. بشكل مبسط.",
|
||||
"toolbarHint": "اختر أداة و ابدأ الرسم!",
|
||||
"helpHint": "الاختصارات و المساعدة"
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "الألوان المخصصة الأكثر استخدامًا",
|
||||
"mostUsedCustomColors": "الألوان المخصصة الأكثر استخداما",
|
||||
"colors": "الألوان",
|
||||
"shades": "الدرجات",
|
||||
"hexCode": "رمز Hex",
|
||||
@@ -580,12 +489,12 @@
|
||||
"exportToImage": {
|
||||
"title": "تصدير كصورة",
|
||||
"button": "تصدير كصورة",
|
||||
"description": "تصدير بيانات المشهد إلى ملف يمكنك الاستيراد منه لاحقًا."
|
||||
"description": "تصدير بيانات المشهد إلى ملف يمكنك الاستيراد منه لاحقاً."
|
||||
},
|
||||
"saveToDisk": {
|
||||
"title": "حفظ الملف على الجهاز",
|
||||
"button": "حفظ الملف على الجهاز",
|
||||
"description": "تصدير بيانات المشهد إلى ملف يمكنك الاستيراد منه لاحقًا."
|
||||
"title": "حفظ الملف للجهاز",
|
||||
"button": "حفظ الملف للجهاز",
|
||||
"description": "تصدير بيانات المشهد إلى ملف يمكنك الاستيراد منه لاحقاً."
|
||||
},
|
||||
"excalidrawPlus": {
|
||||
"title": "Excalidraw+",
|
||||
@@ -602,63 +511,15 @@
|
||||
"shareableLink": {
|
||||
"title": "تحميل من رابط",
|
||||
"button": "استبدال محتواي",
|
||||
"description": "سيتسبب تحميل رسمة خارجية <bold>باستبدال محتواك الموجود حاليًا</bold>.<br></br>بإمكانك إجراء النسخ الاحتياطي لرسمتك الحالية باستخدام أحد الخيارات أدناه."
|
||||
"description": "سيتسبب تحميل رسمة خارجية <bold>باستبدال محتواك الموجود حالياً</bold>.<br></br>بإمكانك إجراء النسخ الاحتياطي لرسمتك الحالية باستخدام أحد الخيارات أدناه."
|
||||
}
|
||||
}
|
||||
},
|
||||
"mermaid": {
|
||||
"title": "Mermaid إلى Excalidraw",
|
||||
"button": "إدراج",
|
||||
"description": "حاليًا، يتم دعم <flowchartLink>مخططات التدفق</flowchartLink>، <sequenceLink>التسلسلات</sequenceLink>، و<classLink>الفئات</classLink> فقط. سيتم عرض الأنواع الأخرى كصورة في Excalidraw.",
|
||||
"syntax": "صيغة Mermaid",
|
||||
"preview": "معاينة"
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": "بحث سريع"
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": "قديم"
|
||||
},
|
||||
"sceneFonts": "في هذا المشهد",
|
||||
"availableFonts": "الخطوط المتوفرة",
|
||||
"empty": "لم يتم العثور على خطوط"
|
||||
},
|
||||
"userList": {
|
||||
"empty": "لم يتم العثور على مستخدمين",
|
||||
"hint": {
|
||||
"text": "انقر على المستخدم للمتابعة",
|
||||
"followStatus": "أنت حاليًا تتابع هذا المستخدم",
|
||||
"inCall": "المستخدم في مكالمة صوتية",
|
||||
"micMuted": "ميكروفون المستخدم مكتم",
|
||||
"isSpeaking": "المستخدم يتحدث"
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "لوحة الأوامر",
|
||||
"shortcuts": {
|
||||
"select": "اختر",
|
||||
"confirm": "تأكيد",
|
||||
"close": "إغلاق"
|
||||
},
|
||||
"recents": "المستخدمة مؤخرًا",
|
||||
"search": {
|
||||
"placeholder": "ابحث في القوائم، الأوامر، واكتشف الجواهر المخفية",
|
||||
"noMatch": "لا توجد أوامر مطابقة..."
|
||||
},
|
||||
"itemNotAvailable": "الأمر غير متوفر...",
|
||||
"shortcutHint": "للحصول على لوحة الأوامر، استخدم {{shortcut}}"
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": "",
|
||||
"syntax": "",
|
||||
"preview": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"copyAsPng": "PNG olaraq panoya kopyala",
|
||||
"copyAsSvg": "SVG olaraq panoya kopyala",
|
||||
"copyText": "Mətn olaraq panoya kopyala",
|
||||
"copySource": "Mənbəni kopyala",
|
||||
"convertToCode": "Koda çevir",
|
||||
"copySource": "",
|
||||
"convertToCode": "",
|
||||
"bringForward": "Önə daşı",
|
||||
"sendToBack": "Geriyə göndərin",
|
||||
"bringToFront": "Önə gətirin",
|
||||
@@ -21,13 +21,11 @@
|
||||
"copyStyles": "Stilləri kopyalayın",
|
||||
"pasteStyles": "Stilləri yapışdırın",
|
||||
"stroke": "Strok rəngi",
|
||||
"changeStroke": "Ştrix rəngini dəyişdir",
|
||||
"background": "Arxa fon",
|
||||
"changeBackground": "Fon rəngini dəyişdir",
|
||||
"fill": "Doldur",
|
||||
"strokeWidth": "Strok eni",
|
||||
"strokeStyle": "Strok stili",
|
||||
"strokeStyle_solid": "Qatı",
|
||||
"strokeStyle_solid": "Solid",
|
||||
"strokeStyle_dashed": "Kəsik",
|
||||
"strokeStyle_dotted": "Nöqtəli",
|
||||
"sloppiness": "Səliqəsizlik",
|
||||
@@ -40,20 +38,12 @@
|
||||
"arrowhead_none": "Heç biri",
|
||||
"arrowhead_arrow": "Ox",
|
||||
"arrowhead_bar": "Çubuq",
|
||||
"arrowhead_circle": "Dairə",
|
||||
"arrowhead_circle_outline": "Çevrə (Kontur)",
|
||||
"arrowhead_circle": "",
|
||||
"arrowhead_circle_outline": "",
|
||||
"arrowhead_triangle": "Üçbucaq",
|
||||
"arrowhead_triangle_outline": "Üçbucaq (kontur)",
|
||||
"arrowhead_diamond": "Almaz",
|
||||
"arrowhead_diamond_outline": "Almaz (kontur)",
|
||||
"arrowhead_crowfoot_many": "",
|
||||
"arrowhead_crowfoot_one": "",
|
||||
"arrowhead_crowfoot_one_or_many": "",
|
||||
"more_options": "",
|
||||
"arrowtypes": "",
|
||||
"arrowtype_sharp": "",
|
||||
"arrowtype_round": "",
|
||||
"arrowtype_elbowed": "",
|
||||
"arrowhead_triangle_outline": "",
|
||||
"arrowhead_diamond": "",
|
||||
"arrowhead_diamond_outline": "",
|
||||
"fontSize": "Şrift ölçüsü",
|
||||
"fontFamily": "Şrift qrupu",
|
||||
"addWatermark": "\"Made with Excalidraw\" əlavə et",
|
||||
@@ -64,7 +54,7 @@
|
||||
"medium": "Orta",
|
||||
"large": "Böyük",
|
||||
"veryLarge": "Çox böyük",
|
||||
"solid": "Qatı",
|
||||
"solid": "Solid",
|
||||
"hachure": "Ştrix",
|
||||
"zigzag": "Ziqzaq",
|
||||
"crossHatch": "Çarpaz dəlik",
|
||||
@@ -82,7 +72,6 @@
|
||||
"canvasColors": "Kanvas üzərində istifadə olunur",
|
||||
"canvasBackground": "Kanvas arxa fonu",
|
||||
"drawingCanvas": "Kanvas çəkmək",
|
||||
"clearCanvas": "Lövhəni təmizlə",
|
||||
"layers": "Qatlar",
|
||||
"actions": "Hərəkətlər",
|
||||
"language": "Dil",
|
||||
@@ -94,56 +83,48 @@
|
||||
"madeWithExcalidraw": "Excalidraw ilə hazırlanmışdır",
|
||||
"group": "Qrup şəklində seçim",
|
||||
"ungroup": "Qrupsuz seçim",
|
||||
"collaborators": "Əməkdaşlar",
|
||||
"toggleGrid": "Toru dəyiş",
|
||||
"addToLibrary": "Kitabxanaya əlavə et",
|
||||
"removeFromLibrary": "Kitabxanadan sil",
|
||||
"libraryLoadingMessage": "Kitabxana yüklənir...",
|
||||
"libraries": "Kitabxanalara bax",
|
||||
"loadingScene": "Səhnə yüklənir...",
|
||||
"loadScene": "Səhnəni fayldan yüklə",
|
||||
"align": "Hizala",
|
||||
"alignTop": "Yuxarı hizala",
|
||||
"alignBottom": "Aşağı hizala",
|
||||
"alignLeft": "Sola hizala",
|
||||
"alignRight": "Sağa hizala",
|
||||
"centerVertically": "Şaquli ortala",
|
||||
"centerHorizontally": "Üfüqi ortala",
|
||||
"distributeHorizontally": "Üfüqi payla",
|
||||
"distributeVertically": "Şaquli payla",
|
||||
"flipHorizontal": "Üfüqi çevir",
|
||||
"flipVertical": "Şaquli çevir",
|
||||
"viewMode": "Görünüş Rejimi",
|
||||
"share": "Paylaş",
|
||||
"showStroke": "Çevrə rəng seçimini göstər",
|
||||
"showBackground": "Fon rəng seçimini göstər",
|
||||
"showFonts": "",
|
||||
"toggleTheme": "Gecə/Güzdüz rejiminə dəyiş",
|
||||
"theme": "Fon",
|
||||
"personalLib": "Şəxsi kitabxana",
|
||||
"excalidrawLib": "Excalidraw kitabxanası",
|
||||
"decreaseFontSize": "Şrift ölçüsünü azalt",
|
||||
"increaseFontSize": "Şrift ölçüsünü artır",
|
||||
"unbindText": "Mətni çıxar",
|
||||
"bindText": "Mətni konteynerə qoş",
|
||||
"createContainerFromText": "Mətni konteynerə bük",
|
||||
"collaborators": "",
|
||||
"showGrid": "",
|
||||
"addToLibrary": "",
|
||||
"removeFromLibrary": "",
|
||||
"libraryLoadingMessage": "",
|
||||
"libraries": "",
|
||||
"loadingScene": "",
|
||||
"align": "",
|
||||
"alignTop": "",
|
||||
"alignBottom": "",
|
||||
"alignLeft": "",
|
||||
"alignRight": "",
|
||||
"centerVertically": "",
|
||||
"centerHorizontally": "",
|
||||
"distributeHorizontally": "",
|
||||
"distributeVertically": "",
|
||||
"flipHorizontal": "",
|
||||
"flipVertical": "",
|
||||
"viewMode": "",
|
||||
"share": "",
|
||||
"showStroke": "",
|
||||
"showBackground": "",
|
||||
"toggleTheme": "",
|
||||
"personalLib": "",
|
||||
"excalidrawLib": "",
|
||||
"decreaseFontSize": "",
|
||||
"increaseFontSize": "",
|
||||
"unbindText": "",
|
||||
"bindText": "",
|
||||
"createContainerFromText": "",
|
||||
"link": {
|
||||
"edit": "Keçidi düzəliş et",
|
||||
"edit": "",
|
||||
"editEmbed": "",
|
||||
"create": "",
|
||||
"label": "Keçid",
|
||||
"createEmbed": "",
|
||||
"label": "",
|
||||
"labelEmbed": "",
|
||||
"empty": "",
|
||||
"hint": "",
|
||||
"goToElement": ""
|
||||
"empty": ""
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "",
|
||||
"editArrow": ""
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"exit": ""
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "",
|
||||
@@ -157,46 +138,12 @@
|
||||
"removeAllElementsFromFrame": "",
|
||||
"eyeDropper": "",
|
||||
"textToDiagram": "",
|
||||
"prompt": "",
|
||||
"followUs": "",
|
||||
"discordChat": "",
|
||||
"zoomToFitViewport": "",
|
||||
"zoomToFitSelection": "",
|
||||
"zoomToFit": "",
|
||||
"installPWA": "",
|
||||
"autoResize": "",
|
||||
"imageCropping": "",
|
||||
"unCroppedDimension": "",
|
||||
"copyElementLink": "",
|
||||
"linkToElement": "",
|
||||
"wrapSelectionInFrame": "",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "",
|
||||
"desc": "",
|
||||
"notFound": ""
|
||||
"prompt": ""
|
||||
},
|
||||
"library": {
|
||||
"noItems": "",
|
||||
"hint_emptyLibrary": "",
|
||||
"hint_emptyPrivateLibrary": "",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "",
|
||||
"noMatch": "",
|
||||
"singleResult": "",
|
||||
"multipleResults": "",
|
||||
"placeholder": "",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"hint_emptyPrivateLibrary": ""
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "",
|
||||
@@ -204,7 +151,6 @@
|
||||
"exportImage": "",
|
||||
"export": "",
|
||||
"copyToClipboard": "",
|
||||
"copyLink": "",
|
||||
"save": "",
|
||||
"saveAs": "",
|
||||
"load": "",
|
||||
@@ -225,43 +171,40 @@
|
||||
"fullScreen": "",
|
||||
"darkMode": "",
|
||||
"lightMode": "",
|
||||
"systemMode": "Sistem rejimi",
|
||||
"zenMode": "Zen rejimi",
|
||||
"objectsSnapMode": "Obyektlərə bərkidin",
|
||||
"exitZenMode": "Zen rejimindən çıxış",
|
||||
"cancel": "Ləğv et",
|
||||
"saveLibNames": "",
|
||||
"clear": "Təmizlə",
|
||||
"remove": "Sil",
|
||||
"embed": "Yerləşdirməni aktiv et",
|
||||
"zenMode": "",
|
||||
"objectsSnapMode": "",
|
||||
"exitZenMode": "",
|
||||
"cancel": "",
|
||||
"clear": "",
|
||||
"remove": "",
|
||||
"embed": "",
|
||||
"publishLibrary": "",
|
||||
"submit": "Göndər",
|
||||
"confirm": "Təsdiqlə",
|
||||
"embeddableInteractionButton": "Əlaqə üçün kliklə"
|
||||
"submit": "",
|
||||
"confirm": "",
|
||||
"embeddableInteractionButton": ""
|
||||
},
|
||||
"alerts": {
|
||||
"clearReset": "Bu, bütün lövhəni təmizləyəcək. Sən əminsiniz?",
|
||||
"couldNotCreateShareableLink": "Paylaşıla bilən keçid yaratmaq mümkün olmadı.",
|
||||
"couldNotCreateShareableLinkTooBig": "Paylaşıla bilən link yaratmaq mümkün olmadı. Səhnə çox böyükdür",
|
||||
"couldNotLoadInvalidFile": "Faylı açmaq müknü olmadı",
|
||||
"importBackendFailed": "İdxal zamanı xəta baş verdi.",
|
||||
"cannotExportEmptyCanvas": "Boş lövhəni ixrac etmək mümkün deyil.",
|
||||
"couldNotCopyToClipboard": "Kopyalana bilmədi.",
|
||||
"decryptFailed": "Məlumatın şifrəsini açmaq mümkün olmadı.",
|
||||
"uploadedSecurly": "Yükləmə end-to-end şifrələmə texnologiyası ilə qorunub, yəni Excalidraw serveri və üçüncü tərəflər məzmunu oxuya bilməz.",
|
||||
"loadSceneOverridePrompt": "Xarici rəsmin yüklənməsi mövcud məzmununuzu əvəz edəcək. Davam etmək istəyirsiniz?",
|
||||
"collabStopOverridePrompt": "Sessiyanın dayandırılması əvvəlki, yerli olaraq saxlanılan çertyojunuzun üzərinə yazılacaq. Əminsiniz?",
|
||||
"errorAddingToLibrary": "Kitabxanaya əlavə etmək mümkün olmadı",
|
||||
"errorRemovingFromLibrary": "Kitabxanadan silmək mümkün olmadı",
|
||||
"confirmAddLibrary": "Bu, kitabxananıza {{numShapes}} forma əlavə edəcək. Əminsiniz?",
|
||||
"imageDoesNotContainScene": "Bu təsvirdə heç bir səhnə məlumatı yoxdur. İxrac zamanı səhnə yerləşdirməni aktiv etmisiniz?",
|
||||
"cannotRestoreFromImage": "Səhnəni bu şəkil faylından bərpa etmək mümkün olmadı",
|
||||
"clearReset": "",
|
||||
"couldNotCreateShareableLink": "",
|
||||
"couldNotCreateShareableLinkTooBig": "",
|
||||
"couldNotLoadInvalidFile": "",
|
||||
"importBackendFailed": "",
|
||||
"cannotExportEmptyCanvas": "",
|
||||
"couldNotCopyToClipboard": "",
|
||||
"decryptFailed": "",
|
||||
"uploadedSecurly": "",
|
||||
"loadSceneOverridePrompt": "",
|
||||
"collabStopOverridePrompt": "",
|
||||
"errorAddingToLibrary": "",
|
||||
"errorRemovingFromLibrary": "",
|
||||
"confirmAddLibrary": "",
|
||||
"imageDoesNotContainScene": "",
|
||||
"cannotRestoreFromImage": "",
|
||||
"invalidSceneUrl": "",
|
||||
"resetLibrary": "",
|
||||
"removeItemsFromsLibrary": "",
|
||||
"invalidEncryptionKey": "",
|
||||
"collabOfflineWarning": "",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"collabOfflineWarning": ""
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "",
|
||||
@@ -269,9 +212,9 @@
|
||||
"fileTooBig": "",
|
||||
"svgImageInsertError": "",
|
||||
"failedToFetchImage": "",
|
||||
"invalidSVGString": "",
|
||||
"cannotResolveCollabServer": "",
|
||||
"importLibraryError": "",
|
||||
"saveLibraryError": "",
|
||||
"collabSaveFailed": "",
|
||||
"collabSaveFailed_sizeExceeded": "",
|
||||
"imageToolNotSupported": "",
|
||||
@@ -292,7 +235,6 @@
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "",
|
||||
"lasso": "",
|
||||
"image": "",
|
||||
"rectangle": "",
|
||||
"diamond": "",
|
||||
@@ -313,23 +255,7 @@
|
||||
"hand": "",
|
||||
"extraTools": "",
|
||||
"mermaidToExcalidraw": "",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "",
|
||||
"diamond": "",
|
||||
"ellipse": "",
|
||||
"arrow": "",
|
||||
"line": "",
|
||||
"freedraw": "",
|
||||
"text": "",
|
||||
"image": "",
|
||||
"group": "",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"selection": "",
|
||||
"iframe": ""
|
||||
"magicSettings": ""
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "",
|
||||
@@ -337,10 +263,8 @@
|
||||
"shapes": ""
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"linearElement": "",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "",
|
||||
"text": "",
|
||||
"embeddable": "",
|
||||
@@ -352,18 +276,15 @@
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"placeImage": "",
|
||||
"publishLibrary": "",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"firefox_clipboard_write": "",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": ""
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "",
|
||||
@@ -378,9 +299,6 @@
|
||||
"openIssueMessage": "",
|
||||
"sceneContent": ""
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": ""
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "",
|
||||
"desc_privacy": "",
|
||||
@@ -410,8 +328,6 @@
|
||||
"click": "",
|
||||
"deepSelect": "",
|
||||
"deepBoxSelect": "",
|
||||
"createFlowchart": "",
|
||||
"navigateFlowchart": "",
|
||||
"curvedArrow": "",
|
||||
"curvedLine": "",
|
||||
"documentation": "",
|
||||
@@ -434,9 +350,7 @@
|
||||
"zoomToSelection": "",
|
||||
"toggleElementLock": "",
|
||||
"movePageUpDown": "",
|
||||
"movePageLeftRight": "",
|
||||
"cropStart": "",
|
||||
"cropFinish": ""
|
||||
"movePageLeftRight": ""
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": ""
|
||||
@@ -507,15 +421,13 @@
|
||||
},
|
||||
"stats": {
|
||||
"angle": "",
|
||||
"shapes": "",
|
||||
"element": "",
|
||||
"elements": "",
|
||||
"height": "",
|
||||
"scene": "",
|
||||
"selected": "",
|
||||
"storage": "",
|
||||
"fullTitle": "",
|
||||
"title": "",
|
||||
"generalStats": "",
|
||||
"elementProperties": "",
|
||||
"total": "",
|
||||
"version": "",
|
||||
"versionCopy": "",
|
||||
@@ -527,15 +439,13 @@
|
||||
"copyStyles": "",
|
||||
"copyToClipboard": "",
|
||||
"copyToClipboardAsPng": "",
|
||||
"copyToClipboardAsSvg": "",
|
||||
"fileSaved": "",
|
||||
"fileSavedToFilename": "",
|
||||
"canvas": "",
|
||||
"selection": "",
|
||||
"pasteAsSingleElement": "",
|
||||
"unableToEmbed": "",
|
||||
"unrecognizedLinkFormat": "",
|
||||
"elementLinkCopied": ""
|
||||
"unrecognizedLinkFormat": ""
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "",
|
||||
@@ -568,7 +478,6 @@
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "",
|
||||
"colors": "",
|
||||
"shades": "",
|
||||
@@ -612,53 +521,5 @@
|
||||
"description": "",
|
||||
"syntax": "",
|
||||
"preview": ""
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": ""
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": ""
|
||||
},
|
||||
"sceneFonts": "",
|
||||
"availableFonts": "",
|
||||
"empty": ""
|
||||
},
|
||||
"userList": {
|
||||
"empty": "",
|
||||
"hint": {
|
||||
"text": "",
|
||||
"followStatus": "",
|
||||
"inCall": "",
|
||||
"micMuted": "",
|
||||
"isSpeaking": ""
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "",
|
||||
"shortcuts": {
|
||||
"select": "",
|
||||
"confirm": "",
|
||||
"close": ""
|
||||
},
|
||||
"recents": "",
|
||||
"search": {
|
||||
"placeholder": "",
|
||||
"noMatch": ""
|
||||
},
|
||||
"itemNotAvailable": "",
|
||||
"shortcutHint": ""
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
"copy": "Копирай",
|
||||
"copyAsPng": "Копиране в клипборда",
|
||||
"copyAsSvg": "Копирано в клипборда като SVG",
|
||||
"copyText": "Копирай в клипборда като текст",
|
||||
"copySource": "Копирай източника в клипборда",
|
||||
"convertToCode": "Конвертирай в код",
|
||||
"copyText": "",
|
||||
"copySource": "",
|
||||
"convertToCode": "",
|
||||
"bringForward": "Преместване напред",
|
||||
"sendToBack": "Изнасяне назад",
|
||||
"bringToFront": "Изнасяне отпред",
|
||||
@@ -21,9 +21,7 @@
|
||||
"copyStyles": "Копирайте стилове",
|
||||
"pasteStyles": "Постави стилове",
|
||||
"stroke": "Щрих",
|
||||
"changeStroke": "Смени цвета на щрих",
|
||||
"background": "Фон",
|
||||
"changeBackground": "Смени цвета на фон",
|
||||
"fill": "Наситеност",
|
||||
"strokeWidth": "Ширина на щриха",
|
||||
"strokeStyle": "Стил на линия",
|
||||
@@ -40,20 +38,12 @@
|
||||
"arrowhead_none": "Без",
|
||||
"arrowhead_arrow": "Стрелка",
|
||||
"arrowhead_bar": "Връх на стрелката",
|
||||
"arrowhead_circle": "Кръг",
|
||||
"arrowhead_circle_outline": "Окръжност",
|
||||
"arrowhead_circle": "",
|
||||
"arrowhead_circle_outline": "",
|
||||
"arrowhead_triangle": "Триъгълник",
|
||||
"arrowhead_triangle_outline": "Триъгълник (очертание)",
|
||||
"arrowhead_diamond": "Диамант",
|
||||
"arrowhead_diamond_outline": "Диамант (очертание)",
|
||||
"arrowhead_crowfoot_many": "",
|
||||
"arrowhead_crowfoot_one": "",
|
||||
"arrowhead_crowfoot_one_or_many": "",
|
||||
"more_options": "",
|
||||
"arrowtypes": "Вид стрелка",
|
||||
"arrowtype_sharp": "Остра стрелка",
|
||||
"arrowtype_round": "Извита стрелка",
|
||||
"arrowtype_elbowed": "",
|
||||
"arrowhead_triangle_outline": "",
|
||||
"arrowhead_diamond": "",
|
||||
"arrowhead_diamond_outline": "",
|
||||
"fontSize": "Размер на шрифта",
|
||||
"fontFamily": "Семейство шрифтове",
|
||||
"addWatermark": "Добави \"Направено с Excalidraw\"",
|
||||
@@ -82,11 +72,10 @@
|
||||
"canvasColors": "Използван на платно",
|
||||
"canvasBackground": "Фон на платно",
|
||||
"drawingCanvas": "Платно за рисуване",
|
||||
"clearCanvas": "Изчисти платното",
|
||||
"layers": "Слоеве",
|
||||
"actions": "Действия",
|
||||
"language": "Език",
|
||||
"liveCollaboration": "Сътрудничество на живо...",
|
||||
"liveCollaboration": "",
|
||||
"duplicateSelection": "Дублирай",
|
||||
"untitled": "Неозаглавено",
|
||||
"name": "Име",
|
||||
@@ -95,13 +84,12 @@
|
||||
"group": "Групирай селекцията",
|
||||
"ungroup": "Спри групирането на селекцията",
|
||||
"collaborators": "Сътрудници",
|
||||
"toggleGrid": "Превключване на мрежа",
|
||||
"showGrid": "Показване на мрежа",
|
||||
"addToLibrary": "Добавяне към библиотеката",
|
||||
"removeFromLibrary": "Премахване от библиотеката",
|
||||
"libraryLoadingMessage": "Зареждане на библиотеката…",
|
||||
"libraries": "Разглеждане на библиотеките",
|
||||
"loadingScene": "Зареждане на сцена…",
|
||||
"loadScene": "Зареди сцена от файл",
|
||||
"align": "Подравняване",
|
||||
"alignTop": "Подравняване отгоре",
|
||||
"alignBottom": "Подравняване отдолу",
|
||||
@@ -115,11 +103,9 @@
|
||||
"flipVertical": "Вертикално обръщане",
|
||||
"viewMode": "Изглед",
|
||||
"share": "Сподели",
|
||||
"showStroke": "Покажи избора на цвят за щрих",
|
||||
"showBackground": "Покажи избора на цвят за фон",
|
||||
"showFonts": "",
|
||||
"toggleTheme": "Превключване на светла/тъмна тема",
|
||||
"theme": "Тема",
|
||||
"showStroke": "",
|
||||
"showBackground": "",
|
||||
"toggleTheme": "Включи тема",
|
||||
"personalLib": "Лична Библиотека",
|
||||
"excalidrawLib": "Excalidraw Библиотека",
|
||||
"decreaseFontSize": "Намали размера на шрифта",
|
||||
@@ -130,20 +116,15 @@
|
||||
"link": {
|
||||
"edit": "Редактирай линк",
|
||||
"editEmbed": "",
|
||||
"create": "Добавяне на връзка",
|
||||
"create": "",
|
||||
"createEmbed": "",
|
||||
"label": "Линк",
|
||||
"labelEmbed": "",
|
||||
"empty": "Няма зададен линк",
|
||||
"hint": "",
|
||||
"goToElement": ""
|
||||
"empty": ""
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "Редактирай линия",
|
||||
"editArrow": "Редактирай стрелка"
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"edit": "",
|
||||
"exit": ""
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "Заключи",
|
||||
@@ -153,58 +134,23 @@
|
||||
},
|
||||
"statusPublished": "Публикувани",
|
||||
"sidebarLock": "",
|
||||
"selectAllElementsInFrame": "Избери всички елементи в рамка",
|
||||
"removeAllElementsFromFrame": "Премахни всички елементи от рамка",
|
||||
"selectAllElementsInFrame": "",
|
||||
"removeAllElementsFromFrame": "",
|
||||
"eyeDropper": "Избери цвят от платното",
|
||||
"textToDiagram": "Текст към диаграма",
|
||||
"prompt": "",
|
||||
"followUs": "Последвайте ни",
|
||||
"discordChat": "Дискорд чат",
|
||||
"zoomToFitViewport": "",
|
||||
"zoomToFitSelection": "Приближи селекцията",
|
||||
"zoomToFit": "Приближи всички елементи",
|
||||
"installPWA": "",
|
||||
"autoResize": "",
|
||||
"imageCropping": "",
|
||||
"unCroppedDimension": "",
|
||||
"copyElementLink": "",
|
||||
"linkToElement": "",
|
||||
"wrapSelectionInFrame": "",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "",
|
||||
"desc": "",
|
||||
"notFound": ""
|
||||
"textToDiagram": "",
|
||||
"prompt": ""
|
||||
},
|
||||
"library": {
|
||||
"noItems": "Няма добавени неща все още...",
|
||||
"hint_emptyLibrary": "Избери предмет от платното, за да го добавиш тук или инсталирай библиотека от публичното хранилище по-долу.",
|
||||
"hint_emptyPrivateLibrary": "Избери предмет от платното, за да го добавиш тук.",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "",
|
||||
"noMatch": "",
|
||||
"singleResult": "резултат",
|
||||
"multipleResults": "резултати",
|
||||
"placeholder": "Търсене на текст по платното...",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"hint_emptyLibrary": "",
|
||||
"hint_emptyPrivateLibrary": ""
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "Нулиране на платно",
|
||||
"exportJSON": "Изнасяна към файл",
|
||||
"exportImage": "Изнеси изображение...",
|
||||
"exportJSON": "",
|
||||
"exportImage": "",
|
||||
"export": "Запази на...",
|
||||
"copyToClipboard": "Копиране в клипборда",
|
||||
"copyLink": "",
|
||||
"save": "Запази към текущ файл",
|
||||
"saveAs": "Запиши като",
|
||||
"load": "Отвори",
|
||||
@@ -225,19 +171,17 @@
|
||||
"fullScreen": "На цял екран",
|
||||
"darkMode": "Тъмен режим",
|
||||
"lightMode": "Светъл режим",
|
||||
"systemMode": "Системен режим",
|
||||
"zenMode": "Режим Zen",
|
||||
"objectsSnapMode": "Прилепване към обекти",
|
||||
"exitZenMode": "Спиране на режим Зен",
|
||||
"objectsSnapMode": "",
|
||||
"exitZenMode": "Спиране на Zen режим",
|
||||
"cancel": "Отмени",
|
||||
"saveLibNames": "",
|
||||
"clear": "Изчисти",
|
||||
"remove": "Премахване",
|
||||
"embed": "Включи вмъкване",
|
||||
"publishLibrary": "",
|
||||
"embed": "",
|
||||
"publishLibrary": "Публикувай",
|
||||
"submit": "Изпрати",
|
||||
"confirm": "Потвърждаване",
|
||||
"embeddableInteractionButton": "Натисни, за да взаимодействаш"
|
||||
"embeddableInteractionButton": ""
|
||||
},
|
||||
"alerts": {
|
||||
"clearReset": "Това ще изчисти цялото платно. Сигурни ли сте?",
|
||||
@@ -254,32 +198,31 @@
|
||||
"errorAddingToLibrary": "Не можем да заредим от библиотеката",
|
||||
"errorRemovingFromLibrary": "Не можем да премахнем елемент от библиотеката",
|
||||
"confirmAddLibrary": "Ще се добавят {{numShapes}} фигура(и) във вашата библиотека. Сигурни ли сте?",
|
||||
"imageDoesNotContainScene": "Това изображение не изглежда да съдържа каквито и да е данни за сцена. Искате ли да включите вмъкване на сцени при изнасяне?",
|
||||
"imageDoesNotContainScene": "",
|
||||
"cannotRestoreFromImage": "Не може да бъде възстановена сцена от този файл",
|
||||
"invalidSceneUrl": "Неуспешно поставяне на сцена от предоставения линк. Той е или неправилно оформен, или не съдържа валидни Excalidraw JSON данни.",
|
||||
"resetLibrary": "Това ще изчисти библиотеката ви. Сигурни ли сте?",
|
||||
"invalidSceneUrl": "",
|
||||
"resetLibrary": "",
|
||||
"removeItemsFromsLibrary": "Изтрий {{count}} елемент(а) от библиотеката?",
|
||||
"invalidEncryptionKey": "Ключът за енкрипция трябва да е от 22 знака. Сътрудничеството на живо е изключено.",
|
||||
"collabOfflineWarning": "Няма налична интернет връзка.\nВашите промени няма да бъдат запазени!",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"invalidEncryptionKey": "",
|
||||
"collabOfflineWarning": ""
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "Този файлов формат не се поддържа.",
|
||||
"imageInsertError": "Неуспешно поставяне на изображение. Опитайте по-късно...",
|
||||
"imageInsertError": "",
|
||||
"fileTooBig": "Файлът е твърде голям. Максималния допустим размер е {{maxSize}}.",
|
||||
"svgImageInsertError": "Неуспешно поставяне на SVG изборажение. SVG данните изглеждат невалидни.",
|
||||
"failedToFetchImage": "Неуспешно получаване на изборажение.",
|
||||
"svgImageInsertError": "",
|
||||
"failedToFetchImage": "",
|
||||
"invalidSVGString": "Невалиден SVG.",
|
||||
"cannotResolveCollabServer": "",
|
||||
"importLibraryError": "Не можем да заредим библиотеката",
|
||||
"saveLibraryError": "",
|
||||
"collabSaveFailed": "",
|
||||
"collabSaveFailed_sizeExceeded": "",
|
||||
"imageToolNotSupported": "Изображенията са изключени.",
|
||||
"imageToolNotSupported": "",
|
||||
"brave_measure_text_error": {
|
||||
"line1": "",
|
||||
"line2": "",
|
||||
"line3": "Силно препоръчваме да изключите тази настройка. Можете да следвате <link>тези стъпки</link> за това как да го направите.",
|
||||
"line4": "Ако изключването на тази настройка не оправи изобразяването на текстови елементи, моля отворете <issueLink>проблем</issueLink> на нашия GitHub или ни пишете на <discordLink>Дискорд</discordLink>"
|
||||
"line4": ""
|
||||
},
|
||||
"libraryElementTypeError": {
|
||||
"embeddable": "",
|
||||
@@ -292,7 +235,6 @@
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "Селекция",
|
||||
"lasso": "",
|
||||
"image": "Вмъкване на изображение",
|
||||
"rectangle": "Правоъгълник",
|
||||
"diamond": "Диамант",
|
||||
@@ -306,30 +248,14 @@
|
||||
"penMode": "",
|
||||
"link": "",
|
||||
"eraser": "Гума",
|
||||
"frame": "Инструмент за рамки",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"laser": "Лазерна показалка",
|
||||
"laser": "",
|
||||
"hand": "",
|
||||
"extraTools": "Още инструменти",
|
||||
"mermaidToExcalidraw": "Mermaid към Excalidraw",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "Правоъгълник",
|
||||
"diamond": "Диамант",
|
||||
"ellipse": "Елипса",
|
||||
"arrow": "Стрелка",
|
||||
"line": "Линия",
|
||||
"freedraw": "Свободно рисуване",
|
||||
"text": "Текст",
|
||||
"image": "Изображение",
|
||||
"group": "Група",
|
||||
"frame": "Рамка",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"selection": "",
|
||||
"iframe": "IFrame"
|
||||
"mermaidToExcalidraw": "",
|
||||
"magicSettings": ""
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "Действия по платното",
|
||||
@@ -337,33 +263,28 @@
|
||||
"shapes": "Фигури"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"linearElement": "Кликнете, за да стартирате няколко точки, плъзнете за една линия",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "Натиснете и влачете, пуснете като сте готови",
|
||||
"text": "Подсказка: Можете също да добавите текст като натиснете някъде два път с инструмента за селекция",
|
||||
"embeddable": "Натисни-премести, за да създадеш вметка за уебсайт",
|
||||
"embeddable": "",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"linearElementMulti": "Кликнете върху последната точка или натиснете Escape или Enter, за да завършите",
|
||||
"lockAngle": "Можете да ограничите ъгъла, като задържите SHIFT",
|
||||
"resize": "Може да ограничите при преоразмеряване като задържите SHIFT,\nзадръжте ALT за преоразмерите през центъра",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"rotate": "Можете да ограничите ъглите, като държите SHIFT, докато се въртите",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_pointSelected": "Натиснете Delete за да изтриете точка(и), CtrlOrCmd+D за дуплициране, или извлачете за да преместите",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"publishLibrary": "Публикувайте собствена библиотека",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"placeImage": "",
|
||||
"publishLibrary": "",
|
||||
"bindTextToElement": "Натиснете Enter, за да добавите",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"firefox_clipboard_write": "",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": ""
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "Невъзможност за показване на preview",
|
||||
@@ -378,12 +299,9 @@
|
||||
"openIssueMessage": "Бяхме много предпазливи да не включите информацията за вашата сцена при грешката. Ако сцената ви не е частна, моля, помислете за последващи действия на нашата <button>тракер за грешки.</button> Моля, включете информация по-долу, като я копирате и добавите в GitHub.",
|
||||
"sceneContent": "Съдържание на сцената:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": "Или"
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "Поканете хора да работят съвместно на рисунката.",
|
||||
"desc_privacy": "",
|
||||
"desc_intro": "Можете да поканите хора на текущата си сцена да си сътрудничат с вас.",
|
||||
"desc_privacy": "Не се притеснявайте, сесията използва криптиране от край до край, така че каквото нарисувате ще остане частно. Дори нашият сървър няма да може да види какво предлагате.",
|
||||
"button_startSession": "Стартирайте сесията",
|
||||
"button_stopSession": "Стоп на сесията",
|
||||
"desc_inProgressIntro": "Сесията за сътрудничество на живо е в ход.",
|
||||
@@ -395,10 +313,10 @@
|
||||
"title": "Грешка"
|
||||
},
|
||||
"exportDialog": {
|
||||
"disk_title": "Запази към диск",
|
||||
"disk_title": "",
|
||||
"disk_details": "",
|
||||
"disk_button": "Запази като файл",
|
||||
"link_title": "Връзка за споделяне",
|
||||
"disk_button": "",
|
||||
"link_title": "",
|
||||
"link_details": "",
|
||||
"link_button": "",
|
||||
"excalidrawplus_description": "",
|
||||
@@ -410,8 +328,6 @@
|
||||
"click": "клик",
|
||||
"deepSelect": "",
|
||||
"deepBoxSelect": "",
|
||||
"createFlowchart": "",
|
||||
"navigateFlowchart": "",
|
||||
"curvedArrow": "Извита стрелка",
|
||||
"curvedLine": "Извита линия",
|
||||
"documentation": "Документация",
|
||||
@@ -434,9 +350,7 @@
|
||||
"zoomToSelection": "Приближи селекцията",
|
||||
"toggleElementLock": "Заключи/Отключи селекция",
|
||||
"movePageUpDown": "Премести страница нагоре/надолу",
|
||||
"movePageLeftRight": "Премести страница наляво/надясно",
|
||||
"cropStart": "",
|
||||
"cropFinish": ""
|
||||
"movePageLeftRight": "Премести страница наляво/надясно"
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": "Изчисти платното"
|
||||
@@ -507,15 +421,13 @@
|
||||
},
|
||||
"stats": {
|
||||
"angle": "Ъгъл",
|
||||
"shapes": "",
|
||||
"element": "Елемент",
|
||||
"elements": "Елементи",
|
||||
"height": "Височина",
|
||||
"scene": "Сцена",
|
||||
"selected": "Селектирано",
|
||||
"storage": "Съхранение на данни",
|
||||
"fullTitle": "",
|
||||
"title": "",
|
||||
"generalStats": "",
|
||||
"elementProperties": "",
|
||||
"title": "Статистика за хакери",
|
||||
"total": "Общо",
|
||||
"version": "Версия",
|
||||
"versionCopy": "Настисни за да копираш",
|
||||
@@ -527,15 +439,13 @@
|
||||
"copyStyles": "Копирани стилове.",
|
||||
"copyToClipboard": "Копирано в клипборда.",
|
||||
"copyToClipboardAsPng": "Копира {{exportSelection}} в клипборда като PNG\n({{exportColorScheme}})",
|
||||
"copyToClipboardAsSvg": "",
|
||||
"fileSaved": "Файлът е запазен.",
|
||||
"fileSavedToFilename": "Запазен към {filename}",
|
||||
"canvas": "платно",
|
||||
"selection": "селекция",
|
||||
"pasteAsSingleElement": "",
|
||||
"unableToEmbed": "",
|
||||
"unrecognizedLinkFormat": "",
|
||||
"elementLinkCopied": ""
|
||||
"unrecognizedLinkFormat": ""
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "Прозрачен",
|
||||
@@ -568,7 +478,6 @@
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "Най-често използвани цветове",
|
||||
"colors": "Цветове",
|
||||
"shades": "Нюанси",
|
||||
@@ -608,57 +517,9 @@
|
||||
},
|
||||
"mermaid": {
|
||||
"title": "",
|
||||
"button": "Вмъкни",
|
||||
"button": "",
|
||||
"description": "",
|
||||
"syntax": "Mermaid Синтаксис",
|
||||
"preview": "Преглед"
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": ""
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": ""
|
||||
},
|
||||
"sceneFonts": "",
|
||||
"availableFonts": "",
|
||||
"empty": ""
|
||||
},
|
||||
"userList": {
|
||||
"empty": "",
|
||||
"hint": {
|
||||
"text": "Натиснете потребител, за да го следвате",
|
||||
"followStatus": "В момента следвате този потребител",
|
||||
"inCall": "",
|
||||
"micMuted": "Микрофона на потребителят е заглушен",
|
||||
"isSpeaking": "Потребителят говори"
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "Палитра команди",
|
||||
"shortcuts": {
|
||||
"select": "Избери",
|
||||
"confirm": "Потвърди",
|
||||
"close": "Затвори"
|
||||
},
|
||||
"recents": "Наскоро използвани",
|
||||
"search": {
|
||||
"placeholder": "",
|
||||
"noMatch": ""
|
||||
},
|
||||
"itemNotAvailable": "",
|
||||
"shortcutHint": ""
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
"syntax": "",
|
||||
"preview": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"copyAsPng": "পীএনজী ছবির মতন কপি করুন",
|
||||
"copyAsSvg": "এসভীজী ছবির মতন কপি করুন",
|
||||
"copyText": "লিখিত তথ্যের মতন কপি করুন",
|
||||
"copySource": "পিএনজি ছবি ক্লিপবোর্ডে কপি করুন",
|
||||
"convertToCode": "কোডে রূপান্তর করুন",
|
||||
"copySource": "",
|
||||
"convertToCode": "",
|
||||
"bringForward": "অধিকতর সামনে আনুন",
|
||||
"sendToBack": "অধিকতর পিছনে নিয়ে যান",
|
||||
"bringToFront": "সবার সামনে আনুন",
|
||||
@@ -21,9 +21,7 @@
|
||||
"copyStyles": "ডিজাইন কপি করুন",
|
||||
"pasteStyles": "ডিজাইন পেস্ট করুন",
|
||||
"stroke": "রেখাংশ",
|
||||
"changeStroke": "Hi",
|
||||
"background": "পটভূমি",
|
||||
"changeBackground": "পটভূমির রঙ পরিবর্তন করুন",
|
||||
"fill": "রং",
|
||||
"strokeWidth": "রেখাংশের বেধ",
|
||||
"strokeStyle": "রেখাংশের ডিজাইন",
|
||||
@@ -40,20 +38,12 @@
|
||||
"arrowhead_none": "কিছু না",
|
||||
"arrowhead_arrow": "তীর",
|
||||
"arrowhead_bar": "রেখাংশ",
|
||||
"arrowhead_circle": "বৃত্ত",
|
||||
"arrowhead_circle_outline": "বৃত্তীয় (প্রান্তরেখা) প্রান্তরেখা",
|
||||
"arrowhead_circle": "",
|
||||
"arrowhead_circle_outline": "",
|
||||
"arrowhead_triangle": "ত্রিভূজ",
|
||||
"arrowhead_triangle_outline": "ত্রিভুজ (প্রান্তরেখা) প্রান্তরেখা",
|
||||
"arrowhead_diamond": "হীরক",
|
||||
"arrowhead_diamond_outline": "হীরক (প্রান্তরেখা)",
|
||||
"arrowhead_crowfoot_many": "",
|
||||
"arrowhead_crowfoot_one": "",
|
||||
"arrowhead_crowfoot_one_or_many": "",
|
||||
"more_options": "",
|
||||
"arrowtypes": "",
|
||||
"arrowtype_sharp": "",
|
||||
"arrowtype_round": "",
|
||||
"arrowtype_elbowed": "",
|
||||
"arrowhead_triangle_outline": "",
|
||||
"arrowhead_diamond": "",
|
||||
"arrowhead_diamond_outline": "",
|
||||
"fontSize": "লেখনীর মাত্রা",
|
||||
"fontFamily": "লেখনীর হরফ",
|
||||
"addWatermark": "এক্সক্যালিড্র দ্বারা প্রস্তুত",
|
||||
@@ -82,7 +72,6 @@
|
||||
"canvasColors": "ক্যানভাসের রং",
|
||||
"canvasBackground": "ক্যানভাসের পটভূমি",
|
||||
"drawingCanvas": "ব্যবহৃত ক্যানভাস",
|
||||
"clearCanvas": "পরিষ্কার ক্যানভাস",
|
||||
"layers": "মাত্রা",
|
||||
"actions": "ক্রিয়া",
|
||||
"language": "ভাষা",
|
||||
@@ -95,13 +84,12 @@
|
||||
"group": "দল গঠন করুন",
|
||||
"ungroup": "দল বিভেদ করুন",
|
||||
"collaborators": "সহযোগী",
|
||||
"toggleGrid": "",
|
||||
"showGrid": "গ্রিড দেখান",
|
||||
"addToLibrary": "সংগ্রহে যোগ করুন",
|
||||
"removeFromLibrary": "সংগ্রহ থেকে বের করুন",
|
||||
"libraryLoadingMessage": "সংগ্রহ তৈরি হচ্ছে",
|
||||
"libraries": "সংগ্রহ দেখুন",
|
||||
"loadingScene": "দৃশ্য তৈরি হচ্ছে",
|
||||
"loadScene": "",
|
||||
"align": "পংক্তিবিন্যাস",
|
||||
"alignTop": "উপর পংক্তি",
|
||||
"alignBottom": "নিম্ন পংক্তি",
|
||||
@@ -116,34 +104,27 @@
|
||||
"viewMode": "দৃশ্য",
|
||||
"share": "ভাগ করুন",
|
||||
"showStroke": "",
|
||||
"showBackground": "পটভূমির রঙ নির্বাচনকারী অপশন দেখান",
|
||||
"showFonts": "",
|
||||
"showBackground": "",
|
||||
"toggleTheme": "",
|
||||
"theme": "",
|
||||
"personalLib": "ব্যক্তিগত লাইব্রেরি",
|
||||
"excalidrawLib": "এক্সক্যালিড্র লাইব্রেরি",
|
||||
"personalLib": "",
|
||||
"excalidrawLib": "",
|
||||
"decreaseFontSize": "লেখনীর মাত্রা কমান",
|
||||
"increaseFontSize": "লেখনীর মাত্রা বাড়ান",
|
||||
"unbindText": "লেখার জোড় খুলুন",
|
||||
"bindText": "কন্টেইনারের সাথে লেখা জোড়া লাগান",
|
||||
"unbindText": "",
|
||||
"bindText": "",
|
||||
"createContainerFromText": "",
|
||||
"link": {
|
||||
"edit": "লিঙ্ক সংশোধন",
|
||||
"editEmbed": "",
|
||||
"create": "",
|
||||
"create": "লিঙ্ক তৈরী",
|
||||
"createEmbed": "",
|
||||
"label": "লিঙ্ক নামকরণ",
|
||||
"labelEmbed": "লিংক ও এম্বেড",
|
||||
"empty": "কোন লিংক সেট করা নেই",
|
||||
"hint": "",
|
||||
"goToElement": ""
|
||||
"labelEmbed": "",
|
||||
"empty": ""
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "লাইন সম্পাদনা করুন",
|
||||
"editArrow": ""
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"edit": "",
|
||||
"exit": ""
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "আবদ্ধ করুন",
|
||||
@@ -153,50 +134,16 @@
|
||||
},
|
||||
"statusPublished": "প্রকাশিত",
|
||||
"sidebarLock": "লক",
|
||||
"selectAllElementsInFrame": "ফ্রেমের ভিতরের সব উপকরণ বাছাই করুন",
|
||||
"removeAllElementsFromFrame": "ফ্রেম থেকে সব উপকরণ মুছুন",
|
||||
"eyeDropper": "ক্যানভাস থেকে রঙ বাছাই করুন",
|
||||
"textToDiagram": "লেখা থেকে ডায়াগ্রাম",
|
||||
"prompt": "",
|
||||
"followUs": "",
|
||||
"discordChat": "",
|
||||
"zoomToFitViewport": "",
|
||||
"zoomToFitSelection": "",
|
||||
"zoomToFit": "",
|
||||
"installPWA": "",
|
||||
"autoResize": "",
|
||||
"imageCropping": "",
|
||||
"unCroppedDimension": "",
|
||||
"copyElementLink": "",
|
||||
"linkToElement": "",
|
||||
"wrapSelectionInFrame": "",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "",
|
||||
"desc": "",
|
||||
"notFound": ""
|
||||
"selectAllElementsInFrame": "",
|
||||
"removeAllElementsFromFrame": "",
|
||||
"eyeDropper": "",
|
||||
"textToDiagram": "",
|
||||
"prompt": ""
|
||||
},
|
||||
"library": {
|
||||
"noItems": "সংগ্রহে কিছু যোগ করা হয়নি",
|
||||
"hint_emptyLibrary": "এখানে যোগ করার জন্য ক্যানভাসে একটি বস্তু নির্বাচন করুন, অথবা নীচে, প্রকাশ্য সংগ্রহশালা থেকে একটি সংগ্রহ ইনস্টল করুন৷",
|
||||
"hint_emptyPrivateLibrary": "এখানে যোগ করার জন্য ক্যানভাসে একটি বস্তু নির্বাচন করুন",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "",
|
||||
"noMatch": "",
|
||||
"singleResult": "",
|
||||
"multipleResults": "",
|
||||
"placeholder": "",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"hint_emptyPrivateLibrary": "এখানে যোগ করার জন্য ক্যানভাসে একটি বস্তু নির্বাচন করুন"
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "ক্যানভাস সাফ করুন",
|
||||
@@ -204,7 +151,6 @@
|
||||
"exportImage": "",
|
||||
"export": "",
|
||||
"copyToClipboard": "ক্লিপবোর্ডে কপি করুন",
|
||||
"copyLink": "",
|
||||
"save": "জমা করুন",
|
||||
"saveAs": "অন্যভাবে জমা করুন",
|
||||
"load": "",
|
||||
@@ -225,16 +171,14 @@
|
||||
"fullScreen": "পূর্ণস্ক্রীন",
|
||||
"darkMode": "ডার্ক মোড",
|
||||
"lightMode": "লাইট মোড",
|
||||
"systemMode": "",
|
||||
"zenMode": "জেন মোড",
|
||||
"objectsSnapMode": "",
|
||||
"exitZenMode": "জেন মোড বন্ধ করুন",
|
||||
"cancel": "বাতিল",
|
||||
"saveLibNames": "",
|
||||
"clear": "সাফ",
|
||||
"remove": "বিয়োগ",
|
||||
"embed": "",
|
||||
"publishLibrary": "",
|
||||
"publishLibrary": "সংগ্রহ প্রকাশ করুন",
|
||||
"submit": "জমা করুন",
|
||||
"confirm": "নিশ্চিত করুন",
|
||||
"embeddableInteractionButton": ""
|
||||
@@ -260,8 +204,7 @@
|
||||
"resetLibrary": "এটি আপনার সংগ্রহ পরিষ্কার করবে। আপনি কি নিশ্চিত?",
|
||||
"removeItemsFromsLibrary": "সংগ্রহ থেকে {{count}} বস্তু বিয়োগ করা হবে। আপনি কি নিশ্চিত?",
|
||||
"invalidEncryptionKey": "অবৈধ এনক্রীপশন কী।",
|
||||
"collabOfflineWarning": "",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"collabOfflineWarning": ""
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "অসমর্থিত ফাইল।",
|
||||
@@ -269,9 +212,9 @@
|
||||
"fileTooBig": "ফাইলটি খুব বড়। সর্বাধিক অনুমোদিত আকার হল {{maxSize}}৷",
|
||||
"svgImageInsertError": "এসভীজী ছবি সন্নিবেশ করা যায়নি। এসভীজী মার্কআপটি অবৈধ মনে হচ্ছে৷",
|
||||
"failedToFetchImage": "",
|
||||
"invalidSVGString": "এসভীজী মার্কআপটি অবৈধ মনে হচ্ছে৷",
|
||||
"cannotResolveCollabServer": "কোল্যাব সার্ভারের সাথে সংযোগ করা যায়নি। পৃষ্ঠাটি পুনরায় লোড করে আবার চেষ্টা করুন।",
|
||||
"importLibraryError": "সংগ্রহ লোড করা যায়নি",
|
||||
"saveLibraryError": "",
|
||||
"collabSaveFailed": "",
|
||||
"collabSaveFailed_sizeExceeded": "",
|
||||
"imageToolNotSupported": "",
|
||||
@@ -292,7 +235,6 @@
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "বাছাই",
|
||||
"lasso": "",
|
||||
"image": "চিত্র সন্নিবেশ",
|
||||
"rectangle": "আয়তক্ষেত্র",
|
||||
"diamond": "রুহিতন",
|
||||
@@ -304,7 +246,7 @@
|
||||
"library": "সংগ্রহ",
|
||||
"lock": "আঁকার পরে নির্বাচিত টুল সক্রিয় রাখুন",
|
||||
"penMode": "",
|
||||
"link": "",
|
||||
"link": "একটি নির্বাচিত আকৃতির জন্য লিঙ্ক যোগ বা আপডেট করুন",
|
||||
"eraser": "ঝাড়ন",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
@@ -313,23 +255,7 @@
|
||||
"hand": "",
|
||||
"extraTools": "",
|
||||
"mermaidToExcalidraw": "",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "",
|
||||
"diamond": "",
|
||||
"ellipse": "",
|
||||
"arrow": "",
|
||||
"line": "",
|
||||
"freedraw": "",
|
||||
"text": "",
|
||||
"image": "",
|
||||
"group": "",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"selection": "",
|
||||
"iframe": ""
|
||||
"magicSettings": ""
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "ক্যানভাস কার্যকলাপ",
|
||||
@@ -337,33 +263,28 @@
|
||||
"shapes": "আকার(গুলি)"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"linearElement": "একাধিক বিন্দু শুরু করতে ক্লিক করুন, একক লাইনের জন্য টেনে আনুন",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "ক্লিক করুন এবং টেনে আনুন, আপনার কাজ শেষ হলে ছেড়ে দিন",
|
||||
"text": "বিশেষ্য: আপনি নির্বাচন টুলের সাথে যে কোনো জায়গায় ডাবল-ক্লিক করে পাঠ্য যোগ করতে পারেন",
|
||||
"embeddable": "",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"text_selected": "লেখা সম্পাদনা করতে ডাবল-ক্লিক করুন বা এন্টার টিপুন",
|
||||
"text_editing": "লেখা সম্পাদনা শেষ করতে এসকেপ বা কন্ট্রোল/কম্যান্ড যোগে এন্টার টিপুন",
|
||||
"linearElementMulti": "শেষ বিন্দুতে ক্লিক করুন অথবা শেষ করতে এসকেপ বা এন্টার টিপুন",
|
||||
"lockAngle": "ঘোরানোর সময় আপনি শিফ্ট ধরে রেখে কোণ সীমাবদ্ধ করতে পারেন",
|
||||
"resize": "আপনি আকার পরিবর্তন করার সময় শিফ্ট ধরে রেখে অনুপাতকে সীমাবদ্ধ করতে পারেন,\nকেন্দ্র থেকে আকার পরিবর্তন করতে অল্ট ধরে রাখুন",
|
||||
"resizeImage": "আপনি শিফ্ট ধরে রেখে অবাধে আকার পরিবর্তন করতে পারেন, কেন্দ্র থেকে আকার পরিবর্তন করতে অল্ট ধরুন",
|
||||
"rotate": "আপনি ঘোরানোর সময় শিফ্ট ধরে রেখে কোণগুলিকে সীমাবদ্ধ করতে পারেন",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"lineEditor_pointSelected": "বিন্দু(গুলি) মুছতে ডিলিট টিপুন, কন্ট্রোল/কম্যান্ড যোগে ডি টিপুন নকল করতে অথবা সরানোর জন্য টানুন",
|
||||
"lineEditor_nothingSelected": "সম্পাদনা করার জন্য একটি বিন্দু নির্বাচন করুন (একাধিক নির্বাচন করতে শিফ্ট ধরে রাখুন),\nঅথবা অল্ট ধরে রাখুন এবং নতুন বিন্দু যোগ করতে ক্লিক করুন",
|
||||
"placeImage": "ছবিটি স্থাপন করতে ক্লিক করুন, অথবা নিজে আকার সেট করতে ক্লিক করুন এবং টেনে আনুন",
|
||||
"publishLibrary": "আপনার নিজস্ব সংগ্রহ প্রকাশ করুন",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"bindTextToElement": "লেখা যোগ করতে এন্টার টিপুন",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"eraserRevert": "মুছে ফেলার জন্য চিহ্নিত উপাদানগুলিকে ফিরিয়ে আনতে অল্ট ধরে রাখুন",
|
||||
"firefox_clipboard_write": "",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": ""
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "প্রিভিউ দেখাতে অপারগ",
|
||||
@@ -378,12 +299,9 @@
|
||||
"openIssueMessage": "আমরা ত্রুটিতে আপনার দৃশ্যের তথ্য অন্তর্ভুক্ত না করার জন্য খুব সতর্ক ছিলাম। আপনার দৃশ্য ব্যক্তিগত না হলে, আমাদের অনুসরণ করার কথা বিবেচনা করুন <button>ত্রুটি ইতিবৃত্ত।</button> অনুগ্রহ করে GitHub ইস্যুতে অনুলিপি এবং পেস্ট করে নীচের তথ্য অন্তর্ভুক্ত করুন।",
|
||||
"sceneContent": "দৃশ্য বিষয়বস্তু:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": ""
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "",
|
||||
"desc_privacy": "",
|
||||
"desc_intro": "আপনি আপনার সাথে সহযোগিতা করার জন্য আপনার বর্তমান দৃশ্যে লোকেদের আমন্ত্রণ জানাতে পারেন৷",
|
||||
"desc_privacy": "চিন্তা করবেন না, সেশনটি এন্ড-টু-এন্ড এনক্রিপশন ব্যবহার করে, তাই আপনি যা আঁকবেন তা গোপন থাকবে। এমনকি আমাদের সার্ভার আপনি যা নিয়ে এসেছেন তা দেখতে সক্ষম হবে না।",
|
||||
"button_startSession": "সেশন শুরু করুন",
|
||||
"button_stopSession": "সেশন বন্ধ করুন",
|
||||
"desc_inProgressIntro": "লাইভ-সহযোগীতার সেশন এখন চলছে।",
|
||||
@@ -410,8 +328,6 @@
|
||||
"click": "ক্লিক",
|
||||
"deepSelect": "",
|
||||
"deepBoxSelect": "",
|
||||
"createFlowchart": "",
|
||||
"navigateFlowchart": "",
|
||||
"curvedArrow": "",
|
||||
"curvedLine": "",
|
||||
"documentation": "",
|
||||
@@ -434,9 +350,7 @@
|
||||
"zoomToSelection": "",
|
||||
"toggleElementLock": "",
|
||||
"movePageUpDown": "",
|
||||
"movePageLeftRight": "",
|
||||
"cropStart": "",
|
||||
"cropFinish": ""
|
||||
"movePageLeftRight": ""
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": ""
|
||||
@@ -507,15 +421,13 @@
|
||||
},
|
||||
"stats": {
|
||||
"angle": "কোণ",
|
||||
"shapes": "",
|
||||
"element": "",
|
||||
"elements": "",
|
||||
"height": "",
|
||||
"scene": "",
|
||||
"selected": "",
|
||||
"storage": "",
|
||||
"fullTitle": "",
|
||||
"title": "",
|
||||
"generalStats": "",
|
||||
"elementProperties": "",
|
||||
"total": "",
|
||||
"version": "",
|
||||
"versionCopy": "",
|
||||
@@ -527,15 +439,13 @@
|
||||
"copyStyles": "",
|
||||
"copyToClipboard": "ক্লিপবোর্ডে কপি করা হয়েছে।",
|
||||
"copyToClipboardAsPng": "",
|
||||
"copyToClipboardAsSvg": "",
|
||||
"fileSaved": "",
|
||||
"fileSavedToFilename": "",
|
||||
"canvas": "",
|
||||
"selection": "বাছাই",
|
||||
"pasteAsSingleElement": "",
|
||||
"unableToEmbed": "",
|
||||
"unrecognizedLinkFormat": "",
|
||||
"elementLinkCopied": ""
|
||||
"unrecognizedLinkFormat": ""
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "",
|
||||
@@ -568,7 +478,6 @@
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "",
|
||||
"colors": "",
|
||||
"shades": "",
|
||||
@@ -612,53 +521,5 @@
|
||||
"description": "",
|
||||
"syntax": "",
|
||||
"preview": ""
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": ""
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": ""
|
||||
},
|
||||
"sceneFonts": "",
|
||||
"availableFonts": "",
|
||||
"empty": ""
|
||||
},
|
||||
"userList": {
|
||||
"empty": "",
|
||||
"hint": {
|
||||
"text": "",
|
||||
"followStatus": "",
|
||||
"inCall": "",
|
||||
"micMuted": "",
|
||||
"isSpeaking": ""
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "",
|
||||
"shortcuts": {
|
||||
"select": "",
|
||||
"confirm": "",
|
||||
"close": ""
|
||||
},
|
||||
"recents": "",
|
||||
"search": {
|
||||
"placeholder": "",
|
||||
"noMatch": ""
|
||||
},
|
||||
"itemNotAvailable": "",
|
||||
"shortcutHint": ""
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,664 +0,0 @@
|
||||
{
|
||||
"labels": {
|
||||
"paste": "পেস্ট করুন",
|
||||
"pasteAsPlaintext": "প্লেইনটেক্সট হিসাবে পেস্ট করুন",
|
||||
"pasteCharts": "চার্ট পেস্ট করুন",
|
||||
"selectAll": "সবটা সিলেক্ট করুন",
|
||||
"multiSelect": "একাধিক সিলেক্ট করুন",
|
||||
"moveCanvas": "ক্যানভাস সরান",
|
||||
"cut": "কাট করুন",
|
||||
"copy": "কপি করুন",
|
||||
"copyAsPng": "পীএনজী ছবির মতন কপি করুন",
|
||||
"copyAsSvg": "এসভীজী ছবির মতন কপি করুন",
|
||||
"copyText": "লিখিত তথ্যের মতন কপি করুন",
|
||||
"copySource": "পিএনজি ছবি ক্লিপবোর্ডে কপি করুন",
|
||||
"convertToCode": "কোডে রূপান্তর করুন",
|
||||
"bringForward": "অধিকতর সামনে আনুন",
|
||||
"sendToBack": "অধিকতর পিছনে নিয়ে যান",
|
||||
"bringToFront": "সবার সামনে আনুন",
|
||||
"sendBackward": "সবার পিছনে নিয়ে যান",
|
||||
"delete": "মুছা",
|
||||
"copyStyles": "ডিজাইন কপি করুন",
|
||||
"pasteStyles": "ডিজাইন পেস্ট করুন",
|
||||
"stroke": "রেখাংশ",
|
||||
"changeStroke": "Hi",
|
||||
"background": "পটভূমি",
|
||||
"changeBackground": "পটভূমির রঙ পরিবর্তন করুন",
|
||||
"fill": "রং",
|
||||
"strokeWidth": "রেখাংশের বেধ",
|
||||
"strokeStyle": "রেখাংশের ডিজাইন",
|
||||
"strokeStyle_solid": "পুরু",
|
||||
"strokeStyle_dashed": "পাতলা",
|
||||
"strokeStyle_dotted": "বিন্দুবিন্দু",
|
||||
"sloppiness": "ভ্রান্তি",
|
||||
"opacity": "দৃশ্যমানতা",
|
||||
"textAlign": "লেখ অনুভূমি",
|
||||
"edges": "কোণ",
|
||||
"sharp": "তীক্ষ্ণ",
|
||||
"round": "গোল",
|
||||
"arrowheads": "তীরের শীর্ষভাগ",
|
||||
"arrowhead_none": "কিছু না",
|
||||
"arrowhead_arrow": "তীর",
|
||||
"arrowhead_bar": "রেখাংশ",
|
||||
"arrowhead_circle": "বৃত্ত",
|
||||
"arrowhead_circle_outline": "বৃত্তীয় (প্রান্তরেখা) প্রান্তরেখা",
|
||||
"arrowhead_triangle": "ত্রিভূজ",
|
||||
"arrowhead_triangle_outline": "ত্রিভুজ (প্রান্তরেখা) প্রান্তরেখা",
|
||||
"arrowhead_diamond": "হীরক",
|
||||
"arrowhead_diamond_outline": "হীরক (প্রান্তরেখা)",
|
||||
"arrowhead_crowfoot_many": "",
|
||||
"arrowhead_crowfoot_one": "",
|
||||
"arrowhead_crowfoot_one_or_many": "",
|
||||
"more_options": "",
|
||||
"arrowtypes": "",
|
||||
"arrowtype_sharp": "",
|
||||
"arrowtype_round": "",
|
||||
"arrowtype_elbowed": "",
|
||||
"fontSize": "লেখনীর মাত্রা",
|
||||
"fontFamily": "লেখনীর হরফ",
|
||||
"addWatermark": "এক্সক্যালিড্র দ্বারা প্রস্তুত",
|
||||
"handDrawn": "হাতে আঁকা",
|
||||
"normal": "স্বাভাবিক",
|
||||
"code": "কোড",
|
||||
"small": "ছোট",
|
||||
"medium": "মাঝারি",
|
||||
"large": "বড়",
|
||||
"veryLarge": "অনেক বড়",
|
||||
"solid": "দৃঢ়",
|
||||
"hachure": "ভ্রুলেখা",
|
||||
"zigzag": "আঁকাবাঁকা",
|
||||
"crossHatch": "ক্রস হ্যাচ",
|
||||
"thin": "পাতলা",
|
||||
"bold": "পুরু",
|
||||
"left": "বাম",
|
||||
"center": "কেন্দ্র",
|
||||
"right": "ডান",
|
||||
"extraBold": "অতি পুরু",
|
||||
"architect": "স্থপতি",
|
||||
"artist": "শিল্পী",
|
||||
"cartoonist": "চিত্রকার",
|
||||
"fileTitle": "ফাইলের নাম",
|
||||
"colorPicker": "রং পছন্দ করুন",
|
||||
"canvasColors": "ক্যানভাসের রং",
|
||||
"canvasBackground": "ক্যানভাসের পটভূমি",
|
||||
"drawingCanvas": "ব্যবহৃত ক্যানভাস",
|
||||
"clearCanvas": "পরিষ্কার ক্যানভাস",
|
||||
"layers": "মাত্রা",
|
||||
"actions": "ক্রিয়া",
|
||||
"language": "ভাষা",
|
||||
"liveCollaboration": "সরাসরি পারস্পরিক সহযোগিতা...",
|
||||
"duplicateSelection": "সদৃশ সিলেক্ট",
|
||||
"untitled": "অনামী",
|
||||
"name": "নাম",
|
||||
"yourName": "আপনার নাম",
|
||||
"madeWithExcalidraw": "এক্সক্যালিড্র দ্বারা তৈরি",
|
||||
"group": "দল গঠন করুন",
|
||||
"ungroup": "দল বিভেদ করুন",
|
||||
"collaborators": "সহযোগী",
|
||||
"toggleGrid": "",
|
||||
"addToLibrary": "সংগ্রহে যোগ করুন",
|
||||
"removeFromLibrary": "সংগ্রহ থেকে বের করুন",
|
||||
"libraryLoadingMessage": "সংগ্রহ তৈরি হচ্ছে",
|
||||
"libraries": "সংগ্রহ দেখুন",
|
||||
"loadingScene": "দৃশ্য তৈরি হচ্ছে",
|
||||
"loadScene": "",
|
||||
"align": "পংক্তিবিন্যাস",
|
||||
"alignTop": "উপর পংক্তি",
|
||||
"alignBottom": "নিম্ন পংক্তি",
|
||||
"alignLeft": "বাম পংক্তি",
|
||||
"alignRight": "ডান পংক্তি",
|
||||
"centerVertically": "উলম্ব কেন্দ্রিত",
|
||||
"centerHorizontally": "অনুভূমিক কেন্দ্রিত",
|
||||
"distributeHorizontally": "অনুভূমিকভাবে বিতরণ করুন",
|
||||
"distributeVertically": "উল্লম্বভাবে বিতরণ করুন",
|
||||
"flipHorizontal": "অনুভূমিক আবর্তন",
|
||||
"flipVertical": "উলম্ব আবর্তন",
|
||||
"viewMode": "দৃশ্য",
|
||||
"share": "ভাগ করুন",
|
||||
"showStroke": "",
|
||||
"showBackground": "পটভূমির রঙ নির্বাচনকারী অপশন দেখান",
|
||||
"showFonts": "",
|
||||
"toggleTheme": "",
|
||||
"theme": "",
|
||||
"personalLib": "ব্যক্তিগত লাইব্রেরি",
|
||||
"excalidrawLib": "এক্সক্যালিড্র লাইব্রেরি",
|
||||
"decreaseFontSize": "লেখনীর মাত্রা কমান",
|
||||
"increaseFontSize": "লেখনীর মাত্রা বাড়ান",
|
||||
"unbindText": "লেখার জোড় খুলুন",
|
||||
"bindText": "কন্টেইনারের সাথে লেখা জোড়া লাগান",
|
||||
"createContainerFromText": "",
|
||||
"link": {
|
||||
"edit": "লিঙ্ক সংশোধন",
|
||||
"editEmbed": "",
|
||||
"create": "",
|
||||
"label": "লিঙ্ক নামকরণ",
|
||||
"labelEmbed": "লিংক ও এম্বেড",
|
||||
"empty": "কোন লিংক সেট করা নেই",
|
||||
"hint": "",
|
||||
"goToElement": ""
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "লাইন সম্পাদনা করুন",
|
||||
"editArrow": ""
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "আবদ্ধ করুন",
|
||||
"unlock": "বিচ্ছিন্ন করুন",
|
||||
"lockAll": "সব আবদ্ধ করুন",
|
||||
"unlockAll": "সব বিচ্ছিন্ন করুন"
|
||||
},
|
||||
"statusPublished": "প্রকাশিত",
|
||||
"sidebarLock": "লক",
|
||||
"selectAllElementsInFrame": "ফ্রেমের ভিতরের সব উপকরণ বাছাই করুন",
|
||||
"removeAllElementsFromFrame": "ফ্রেম থেকে সব উপকরণ মুছুন",
|
||||
"eyeDropper": "ক্যানভাস থেকে রঙ বাছাই করুন",
|
||||
"textToDiagram": "লেখা থেকে ডায়াগ্রাম",
|
||||
"prompt": "",
|
||||
"followUs": "",
|
||||
"discordChat": "",
|
||||
"zoomToFitViewport": "",
|
||||
"zoomToFitSelection": "",
|
||||
"zoomToFit": "",
|
||||
"installPWA": "",
|
||||
"autoResize": "",
|
||||
"imageCropping": "",
|
||||
"unCroppedDimension": "",
|
||||
"copyElementLink": "",
|
||||
"linkToElement": "",
|
||||
"wrapSelectionInFrame": "",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "",
|
||||
"desc": "",
|
||||
"notFound": ""
|
||||
},
|
||||
"library": {
|
||||
"noItems": "সংগ্রহে কিছু যোগ করা হয়নি",
|
||||
"hint_emptyLibrary": "এখানে যোগ করার জন্য ক্যানভাসে একটি বস্তু নির্বাচন করুন, অথবা নীচে, প্রকাশ্য সংগ্রহশালা থেকে একটি সংগ্রহ ইনস্টল করুন৷",
|
||||
"hint_emptyPrivateLibrary": "এখানে যোগ করার জন্য ক্যানভাসে একটি বস্তু নির্বাচন করুন",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "",
|
||||
"noMatch": "",
|
||||
"singleResult": "",
|
||||
"multipleResults": "",
|
||||
"placeholder": "",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "ক্যানভাস সাফ করুন",
|
||||
"exportJSON": "জেসন নিবদ্ধ করুন",
|
||||
"exportImage": "",
|
||||
"export": "",
|
||||
"copyToClipboard": "ক্লিপবোর্ডে কপি করুন",
|
||||
"copyLink": "",
|
||||
"save": "জমা করুন",
|
||||
"saveAs": "অন্যভাবে জমা করুন",
|
||||
"load": "",
|
||||
"getShareableLink": "ভাগযোগ্য লিঙ্ক পান",
|
||||
"close": "বন্ধ করুন",
|
||||
"selectLanguage": "ভাষা চিহ্নিত করুন",
|
||||
"scrollBackToContent": "বিষয়বস্তুতে ফেরত যান",
|
||||
"zoomIn": "বড় করুন",
|
||||
"zoomOut": "ছোট করুন",
|
||||
"resetZoom": "স্বাভাবিক করুন",
|
||||
"menu": "তালিকা",
|
||||
"done": "সম্পন্ন",
|
||||
"edit": "সংশোধন করুন",
|
||||
"undo": "ফেরত যান",
|
||||
"redo": "পুনরায় করুন",
|
||||
"resetLibrary": "সংগ্রহ সাফ করুন",
|
||||
"createNewRoom": "নতুন রুম বানান",
|
||||
"fullScreen": "পূর্ণস্ক্রীন",
|
||||
"darkMode": "ডার্ক মোড",
|
||||
"lightMode": "লাইট মোড",
|
||||
"systemMode": "",
|
||||
"zenMode": "জেন মোড",
|
||||
"objectsSnapMode": "",
|
||||
"exitZenMode": "জেন মোড বন্ধ করুন",
|
||||
"cancel": "বাতিল",
|
||||
"saveLibNames": "",
|
||||
"clear": "সাফ",
|
||||
"remove": "বিয়োগ",
|
||||
"embed": "",
|
||||
"publishLibrary": "",
|
||||
"submit": "জমা করুন",
|
||||
"confirm": "নিশ্চিত করুন",
|
||||
"embeddableInteractionButton": ""
|
||||
},
|
||||
"alerts": {
|
||||
"clearReset": "এটি পুরো ক্যানভাস সাফ করবে। আপনি কি নিশ্চিত?",
|
||||
"couldNotCreateShareableLink": "ভাগ করা যায় এমন লিঙ্ক তৈরি করা যায়নি।",
|
||||
"couldNotCreateShareableLinkTooBig": "ভাগ করা যায় এমন লিঙ্ক তৈরি করা যায়নি: দৃশ্যটি খুব বড়",
|
||||
"couldNotLoadInvalidFile": "অবৈধ ফাইল লোড করা যায়নি",
|
||||
"importBackendFailed": "ব্যাকেন্ড থেকে আপলোড ব্যর্থ হয়েছে।",
|
||||
"cannotExportEmptyCanvas": "খালি ক্যানভাস নিবদ্ধ করা যাবে না।",
|
||||
"couldNotCopyToClipboard": "ক্লিপবোর্ডে কপি করা যায়নি।",
|
||||
"decryptFailed": "তথ্য ডিক্রিপ্ট করা যায়নি।",
|
||||
"uploadedSecurly": "আপলোডটি এন্ড-টু-এন্ড এনক্রিপশনের মাধ্যমে সুরক্ষিত করা হয়েছে, যার অর্থ হল এক্সক্যালিড্র সার্ভার এবং তৃতীয় পক্ষের দ্বারা পড়তে পারা সম্ভব নয়।",
|
||||
"loadSceneOverridePrompt": "বাহ্যিক অঙ্কন লোড করা আপনার বিদ্যমান দৃশ্য প্রতিস্থাপন করবে। আপনি কি অবিরত করতে চান?",
|
||||
"collabStopOverridePrompt": "অধিবেশন বন্ধ করা আপনার পূর্ববর্তী, স্থানীয়ভাবে সঞ্চিত অঙ্কন ওভাররাইট করবে। আপনি কি নিশ্চিত?\n\n(যদি আপনি আপনার স্থানীয় অঙ্কন রাখতে চান, তাহলে শুধু ব্রাউজার ট্যাবটি বন্ধ করুন।)",
|
||||
"errorAddingToLibrary": "বস্তুটি সংগ্রহে যোগ করা যায়নি",
|
||||
"errorRemovingFromLibrary": "বস্তুটি সংগ্রহ থেকে বিয়োগ করা যায়নি",
|
||||
"confirmAddLibrary": "এটি আপনার সংগ্রহে {{numShapes}} আকার(গুলি) যোগ করবে। আপনি কি নিশ্চিত?",
|
||||
"imageDoesNotContainScene": "এই ছবিতে কোনো দৃশ্যের তথ্য আছে বলে মনে হয় না৷ আপনি কি নিবদ্ধ করার সময় দৃশ্য এমবেডিং করতে সক্ষম?",
|
||||
"cannotRestoreFromImage": "এই ফাইল থেকে দৃশ্য পুনরুদ্ধার করা যায়নি",
|
||||
"invalidSceneUrl": "সরবরাহ করা লিঙ্ক থেকে দৃশ্য লোড করা যায়নি৷ এটি হয় বিকৃত, অথবা বৈধ এক্সক্যালিড্র জেসন তথ্য নেই৷",
|
||||
"resetLibrary": "এটি আপনার সংগ্রহ পরিষ্কার করবে। আপনি কি নিশ্চিত?",
|
||||
"removeItemsFromsLibrary": "সংগ্রহ থেকে {{count}} বস্তু বিয়োগ করা হবে। আপনি কি নিশ্চিত?",
|
||||
"invalidEncryptionKey": "অবৈধ এনক্রীপশন কী।",
|
||||
"collabOfflineWarning": "",
|
||||
"localStorageQuotaExceeded": ""
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "অসমর্থিত ফাইল।",
|
||||
"imageInsertError": "ছবি সন্নিবেশ করা যায়নি। পরে আবার চেষ্টা করুন...",
|
||||
"fileTooBig": "ফাইলটি খুব বড়। সর্বাধিক অনুমোদিত আকার হল {{maxSize}}৷",
|
||||
"svgImageInsertError": "এসভীজী ছবি সন্নিবেশ করা যায়নি। এসভীজী মার্কআপটি অবৈধ মনে হচ্ছে৷",
|
||||
"failedToFetchImage": "",
|
||||
"cannotResolveCollabServer": "কোল্যাব সার্ভারের সাথে সংযোগ করা যায়নি। পৃষ্ঠাটি পুনরায় লোড করে আবার চেষ্টা করুন।",
|
||||
"importLibraryError": "সংগ্রহ লোড করা যায়নি",
|
||||
"saveLibraryError": "",
|
||||
"collabSaveFailed": "",
|
||||
"collabSaveFailed_sizeExceeded": "",
|
||||
"imageToolNotSupported": "",
|
||||
"brave_measure_text_error": {
|
||||
"line1": "",
|
||||
"line2": "",
|
||||
"line3": "",
|
||||
"line4": ""
|
||||
},
|
||||
"libraryElementTypeError": {
|
||||
"embeddable": "",
|
||||
"iframe": "",
|
||||
"image": ""
|
||||
},
|
||||
"asyncPasteFailedOnRead": "",
|
||||
"asyncPasteFailedOnParse": "",
|
||||
"copyToSystemClipboardFailed": ""
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "বাছাই",
|
||||
"lasso": "",
|
||||
"image": "চিত্র সন্নিবেশ",
|
||||
"rectangle": "আয়তক্ষেত্র",
|
||||
"diamond": "রুহিতন",
|
||||
"ellipse": "উপবৃত্ত",
|
||||
"arrow": "তীর",
|
||||
"line": "রেখা",
|
||||
"freedraw": "কলম",
|
||||
"text": "লেখা",
|
||||
"library": "সংগ্রহ",
|
||||
"lock": "আঁকার পরে নির্বাচিত টুল সক্রিয় রাখুন",
|
||||
"penMode": "",
|
||||
"link": "",
|
||||
"eraser": "ঝাড়ন",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"laser": "",
|
||||
"hand": "",
|
||||
"extraTools": "",
|
||||
"mermaidToExcalidraw": "",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "",
|
||||
"diamond": "",
|
||||
"ellipse": "",
|
||||
"arrow": "",
|
||||
"line": "",
|
||||
"freedraw": "",
|
||||
"text": "",
|
||||
"image": "",
|
||||
"group": "",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"selection": "",
|
||||
"iframe": ""
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "ক্যানভাস কার্যকলাপ",
|
||||
"selectedShapeActions": "বাছাই করা আকার(গুলি)র কার্যকলাপ",
|
||||
"shapes": "আকার(গুলি)"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"linearElement": "একাধিক বিন্দু শুরু করতে ক্লিক করুন, একক লাইনের জন্য টেনে আনুন",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "ক্লিক করুন এবং টেনে আনুন, আপনার কাজ শেষ হলে ছেড়ে দিন",
|
||||
"text": "বিশেষ্য: আপনি নির্বাচন টুলের সাথে যে কোনো জায়গায় ডাবল-ক্লিক করে পাঠ্য যোগ করতে পারেন",
|
||||
"embeddable": "",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"publishLibrary": "আপনার নিজস্ব সংগ্রহ প্রকাশ করুন",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"firefox_clipboard_write": "",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "প্রিভিউ দেখাতে অপারগ",
|
||||
"canvasTooBig": "ক্যানভাস অনেক বড়।",
|
||||
"canvasTooBigTip": "বিশেষ্য: দূরতম উপাদানগুলোকে একটু কাছাকাছি নিয়ে যাওয়ার চেষ্টা করুন।"
|
||||
},
|
||||
"errorSplash": {
|
||||
"headingMain": "একটি ত্রুটির সম্মুখীন হয়েছে৷ চেষ্টা করুন <button>পৃষ্ঠাটি পুনরায় লোড করার।</button>",
|
||||
"clearCanvasMessage": "যদি পুনরায় লোড করা কাজ না করে, চেষ্টা করুন <button>ক্যানভাস পরিষ্কার করার।</button>",
|
||||
"clearCanvasCaveat": " এর ফলে কাজের ক্ষতি হবে ",
|
||||
"trackedToSentry": "ত্রুটি {{eventId}} আমাদের সিস্টেমে ট্র্যাক করা হয়েছিল।",
|
||||
"openIssueMessage": "আমরা ত্রুটিতে আপনার দৃশ্যের তথ্য অন্তর্ভুক্ত না করার জন্য খুব সতর্ক ছিলাম। আপনার দৃশ্য ব্যক্তিগত না হলে, আমাদের অনুসরণ করার কথা বিবেচনা করুন <button>ত্রুটি ইতিবৃত্ত।</button> অনুগ্রহ করে GitHub ইস্যুতে অনুলিপি এবং পেস্ট করে নীচের তথ্য অন্তর্ভুক্ত করুন।",
|
||||
"sceneContent": "দৃশ্য বিষয়বস্তু:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": ""
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "",
|
||||
"desc_privacy": "",
|
||||
"button_startSession": "সেশন শুরু করুন",
|
||||
"button_stopSession": "সেশন বন্ধ করুন",
|
||||
"desc_inProgressIntro": "লাইভ-সহযোগীতার সেশন এখন চলছে।",
|
||||
"desc_shareLink": "আপনি যার সাথে সহযোগিতা করতে চান তাদের সাথে এই লিঙ্কটি ভাগ করুন: ",
|
||||
"desc_exitSession": "অধিবেশন বন্ধ করা আপনাকে রুম থেকে সংযোগ বিচ্ছিন্ন করবে, কিন্তু আপনি স্থানীয়ভাবে দৃশ্যের সাথে কাজ চালিয়ে যেতে সক্ষম হবেন। মনে রাখবেন যে এটি অন্য লোকেদের প্রভাবিত করবে না এবং তারা এখনও তাদের সংস্করণে সহযোগিতা করতে সক্ষম হবে।",
|
||||
"shareTitle": "এক্সক্যালিড্র লাইভ সহযোগিতা সেশনে যোগ দিন"
|
||||
},
|
||||
"errorDialog": {
|
||||
"title": "ত্রুটি"
|
||||
},
|
||||
"exportDialog": {
|
||||
"disk_title": "",
|
||||
"disk_details": "",
|
||||
"disk_button": "",
|
||||
"link_title": "",
|
||||
"link_details": "",
|
||||
"link_button": "",
|
||||
"excalidrawplus_description": "",
|
||||
"excalidrawplus_button": "নিবদ্ধ",
|
||||
"excalidrawplus_exportError": ""
|
||||
},
|
||||
"helpDialog": {
|
||||
"blog": "",
|
||||
"click": "ক্লিক",
|
||||
"deepSelect": "",
|
||||
"deepBoxSelect": "",
|
||||
"createFlowchart": "",
|
||||
"navigateFlowchart": "",
|
||||
"curvedArrow": "",
|
||||
"curvedLine": "",
|
||||
"documentation": "",
|
||||
"doubleClick": "",
|
||||
"drag": "",
|
||||
"editor": "",
|
||||
"editLineArrowPoints": "",
|
||||
"editText": "",
|
||||
"github": "",
|
||||
"howto": "",
|
||||
"or": "অথবা",
|
||||
"preventBinding": "",
|
||||
"tools": "",
|
||||
"shortcuts": "",
|
||||
"textFinish": "",
|
||||
"textNewLine": "",
|
||||
"title": "",
|
||||
"view": "",
|
||||
"zoomToFit": "",
|
||||
"zoomToSelection": "",
|
||||
"toggleElementLock": "",
|
||||
"movePageUpDown": "",
|
||||
"movePageLeftRight": "",
|
||||
"cropStart": "",
|
||||
"cropFinish": ""
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": ""
|
||||
},
|
||||
"publishDialog": {
|
||||
"title": "",
|
||||
"itemName": "",
|
||||
"authorName": "",
|
||||
"githubUsername": "",
|
||||
"twitterUsername": "",
|
||||
"libraryName": "",
|
||||
"libraryDesc": "",
|
||||
"website": "",
|
||||
"placeholder": {
|
||||
"authorName": "",
|
||||
"libraryName": "",
|
||||
"libraryDesc": "",
|
||||
"githubHandle": "",
|
||||
"twitterHandle": "",
|
||||
"website": ""
|
||||
},
|
||||
"errors": {
|
||||
"required": "",
|
||||
"website": ""
|
||||
},
|
||||
"noteDescription": "",
|
||||
"noteGuidelines": "",
|
||||
"noteLicense": "",
|
||||
"noteItems": "",
|
||||
"atleastOneLibItem": "",
|
||||
"republishWarning": ""
|
||||
},
|
||||
"publishSuccessDialog": {
|
||||
"title": "",
|
||||
"content": ""
|
||||
},
|
||||
"confirmDialog": {
|
||||
"resetLibrary": "",
|
||||
"removeItemsFromLib": ""
|
||||
},
|
||||
"imageExportDialog": {
|
||||
"header": "",
|
||||
"label": {
|
||||
"withBackground": "",
|
||||
"onlySelected": "",
|
||||
"darkMode": "",
|
||||
"embedScene": "",
|
||||
"scale": "",
|
||||
"padding": ""
|
||||
},
|
||||
"tooltip": {
|
||||
"embedScene": ""
|
||||
},
|
||||
"title": {
|
||||
"exportToPng": "",
|
||||
"exportToSvg": "",
|
||||
"copyPngToClipboard": ""
|
||||
},
|
||||
"button": {
|
||||
"exportToPng": "",
|
||||
"exportToSvg": "",
|
||||
"copyPngToClipboard": ""
|
||||
}
|
||||
},
|
||||
"encrypted": {
|
||||
"tooltip": "",
|
||||
"link": ""
|
||||
},
|
||||
"stats": {
|
||||
"angle": "কোণ",
|
||||
"shapes": "",
|
||||
"height": "",
|
||||
"scene": "",
|
||||
"selected": "",
|
||||
"storage": "",
|
||||
"fullTitle": "",
|
||||
"title": "",
|
||||
"generalStats": "",
|
||||
"elementProperties": "",
|
||||
"total": "",
|
||||
"version": "",
|
||||
"versionCopy": "",
|
||||
"versionNotAvailable": "",
|
||||
"width": "প্রস্থ"
|
||||
},
|
||||
"toast": {
|
||||
"addedToLibrary": "সংগ্রহশালায় যুক্ত হয়েছে",
|
||||
"copyStyles": "",
|
||||
"copyToClipboard": "ক্লিপবোর্ডে কপি করা হয়েছে।",
|
||||
"copyToClipboardAsPng": "",
|
||||
"copyToClipboardAsSvg": "",
|
||||
"fileSaved": "",
|
||||
"fileSavedToFilename": "",
|
||||
"canvas": "",
|
||||
"selection": "বাছাই",
|
||||
"pasteAsSingleElement": "",
|
||||
"unableToEmbed": "",
|
||||
"unrecognizedLinkFormat": "",
|
||||
"elementLinkCopied": ""
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "",
|
||||
"black": "",
|
||||
"white": "",
|
||||
"red": "",
|
||||
"pink": "",
|
||||
"grape": "",
|
||||
"violet": "",
|
||||
"gray": "",
|
||||
"blue": "",
|
||||
"cyan": "",
|
||||
"teal": "",
|
||||
"green": "",
|
||||
"yellow": "",
|
||||
"orange": "",
|
||||
"bronze": ""
|
||||
},
|
||||
"welcomeScreen": {
|
||||
"app": {
|
||||
"center_heading": "",
|
||||
"center_heading_plus": "",
|
||||
"menuHint": ""
|
||||
},
|
||||
"defaults": {
|
||||
"menuHint": "",
|
||||
"center_heading": "",
|
||||
"toolbarHint": "",
|
||||
"helpHint": ""
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "",
|
||||
"colors": "",
|
||||
"shades": "",
|
||||
"hexCode": "",
|
||||
"noShades": ""
|
||||
},
|
||||
"overwriteConfirm": {
|
||||
"action": {
|
||||
"exportToImage": {
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
},
|
||||
"saveToDisk": {
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
},
|
||||
"excalidrawPlus": {
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"modal": {
|
||||
"loadFromFile": {
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
},
|
||||
"shareableLink": {
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"mermaid": {
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": "",
|
||||
"syntax": "",
|
||||
"preview": ""
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": ""
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": ""
|
||||
},
|
||||
"sceneFonts": "",
|
||||
"availableFonts": "",
|
||||
"empty": ""
|
||||
},
|
||||
"userList": {
|
||||
"empty": "",
|
||||
"hint": {
|
||||
"text": "",
|
||||
"followStatus": "",
|
||||
"inCall": "",
|
||||
"micMuted": "",
|
||||
"isSpeaking": ""
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "",
|
||||
"shortcuts": {
|
||||
"select": "",
|
||||
"confirm": "",
|
||||
"close": ""
|
||||
},
|
||||
"recents": "",
|
||||
"search": {
|
||||
"placeholder": "",
|
||||
"noMatch": ""
|
||||
},
|
||||
"itemNotAvailable": "",
|
||||
"shortcutHint": ""
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,8 @@
|
||||
"copyAsPng": "Copia al porta-retalls com a PNG",
|
||||
"copyAsSvg": "Copia al porta-retalls com a SVG",
|
||||
"copyText": "Copia al porta-retalls com a text",
|
||||
"copySource": "Copia al porta-retalls",
|
||||
"convertToCode": "Converteix a codi",
|
||||
"copySource": "Copia l'origen al porta-retalls",
|
||||
"convertToCode": "",
|
||||
"bringForward": "Porta endavant",
|
||||
"sendToBack": "Envia enrere",
|
||||
"bringToFront": "Porta al davant",
|
||||
@@ -21,9 +21,7 @@
|
||||
"copyStyles": "Copia els estils",
|
||||
"pasteStyles": "Enganxa els estils",
|
||||
"stroke": "Color del traç",
|
||||
"changeStroke": "Canvia el color del traç",
|
||||
"background": "Color del fons",
|
||||
"changeBackground": "Canvia el color de fons",
|
||||
"fill": "Estil del fons",
|
||||
"strokeWidth": "Amplada del traç",
|
||||
"strokeStyle": "Estil del traç",
|
||||
@@ -40,20 +38,12 @@
|
||||
"arrowhead_none": "Cap",
|
||||
"arrowhead_arrow": "Fletxa",
|
||||
"arrowhead_bar": "Barra",
|
||||
"arrowhead_circle": "Cercle",
|
||||
"arrowhead_circle_outline": "Circumferència",
|
||||
"arrowhead_circle": "",
|
||||
"arrowhead_circle_outline": "",
|
||||
"arrowhead_triangle": "Triangle",
|
||||
"arrowhead_triangle_outline": "Triangle (vora)",
|
||||
"arrowhead_diamond": "Rombe",
|
||||
"arrowhead_diamond_outline": "Rombe (vora)",
|
||||
"arrowhead_crowfoot_many": "Potes de gall (moltes)",
|
||||
"arrowhead_crowfoot_one": "Potes de gall (una)",
|
||||
"arrowhead_crowfoot_one_or_many": "Potes de gall (una o moltes)",
|
||||
"more_options": "Més opcions",
|
||||
"arrowtypes": "Tipus de fletxa",
|
||||
"arrowtype_sharp": "Fletxa Esmolada",
|
||||
"arrowtype_round": "Fletxa corba",
|
||||
"arrowtype_elbowed": "Fletxa de colzes",
|
||||
"arrowhead_triangle_outline": "",
|
||||
"arrowhead_diamond": "",
|
||||
"arrowhead_diamond_outline": "",
|
||||
"fontSize": "Mida de lletra",
|
||||
"fontFamily": "Tipus de lletra",
|
||||
"addWatermark": "Afegeix-hi «Fet amb Excalidraw»",
|
||||
@@ -66,7 +56,7 @@
|
||||
"veryLarge": "Molt gran",
|
||||
"solid": "Sòlid",
|
||||
"hachure": "Ratlletes",
|
||||
"zigzag": "Ziga-zaga",
|
||||
"zigzag": "",
|
||||
"crossHatch": "Ratlletes creuades",
|
||||
"thin": "Fi",
|
||||
"bold": "Negreta",
|
||||
@@ -82,7 +72,6 @@
|
||||
"canvasColors": "Usat al llenç",
|
||||
"canvasBackground": "Fons del llenç",
|
||||
"drawingCanvas": "Llenç de dibuix",
|
||||
"clearCanvas": "Neteja el llenç",
|
||||
"layers": "Capes",
|
||||
"actions": "Accions",
|
||||
"language": "Llengua",
|
||||
@@ -95,13 +84,12 @@
|
||||
"group": "Agrupa la selecció",
|
||||
"ungroup": "Desagrupa la selecció",
|
||||
"collaborators": "Col·laboradors",
|
||||
"toggleGrid": "Alterna la quadrícula",
|
||||
"showGrid": "Mostra la graella",
|
||||
"addToLibrary": "Afegir a la biblioteca",
|
||||
"removeFromLibrary": "Eliminar de la biblioteca",
|
||||
"libraryLoadingMessage": "S'està carregant la biblioteca…",
|
||||
"libraries": "Explora les biblioteques",
|
||||
"loadingScene": "S'està carregant l'escena…",
|
||||
"loadScene": "Carrega una escena des d'un fitxer",
|
||||
"align": "Alinea",
|
||||
"alignTop": "Alinea a la part superior",
|
||||
"alignBottom": "Alinea a la part inferior",
|
||||
@@ -117,33 +105,26 @@
|
||||
"share": "Comparteix",
|
||||
"showStroke": "Mostra el selector de color del traç",
|
||||
"showBackground": "Mostra el selector de color de fons",
|
||||
"showFonts": "Mostra el selector tipogràfic",
|
||||
"toggleTheme": "Alternar tema clar i fosc",
|
||||
"theme": "Tema",
|
||||
"toggleTheme": "Activa o desactiva el tema",
|
||||
"personalLib": "Biblioteca personal",
|
||||
"excalidrawLib": "Biblioteca d'Excalidraw",
|
||||
"decreaseFontSize": "Redueix la mida de la lletra",
|
||||
"increaseFontSize": "Augmenta la mida de la lletra",
|
||||
"unbindText": "Desvincular el text",
|
||||
"bindText": "Ajusta el text al contenidor",
|
||||
"createContainerFromText": "Ajusta el text al contenidor",
|
||||
"createContainerFromText": "",
|
||||
"link": {
|
||||
"edit": "Edita l'enllaç",
|
||||
"editEmbed": "Editar enllaç incrustable",
|
||||
"create": "Afegir un enllaç",
|
||||
"editEmbed": "Edita l'enllaç i incrusta-ho",
|
||||
"create": "Crea un enllaç",
|
||||
"createEmbed": "",
|
||||
"label": "Enllaç",
|
||||
"labelEmbed": "Enllaça i encasta",
|
||||
"empty": "No s'ha definit cap enllaç",
|
||||
"hint": "Escriu o enganxa un enllaç aquí",
|
||||
"goToElement": "Anar a l'element objectiu"
|
||||
"labelEmbed": "",
|
||||
"empty": "No s'ha definit cap enllaç"
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "Editar línia",
|
||||
"editArrow": "Edita la fletxa"
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"exit": "Sortir de l'editor de línia"
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "Bloca",
|
||||
@@ -154,49 +135,15 @@
|
||||
"statusPublished": "Publicat",
|
||||
"sidebarLock": "Manté la barra lateral oberta",
|
||||
"selectAllElementsInFrame": "Selecciona tots els elements del marc",
|
||||
"removeAllElementsFromFrame": "Elimina tots els elements del marc",
|
||||
"eyeDropper": "Tria un color del llenç",
|
||||
"textToDiagram": "Text a diagrama",
|
||||
"prompt": "Prompt",
|
||||
"followUs": "Seguiu-nos",
|
||||
"discordChat": "Xat de Discord",
|
||||
"zoomToFitViewport": "Amplia per adaptar-se a la finestra",
|
||||
"zoomToFitSelection": "Zoom per veure la selecció",
|
||||
"zoomToFit": "Zoom per veure tots els elements",
|
||||
"installPWA": "Instal·la Excalidraw localment (PWA)",
|
||||
"autoResize": "Activa la redimensió de text automàtica",
|
||||
"imageCropping": "Retallar la imatge",
|
||||
"unCroppedDimension": "Dimensió sense retallar",
|
||||
"copyElementLink": "Copiar enllaç a objecte",
|
||||
"linkToElement": "Enllaç a l'objecte",
|
||||
"wrapSelectionInFrame": "Embolica la selecció en un marc",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "Enllaç a l'objecte",
|
||||
"desc": "Fes clic en una forma al llenç o enganxa un enllaç.",
|
||||
"notFound": "L'objecte enllaçat no s'ha trobat al llenç."
|
||||
"removeAllElementsFromFrame": "Eliminat tots els elements del marc",
|
||||
"eyeDropper": "",
|
||||
"textToDiagram": "",
|
||||
"prompt": ""
|
||||
},
|
||||
"library": {
|
||||
"noItems": "Encara no s'hi han afegit elements...",
|
||||
"hint_emptyLibrary": "Trieu un element o un llenç per a afegir-lo aquí, o instal·leu una biblioteca del repositori públic, més avall.",
|
||||
"hint_emptyPrivateLibrary": "Trieu un element o un llenç per a afegir-lo aquí.",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "Troba al llenç",
|
||||
"noMatch": "No hem trobat coincidències...",
|
||||
"singleResult": "resultat",
|
||||
"multipleResults": "resultats",
|
||||
"placeholder": "Troba al llenç...",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"hint_emptyPrivateLibrary": "Trieu un element o un llenç per a afegir-lo aquí."
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "Neteja el llenç",
|
||||
@@ -204,7 +151,6 @@
|
||||
"exportImage": "Exporta la imatge...",
|
||||
"export": "Guardar a...",
|
||||
"copyToClipboard": "Copia al porta-retalls",
|
||||
"copyLink": "Copia l'enllaç",
|
||||
"save": "Desa al fitxer actual",
|
||||
"saveAs": "Anomena i desa",
|
||||
"load": "Obrir",
|
||||
@@ -225,16 +171,14 @@
|
||||
"fullScreen": "Pantalla completa",
|
||||
"darkMode": "Mode fosc",
|
||||
"lightMode": "Mode clar",
|
||||
"systemMode": "Mode del sistema",
|
||||
"zenMode": "Mode zen",
|
||||
"objectsSnapMode": "Ajusta als objectes",
|
||||
"objectsSnapMode": "",
|
||||
"exitZenMode": "Surt de mode zen",
|
||||
"cancel": "Cancel·la",
|
||||
"saveLibNames": "",
|
||||
"clear": "Neteja",
|
||||
"remove": "Suprimeix",
|
||||
"embed": "Commuta incrustació",
|
||||
"publishLibrary": "",
|
||||
"embed": "",
|
||||
"publishLibrary": "Publica",
|
||||
"submit": "Envia",
|
||||
"confirm": "Confirma",
|
||||
"embeddableInteractionButton": "Feu clic per interactuar"
|
||||
@@ -260,39 +204,37 @@
|
||||
"resetLibrary": "Això buidarà la biblioteca. N'esteu segur?",
|
||||
"removeItemsFromsLibrary": "Suprimir {{count}} element(s) de la biblioteca?",
|
||||
"invalidEncryptionKey": "La clau d'encriptació ha de tenir 22 caràcters. La col·laboració en directe està desactivada.",
|
||||
"collabOfflineWarning": "Sense connexió a internet disponible.\nEls vostres canvis no seran guardats!",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"collabOfflineWarning": "Sense connexió a internet disponible.\nEls vostres canvis no seran guardats!"
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "Tipus de fitxer no suportat.",
|
||||
"imageInsertError": "No s'ha pogut insertar la imatge, torneu-ho a provar més tard...",
|
||||
"fileTooBig": "El fitxer és massa gros. La mida màxima permesa és {{maxSize}}.",
|
||||
"svgImageInsertError": "No ha estat possible inserir la imatge SVG. Les marques SVG semblen invàlides.",
|
||||
"failedToFetchImage": "No s'ha pogut obtenir la imatge.",
|
||||
"failedToFetchImage": "",
|
||||
"invalidSVGString": "SVG no vàlid.",
|
||||
"cannotResolveCollabServer": "No ha estat possible connectar amb el servidor collab. Si us plau recarregueu la pàgina i torneu a provar.",
|
||||
"importLibraryError": "No s'ha pogut carregar la biblioteca",
|
||||
"saveLibraryError": "No hem pogut desar la llibreria a l'emmagatzematge. Si us plau, deseu la vostra llibreria a un fitxer local per assegurar que no perds els canvis.",
|
||||
"collabSaveFailed": "No s'ha pogut desar a la base de dades de fons. Si els problemes persisteixen, hauríeu de desar el fitxer localment per assegurar-vos que no perdeu el vostre treball.",
|
||||
"collabSaveFailed_sizeExceeded": "No s'ha pogut desar a la base de dades de fons, sembla que el llenç és massa gran. Hauríeu de desar el fitxer localment per assegurar-vos que no perdeu el vostre treball.",
|
||||
"imageToolNotSupported": "Les imatges no estan habilitades.",
|
||||
"imageToolNotSupported": "",
|
||||
"brave_measure_text_error": {
|
||||
"line1": "Sembla que feu servir el navegador Brave amb el <bold>blocatge agressiu d'indentificació única</bold> activat.",
|
||||
"line2": "Això podria provocar problemes amb els <bold>elements de text</bold> en els vostres dissenys.",
|
||||
"line3": "Us recomanem encaridament que desactiveu aquesta característica. Podeu seguir <link>aquests passos</link> per a fer-ho.",
|
||||
"line4": "Si els elements de text no es mostren correctament malgrat haver desactivat aquesta opció, si us plau, obriu una <issueLink>incidència</issueLink> a la nostra pàgina de GitHub o escriviu-nos a <discordLink>Discord</discordLink>"
|
||||
"line1": "",
|
||||
"line2": "",
|
||||
"line3": "",
|
||||
"line4": ""
|
||||
},
|
||||
"libraryElementTypeError": {
|
||||
"embeddable": "Els elements incrustables no poden afegir-se a la biblioteca.",
|
||||
"iframe": "Elements IFrame no es poden afegir a la biblioteca.",
|
||||
"image": "Suport per a afegir imatges a la biblioteca aviat!"
|
||||
"embeddable": "",
|
||||
"iframe": "",
|
||||
"image": ""
|
||||
},
|
||||
"asyncPasteFailedOnRead": "No s'ha pogut enganxar (no s'ha pogut llegir del porta-retalls del sistema).",
|
||||
"asyncPasteFailedOnRead": "",
|
||||
"asyncPasteFailedOnParse": "No s'ha pogut enganxar.",
|
||||
"copyToSystemClipboardFailed": "No s'ha pogut copiar al porta-retalls."
|
||||
"copyToSystemClipboardFailed": ""
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "Selecció",
|
||||
"lasso": "",
|
||||
"image": "Insereix imatge",
|
||||
"rectangle": "Rectangle",
|
||||
"diamond": "Rombe",
|
||||
@@ -304,32 +246,16 @@
|
||||
"library": "Biblioteca",
|
||||
"lock": "Mantenir activa l'eina seleccionada desprès de dibuixar",
|
||||
"penMode": "Mode de llapis - evita tocar",
|
||||
"link": "Afegeix/actualitza l'enllaç per a una forma seleccionada",
|
||||
"link": "Afegeix / actualitza l'enllaç per a la forma seleccionada",
|
||||
"eraser": "Esborrador",
|
||||
"frame": "Eina de marc",
|
||||
"magicframe": "De Wireframe a codi",
|
||||
"embeddable": "Incrustació Web",
|
||||
"laser": "Punter làser",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"laser": "",
|
||||
"hand": "Mà (eina de desplaçament)",
|
||||
"extraTools": "Més eines",
|
||||
"mermaidToExcalidraw": "Mermaid a Excalidraw",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "Rectangle",
|
||||
"diamond": "Rombe",
|
||||
"ellipse": "El·lipse",
|
||||
"arrow": "Fletxa",
|
||||
"line": "Línia",
|
||||
"freedraw": "Dibuix a mà alçada",
|
||||
"text": "Text",
|
||||
"image": "Imatge",
|
||||
"group": "Grup",
|
||||
"frame": "Marc",
|
||||
"magicframe": "De Wireframe a codi",
|
||||
"embeddable": "Incrustació Web",
|
||||
"selection": "Selecció",
|
||||
"iframe": "IFrame"
|
||||
"extraTools": "",
|
||||
"mermaidToExcalidraw": "De Mermaid a Excalidraw",
|
||||
"magicSettings": "Preferències d'IA"
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "Accions del llenç",
|
||||
@@ -337,33 +263,28 @@
|
||||
"shapes": "Formes"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"canvasPanning": "Per moure el llenç, manteniu premuda la roda del ratolí o la barra espaiadora mentre arrossegueu o utilitzeu l'eina manual",
|
||||
"linearElement": "Feu clic per a dibuixar múltiples punts; arrossegueu per a una sola línia",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "Feu clic i arrossegueu, deixeu anar per a finalitzar",
|
||||
"text": "Consell: també podeu afegir text fent doble clic en qualsevol lloc amb l'eina de selecció",
|
||||
"embeddable": "Feu clic i arrossegueu per crear una Incrustació Web",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"embeddable": "",
|
||||
"text_selected": "Feu doble clic o premeu Retorn per a editar el text",
|
||||
"text_editing": "Premeu Escapada o Ctrl+Retorn (o Ordre+Retorn) per a finalitzar l'edició",
|
||||
"linearElementMulti": "Feu clic a l'ultim punt, o pitgeu Esc o Retorn per a finalitzar",
|
||||
"lockAngle": "Per restringir els angles, mantenir premut el majúscul (SHIFT)",
|
||||
"resize": "Per restringir les proporcions mentres es canvia la mida, mantenir premut el majúscul (SHIFT); per canviar la mida des del centre, mantenir premut ALT",
|
||||
"resizeImage": "Podeu redimensionar lliurement prement MAJÚSCULA;\nper a redimensionar des del centre, premeu ALT",
|
||||
"rotate": "Per restringir els angles mentre gira, mantenir premut el majúscul (SHIFT)",
|
||||
"lineEditor_info": "Mantingueu premut Ctrl o Cmd i feu doble clic o premeu Ctrl o Cmd + Retorn per editar els punts",
|
||||
"lineEditor_pointSelected": "Premeu Suprimir per a eliminar el(s) punt(s), CtrlOrCmd+D per a duplicar-lo, o arrossegueu-lo per a moure'l",
|
||||
"lineEditor_nothingSelected": "Seleccioneu un punt per a editar-lo (premeu SHIFT si voleu\nselecció múltiple), o manteniu Alt i feu clic per a afegir més punts",
|
||||
"placeImage": "Feu clic per a col·locar la imatge o clic i arrossegar per a establir-ne la mida manualment",
|
||||
"publishLibrary": "Publiqueu la vostra pròpia llibreria",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"bindTextToElement": "Premeu enter per a afegir-hi text",
|
||||
"deepBoxSelect": "Manteniu CtrlOrCmd per a selecció profunda, i per a evitar l'arrossegament",
|
||||
"eraserRevert": "Mantingueu premuda Alt per a revertir els elements seleccionats per a esborrar",
|
||||
"firefox_clipboard_write": "És probable que aquesta funció es pugui activar posant la marca \"dom.events.asyncClipboard.clipboardItem\" a \"true\". Per canviar les marques del navegador al Firefox, visiteu la pàgina \"about:config\".",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": ""
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "No es pot mostrar la previsualització",
|
||||
@@ -378,12 +299,9 @@
|
||||
"openIssueMessage": "Anàvem amb molta cura de no incloure la informació de la vostra escena en l'error. Si l'escena no és privada, podeu fer-ne el seguiment al nostre <button>rastrejador d'errors.</button> Incloeu la informació a continuació copiant i enganxant a GitHub Issues.",
|
||||
"sceneContent": "Contingut de l'escena:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": "O"
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "Convideu gent a col·laborar en el vostre disseny.",
|
||||
"desc_privacy": "No us amoïneu, la sessió està encriptada d'extrem a extrem i és totalment privada. Ni tan sols el nostre servidor pot veure què dibuixeu.",
|
||||
"desc_intro": "Podeu convidar persones a la vostra escena actual a col·laborar amb vós.",
|
||||
"desc_privacy": "No us preocupeu, la sessió utilitza el xifratge de punta a punta, de manera que qualsevol cosa que dibuixeu romandrà privada. Ni tan sols el nostre servidor podrà veure què feu.",
|
||||
"button_startSession": "Inicia la sessió",
|
||||
"button_stopSession": "Atura la sessió",
|
||||
"desc_inProgressIntro": "La sessió de col·laboració en directe està en marxa.",
|
||||
@@ -410,16 +328,14 @@
|
||||
"click": "clic",
|
||||
"deepSelect": "Selecció profunda",
|
||||
"deepBoxSelect": "Seleccioneu profundament dins del quadre i eviteu arrossegar",
|
||||
"createFlowchart": "Crear un diagrama de flux a partir d'un element genèric",
|
||||
"navigateFlowchart": "Navegar per un diagrama de flux",
|
||||
"curvedArrow": "Fletxa corba",
|
||||
"curvedLine": "Línia corba",
|
||||
"documentation": "Documentació",
|
||||
"doubleClick": "doble clic",
|
||||
"drag": "arrossega",
|
||||
"editor": "Editor",
|
||||
"editLineArrowPoints": "Edita els punts de la línia/fletxa",
|
||||
"editText": "Edita text / afegeix etiqueta",
|
||||
"editLineArrowPoints": "",
|
||||
"editText": "",
|
||||
"github": "Hi heu trobat un problema? Informeu-ne",
|
||||
"howto": "Seguiu les nostres guies",
|
||||
"or": "o",
|
||||
@@ -434,9 +350,7 @@
|
||||
"zoomToSelection": "Zoom per veure la selecció",
|
||||
"toggleElementLock": "Blocar/desblocar la selecció",
|
||||
"movePageUpDown": "Mou la pàgina cap amunt/a baix",
|
||||
"movePageLeftRight": "Mou la pàgina cap a l'esquerra/dreta",
|
||||
"cropStart": "Retallar l'imatge",
|
||||
"cropFinish": "Finalitza el retall d'imatge"
|
||||
"movePageLeftRight": "Mou la pàgina cap a l'esquerra/dreta"
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": "Neteja el llenç"
|
||||
@@ -478,27 +392,27 @@
|
||||
"removeItemsFromLib": "Suprimeix els elements seleccionats de la llibreria"
|
||||
},
|
||||
"imageExportDialog": {
|
||||
"header": "Exporteu la imatge",
|
||||
"header": "",
|
||||
"label": {
|
||||
"withBackground": "Fons",
|
||||
"onlySelected": "Només seleccionat",
|
||||
"withBackground": "",
|
||||
"onlySelected": "Només els seleccionats",
|
||||
"darkMode": "Mode fosc",
|
||||
"embedScene": "Incrusta escena",
|
||||
"scale": "Escala",
|
||||
"padding": "Marge intern (padding)"
|
||||
"embedScene": "",
|
||||
"scale": "",
|
||||
"padding": ""
|
||||
},
|
||||
"tooltip": {
|
||||
"embedScene": "Les dades de l’escena es desaran al fitxer PNG/SVG de manera que es pugui restaurar l’escena.\nAixò farà augmentar la mida del fitxer exportat."
|
||||
"embedScene": ""
|
||||
},
|
||||
"title": {
|
||||
"exportToPng": "Exporteu a PNG",
|
||||
"exportToSvg": "Exporteu a SVG",
|
||||
"copyPngToClipboard": "Copieu el PNG al porta-retalls"
|
||||
"exportToPng": "Exporta a PNG",
|
||||
"exportToSvg": "Exporta a SVG",
|
||||
"copyPngToClipboard": "Copia el PNG al porta-retalls"
|
||||
},
|
||||
"button": {
|
||||
"exportToPng": "PNG",
|
||||
"exportToSvg": "SVG",
|
||||
"copyPngToClipboard": "Copieu al porta-retalls"
|
||||
"exportToSvg": "",
|
||||
"copyPngToClipboard": ""
|
||||
}
|
||||
},
|
||||
"encrypted": {
|
||||
@@ -507,15 +421,13 @@
|
||||
},
|
||||
"stats": {
|
||||
"angle": "Angle",
|
||||
"shapes": "Formes",
|
||||
"element": "Element",
|
||||
"elements": "Elements",
|
||||
"height": "Altura",
|
||||
"scene": "Escena",
|
||||
"selected": "Seleccionat",
|
||||
"storage": "Emmagatzematge",
|
||||
"fullTitle": "Propietats del Llenç i de la Forma",
|
||||
"title": "Propietats",
|
||||
"generalStats": "General",
|
||||
"elementProperties": "Propietats de la forma",
|
||||
"title": "Estadístiques per nerds",
|
||||
"total": "Total",
|
||||
"version": "Versió",
|
||||
"versionCopy": "Feu clic per a copiar",
|
||||
@@ -527,28 +439,26 @@
|
||||
"copyStyles": "S'han copiat els estils.",
|
||||
"copyToClipboard": "S'ha copiat al porta-retalls.",
|
||||
"copyToClipboardAsPng": "S'ha copiat {{exportSelection}} al porta-retalls en format PNG\n({{exportColorScheme}})",
|
||||
"copyToClipboardAsSvg": "S'ha copiat {{exportSelection}} al porta-retalls com a SVG\n({{exportColorScheme}})",
|
||||
"fileSaved": "S'ha desat el fitxer.",
|
||||
"fileSavedToFilename": "S'ha desat a {filename}",
|
||||
"canvas": "el llenç",
|
||||
"selection": "la selecció",
|
||||
"pasteAsSingleElement": "Fer servir {{shortcut}} per enganxar com un sol element,\no enganxeu-lo en un editor de text existent",
|
||||
"unableToEmbed": "Actualment no es permet incrustar aquesta URL. Planteja un problema a GitHub per sol·licitar que l'URL estigui a la llista blanca",
|
||||
"unrecognizedLinkFormat": "L'enllaç que has incrustat no coincideix amb el format esperat. Si us plau, intenta enganxar l'enllaç 'embed' proporcionada pel lloc web d'origen",
|
||||
"elementLinkCopied": "Enllaç copiat al porta-retalls"
|
||||
"unableToEmbed": "",
|
||||
"unrecognizedLinkFormat": ""
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "Transparent",
|
||||
"black": "Negre",
|
||||
"white": "Blanc",
|
||||
"red": "Vermell",
|
||||
"pink": "Rosa",
|
||||
"grape": "Violat (raïm)",
|
||||
"violet": "Violat",
|
||||
"gray": "Gris",
|
||||
"blue": "Blau",
|
||||
"cyan": "Cian",
|
||||
"teal": "Xarxet",
|
||||
"black": "",
|
||||
"white": "",
|
||||
"red": "",
|
||||
"pink": "",
|
||||
"grape": "",
|
||||
"violet": "",
|
||||
"gray": "",
|
||||
"blue": "",
|
||||
"cyan": "",
|
||||
"teal": "",
|
||||
"green": "Verd",
|
||||
"yellow": "Groc",
|
||||
"orange": "Taronja",
|
||||
@@ -568,97 +478,48 @@
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "Colors personalitzats més usats",
|
||||
"colors": "Colors",
|
||||
"shades": "Ombres",
|
||||
"hexCode": "Codi hexadecimal",
|
||||
"noShades": "No hi ha ombres disponibles per a aquest color"
|
||||
"mostUsedCustomColors": "",
|
||||
"colors": "",
|
||||
"shades": "",
|
||||
"hexCode": "",
|
||||
"noShades": ""
|
||||
},
|
||||
"overwriteConfirm": {
|
||||
"action": {
|
||||
"exportToImage": {
|
||||
"title": "Exporteu com a imatge",
|
||||
"button": "Exporteu com a imatge",
|
||||
"description": "Exporta les dades de l'escena com una imatge des de la qual podràs importar-les més tard."
|
||||
"title": "Exporta com a imatge",
|
||||
"button": "Exporta com a imatge",
|
||||
"description": ""
|
||||
},
|
||||
"saveToDisk": {
|
||||
"title": "Deseu al disc",
|
||||
"button": "Deseu al disc",
|
||||
"description": "Exporta les dades de l'escena a un fitxer des del qual podràs importar-les més tard."
|
||||
"title": "Desa al disc",
|
||||
"button": "Desa al disc",
|
||||
"description": ""
|
||||
},
|
||||
"excalidrawPlus": {
|
||||
"title": "Excalidraw+",
|
||||
"button": "Exporta a Excalidraw+",
|
||||
"description": "Desa l'escena al teu espai de treball d'Excalidraw+."
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"modal": {
|
||||
"loadFromFile": {
|
||||
"title": "Carrega des d'un fitxer",
|
||||
"button": "Carrega des d'un fitxer",
|
||||
"description": "Carregar des d'un fitxer <bold>substituirà el contingut actual</bold>.<br></br>Podeu desar el vostre disseny abans fent servir una de les opcions més avall."
|
||||
"description": ""
|
||||
},
|
||||
"shareableLink": {
|
||||
"title": "Carrega des d'un enllaç",
|
||||
"button": "Substitueix el contingut",
|
||||
"description": "Carregar un disseny extern <bold>substituirà el contingut actual</bold>.<br></br>Podeu desar el vostre disseny abans fent servir una de les opcions més avall."
|
||||
"button": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"mermaid": {
|
||||
"title": "Mermaid a Excalidraw",
|
||||
"button": "Inseriu",
|
||||
"description": "Actualment només s'admeten els diagrames <flowchartLink>Flowchart</flowchartLink>, <sequenceLink> Sequence, </sequenceLink> i <classLink> Class </classLink>. Els altres tipus es representaran com a imatge a Excalidraw.",
|
||||
"title": "De Mermaid a Excalidraw",
|
||||
"button": "Insereix",
|
||||
"description": "",
|
||||
"syntax": "Sintaxi de Mermaid",
|
||||
"preview": "Previsualització"
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": "Cerca ràpida"
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": "antic"
|
||||
},
|
||||
"sceneFonts": "En aquesta escena",
|
||||
"availableFonts": "Lletres tipogràfiques disponibles",
|
||||
"empty": "No s'ha trobat cap lletra tipogràfica"
|
||||
},
|
||||
"userList": {
|
||||
"empty": "No s'ha trobat cap usuari",
|
||||
"hint": {
|
||||
"text": "Feu clic sobre un usuari per seguir-lo",
|
||||
"followStatus": "Ara per ara seguiu aquest usuari",
|
||||
"inCall": "L'usuari es troba en una trucada de veu",
|
||||
"micMuted": "El micròfon de l'usuari és silenciat",
|
||||
"isSpeaking": "L'usuari parla ara"
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "Paleta d'ordres",
|
||||
"shortcuts": {
|
||||
"select": "Selecciona",
|
||||
"confirm": "Confirma",
|
||||
"close": "Tanca"
|
||||
},
|
||||
"recents": "Usats recentment",
|
||||
"search": {
|
||||
"placeholder": "Cerca menús, ordres i descobreix joies amagades",
|
||||
"noMatch": "No hi ha ordres coincidents..."
|
||||
},
|
||||
"itemNotAvailable": "Ordre no disponible...",
|
||||
"shortcutHint": "Per obrir la paleta d'ordres, utilitza {{shortcut}}"
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"copyAsPng": "Zkopírovat do schránky jako PNG",
|
||||
"copyAsSvg": "Zkopírovat do schránky jako SVG",
|
||||
"copyText": "Zkopírovat do schránky jako text",
|
||||
"copySource": "Kopírovat zdroj do schránky",
|
||||
"convertToCode": "Převést na kód",
|
||||
"copySource": "",
|
||||
"convertToCode": "",
|
||||
"bringForward": "Přenést blíž",
|
||||
"sendToBack": "Přenést do pozadí",
|
||||
"bringToFront": "Přenést do popředí",
|
||||
@@ -21,9 +21,7 @@
|
||||
"copyStyles": "Kopírovat styly",
|
||||
"pasteStyles": "Vložit styly",
|
||||
"stroke": "Obrys",
|
||||
"changeStroke": "Změnit barvu ohraničení",
|
||||
"background": "Pozadí",
|
||||
"changeBackground": "Změnit barvu pozadí",
|
||||
"fill": "Výplň",
|
||||
"strokeWidth": "Tloušťka tahu",
|
||||
"strokeStyle": "Styl tahu",
|
||||
@@ -40,20 +38,12 @@
|
||||
"arrowhead_none": "Žádný",
|
||||
"arrowhead_arrow": "Šipka",
|
||||
"arrowhead_bar": "Kóta",
|
||||
"arrowhead_circle": "Kruh",
|
||||
"arrowhead_circle_outline": "Kružnice",
|
||||
"arrowhead_circle": "",
|
||||
"arrowhead_circle_outline": "",
|
||||
"arrowhead_triangle": "Trojúhelník",
|
||||
"arrowhead_triangle_outline": "Trojúhelník (obrys)",
|
||||
"arrowhead_diamond": "Kosočtverec",
|
||||
"arrowhead_diamond_outline": "Kosočtverec (obrys)",
|
||||
"arrowhead_crowfoot_many": "",
|
||||
"arrowhead_crowfoot_one": "",
|
||||
"arrowhead_crowfoot_one_or_many": "",
|
||||
"more_options": "",
|
||||
"arrowtypes": "Typ šipky",
|
||||
"arrowtype_sharp": "Ostrá šipka",
|
||||
"arrowtype_round": "Zakřivená šipka",
|
||||
"arrowtype_elbowed": "",
|
||||
"arrowhead_triangle_outline": "",
|
||||
"arrowhead_diamond": "",
|
||||
"arrowhead_diamond_outline": "",
|
||||
"fontSize": "Velikost písma",
|
||||
"fontFamily": "Písmo",
|
||||
"addWatermark": "Přidat \"Vyrobeno s Excalidraw\"",
|
||||
@@ -65,7 +55,7 @@
|
||||
"large": "Velké",
|
||||
"veryLarge": "Velmi velké",
|
||||
"solid": "Plný",
|
||||
"hachure": "Šrafování",
|
||||
"hachure": "Hachure",
|
||||
"zigzag": "Klikatě",
|
||||
"crossHatch": "Křížový šrafování",
|
||||
"thin": "Tenký",
|
||||
@@ -82,7 +72,6 @@
|
||||
"canvasColors": "Použito na plátně",
|
||||
"canvasBackground": "Pozadí plátna",
|
||||
"drawingCanvas": "Kreslicí plátno",
|
||||
"clearCanvas": "Vyčistit plátno",
|
||||
"layers": "Vrstvy",
|
||||
"actions": "Akce",
|
||||
"language": "Jazyk",
|
||||
@@ -95,13 +84,12 @@
|
||||
"group": "Sloučit výběr do skupiny",
|
||||
"ungroup": "Zrušit sloučení skupiny",
|
||||
"collaborators": "Spolupracovníci",
|
||||
"toggleGrid": "Přepínač mřížky",
|
||||
"showGrid": "Zobrazit mřížku",
|
||||
"addToLibrary": "Přidat do knihovny",
|
||||
"removeFromLibrary": "Odebrat z knihovny",
|
||||
"libraryLoadingMessage": "Načítání knihovny…",
|
||||
"libraries": "Procházet knihovny",
|
||||
"loadingScene": "Načítání scény…",
|
||||
"loadScene": "Načíst scénu ze souboru",
|
||||
"align": "Zarovnání",
|
||||
"alignTop": "Zarovnat nahoru",
|
||||
"alignBottom": "Zarovnat dolů",
|
||||
@@ -117,9 +105,7 @@
|
||||
"share": "Sdílet",
|
||||
"showStroke": "Zobrazit výběr barvy",
|
||||
"showBackground": "Zobrazit výběr barev pozadí",
|
||||
"showFonts": "Zobrazit výběr písma",
|
||||
"toggleTheme": "Přepnout světlý/tmavý motiv",
|
||||
"theme": "Motiv",
|
||||
"toggleTheme": "Přepnout tmavý řežim",
|
||||
"personalLib": "Osobní knihovna",
|
||||
"excalidrawLib": "Exkalidraw knihovna",
|
||||
"decreaseFontSize": "Zmenšit písmo",
|
||||
@@ -129,21 +115,16 @@
|
||||
"createContainerFromText": "Zabalit text do kontejneru",
|
||||
"link": {
|
||||
"edit": "Upravit odkaz",
|
||||
"editEmbed": "Upravit odkaz pro vložení",
|
||||
"create": "Přidat odkaz",
|
||||
"editEmbed": "",
|
||||
"create": "Vytvořit odkaz",
|
||||
"createEmbed": "",
|
||||
"label": "Odkaz",
|
||||
"labelEmbed": "Odkaz & vložit",
|
||||
"empty": "Není nastaven žádný odkaz",
|
||||
"hint": "Napište nebo vložte svůj odkaz zde",
|
||||
"goToElement": "Přejít na cílový prvek"
|
||||
"labelEmbed": "",
|
||||
"empty": ""
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "Upravit čáru",
|
||||
"editArrow": "Upravit šipku"
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"exit": "Ukončit editor řádků"
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "Uzamknout",
|
||||
@@ -153,50 +134,16 @@
|
||||
},
|
||||
"statusPublished": "Zveřejněno",
|
||||
"sidebarLock": "Ponechat postranní panel otevřený",
|
||||
"selectAllElementsInFrame": "Vybrat všechny prvky v orámování",
|
||||
"removeAllElementsFromFrame": "Odstranit všechny prvky z orámování",
|
||||
"selectAllElementsInFrame": "",
|
||||
"removeAllElementsFromFrame": "",
|
||||
"eyeDropper": "Vyberte barvu z plátna",
|
||||
"textToDiagram": "Z textu na diagram",
|
||||
"prompt": "Výzva",
|
||||
"followUs": "Sledujte nás",
|
||||
"discordChat": "Discord chat",
|
||||
"zoomToFitViewport": "",
|
||||
"zoomToFitSelection": "Přiblížit na výběr",
|
||||
"zoomToFit": "Přiblížit na zobrazení všech prvků",
|
||||
"installPWA": "Instalovat Excalidraw lokálně (PWA)",
|
||||
"autoResize": "Povolit automatickou změnu velikosti textu",
|
||||
"imageCropping": "",
|
||||
"unCroppedDimension": "",
|
||||
"copyElementLink": "Kopírovat odkaz na objekt",
|
||||
"linkToElement": "Odkaz na objekt",
|
||||
"wrapSelectionInFrame": "",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "Odkaz na objekt",
|
||||
"desc": "Klikněte na tvar na plátně nebo vložte odkaz.",
|
||||
"notFound": "Propojený objekt nebyl na plátně nalezen."
|
||||
"textToDiagram": "",
|
||||
"prompt": ""
|
||||
},
|
||||
"library": {
|
||||
"noItems": "Dosud neexistují žádné položky...",
|
||||
"hint_emptyLibrary": "Vyberte položku na plátně a přidejte ji sem nebo nainstalujte knihovnu z veřejného úložiště níže.",
|
||||
"hint_emptyPrivateLibrary": "Vyberte položku na plátně a přidejte ji sem.",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "Najít na plátně",
|
||||
"noMatch": "Nebyla nalezena žádná shoda...",
|
||||
"singleResult": "výsledek",
|
||||
"multipleResults": "výsledky",
|
||||
"placeholder": "",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"hint_emptyPrivateLibrary": "Vyberte položku na plátně a přidejte ji sem."
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "Resetovat plátno",
|
||||
@@ -204,7 +151,6 @@
|
||||
"exportImage": "Exportovat obrázek...",
|
||||
"export": "Uložit jako...",
|
||||
"copyToClipboard": "Kopírovat do schránky",
|
||||
"copyLink": "Kopírovat odkaz",
|
||||
"save": "Uložit do aktuálního souboru",
|
||||
"saveAs": "Uložit jako",
|
||||
"load": "Otevřít",
|
||||
@@ -215,7 +161,7 @@
|
||||
"zoomIn": "Přiblížit",
|
||||
"zoomOut": "Oddálit",
|
||||
"resetZoom": "Resetovat přiblížení",
|
||||
"menu": "Hlavní nabídka",
|
||||
"menu": "Menu",
|
||||
"done": "Hotovo",
|
||||
"edit": "Upravit",
|
||||
"undo": "Zpět",
|
||||
@@ -225,19 +171,17 @@
|
||||
"fullScreen": "Celá obrazovka",
|
||||
"darkMode": "Tmavý režim",
|
||||
"lightMode": "Světlý režim",
|
||||
"systemMode": "Nastavení systému",
|
||||
"zenMode": "Zen mód",
|
||||
"objectsSnapMode": "Přichytávat k objektům",
|
||||
"objectsSnapMode": "",
|
||||
"exitZenMode": "Opustit zen mód",
|
||||
"cancel": "Zrušit",
|
||||
"saveLibNames": "",
|
||||
"clear": "Vyčistit",
|
||||
"remove": "Odstranit",
|
||||
"embed": "Přepínač vkládání",
|
||||
"publishLibrary": "",
|
||||
"embed": "",
|
||||
"publishLibrary": "Zveřejnit",
|
||||
"submit": "Odeslat",
|
||||
"confirm": "Potvrdit",
|
||||
"embeddableInteractionButton": "Klikněte pro interakci"
|
||||
"embeddableInteractionButton": ""
|
||||
},
|
||||
"alerts": {
|
||||
"clearReset": "Toto vymaže celé plátno. Jste si jisti?",
|
||||
@@ -260,21 +204,20 @@
|
||||
"resetLibrary": "Tímto vymažete vaši knihovnu. Jste si jisti?",
|
||||
"removeItemsFromsLibrary": "Smazat {{count}} položek z knihovny?",
|
||||
"invalidEncryptionKey": "Šifrovací klíč musí mít 22 znaků. Live spolupráce je zakázána.",
|
||||
"collabOfflineWarning": "Není k dispozici žádné internetové připojení.\nVaše změny nebudou uloženy!",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"collabOfflineWarning": "Není k dispozici žádné internetové připojení.\nVaše změny nebudou uloženy!"
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "Nepodporovaný typ souboru.",
|
||||
"imageInsertError": "Nelze vložit obrázek. Zkuste to později...",
|
||||
"fileTooBig": "Soubor je příliš velký. Maximální povolená velikost je {{maxSize}}.",
|
||||
"svgImageInsertError": "Nelze vložit SVG obrázek. Značení SVG je neplatné.",
|
||||
"failedToFetchImage": "Nepodařilo se načíst obrázek.",
|
||||
"failedToFetchImage": "",
|
||||
"invalidSVGString": "Neplatný SVG.",
|
||||
"cannotResolveCollabServer": "Nelze se připojit ke sdílenému serveru. Prosím obnovte stránku a zkuste to znovu.",
|
||||
"importLibraryError": "Nelze načíst knihovnu",
|
||||
"saveLibraryError": "",
|
||||
"collabSaveFailed": "Nelze uložit do databáze na serveru. Pokud problémy přetrvávají, měli byste uložit soubor lokálně, abyste se ujistili, že neztratíte svou práci.",
|
||||
"collabSaveFailed_sizeExceeded": "Nelze uložit do databáze na serveru, plátno se zdá být příliš velké. Měli byste uložit soubor lokálně, abyste se ujistili, že neztratíte svou práci.",
|
||||
"imageToolNotSupported": "Obrázky jsou vypnuty.",
|
||||
"imageToolNotSupported": "",
|
||||
"brave_measure_text_error": {
|
||||
"line1": "Vypadá to, že používáte Brave prohlížeč s povoleným nastavením <bold>Aggressively Block Fingerprinting</bold>.",
|
||||
"line2": "To by mohlo vést k narušení <bold>Textových elementů</bold> ve vašich výkresech.",
|
||||
@@ -287,12 +230,11 @@
|
||||
"image": ""
|
||||
},
|
||||
"asyncPasteFailedOnRead": "",
|
||||
"asyncPasteFailedOnParse": "Nepodařilo se vložit.",
|
||||
"asyncPasteFailedOnParse": "",
|
||||
"copyToSystemClipboardFailed": ""
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "Výběr",
|
||||
"lasso": "",
|
||||
"image": "Vložit obrázek",
|
||||
"rectangle": "Obdélník",
|
||||
"diamond": "Diamant",
|
||||
@@ -304,32 +246,16 @@
|
||||
"library": "Knihovna",
|
||||
"lock": "Po kreslení ponechat vybraný nástroj aktivní",
|
||||
"penMode": "Režim Pera - zabránit dotyku",
|
||||
"link": "",
|
||||
"link": "Přidat/aktualizovat odkaz pro vybraný tvar",
|
||||
"eraser": "Guma",
|
||||
"frame": "Orámování",
|
||||
"magicframe": "Z wireframu na kód",
|
||||
"embeddable": "Web Embed",
|
||||
"laser": "Laserové ukazovátko",
|
||||
"hand": "Ruka (nástroj pro posouvání)",
|
||||
"extraTools": "Více nástrojů",
|
||||
"mermaidToExcalidraw": "",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "Obdélník",
|
||||
"diamond": "Kosočtverec",
|
||||
"ellipse": "Elipsa",
|
||||
"arrow": "Šipka",
|
||||
"line": "Čára",
|
||||
"freedraw": "Volné kreslení",
|
||||
"text": "Text",
|
||||
"image": "Obrázek",
|
||||
"group": "Skupina",
|
||||
"frame": "Rám",
|
||||
"magicframe": "Z wireframu na kód",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"selection": "Výběr",
|
||||
"iframe": "IFrame"
|
||||
"laser": "",
|
||||
"hand": "Ruka (nástroj pro posouvání)",
|
||||
"extraTools": "",
|
||||
"mermaidToExcalidraw": "",
|
||||
"magicSettings": ""
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "Akce plátna",
|
||||
@@ -337,33 +263,28 @@
|
||||
"shapes": "Tvary"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"canvasPanning": "Chcete-li přesunout plátno, podržte kolečko nebo mezerník při tažení nebo použijte nástroj Ruka",
|
||||
"linearElement": "Kliknutím pro více bodů, táhnutím pro jednu čáru",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "Klikněte a táhněte, pro ukončení pusťte",
|
||||
"text": "Tip: Text můžete také přidat dvojitým kliknutím kdekoli pomocí nástroje pro výběr",
|
||||
"embeddable": "",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"text_selected": "Dvojklikem nebo stisknutím klávesy ENTER upravíte text",
|
||||
"text_editing": "Stiskněte Escape nebo Ctrl/Cmd+ENTER pro dokončení úprav",
|
||||
"linearElementMulti": "Klikněte na poslední bod nebo stiskněte Escape anebo Enter pro dokončení",
|
||||
"lockAngle": "Úhel můžete omezit podržením SHIFT",
|
||||
"resize": "Můžete omezit proporce podržením SHIFT při změně velikosti,\npodržte ALT pro změnu velikosti od středu",
|
||||
"resizeImage": "Můžete volně změnit velikost podržením SHIFT,\npodržením klávesy ALT změníte velikosti od středu",
|
||||
"rotate": "Úhly můžete omezit podržením SHIFT při otáčení",
|
||||
"lineEditor_info": "Podržte Ctrl/Cmd a dvakrát klikněte nebo stiskněte Ctrl/Cmd + Enter pro úpravu bodů",
|
||||
"lineEditor_pointSelected": "Stisknutím tlačítka Delete odstraňte bod(y),\nCtrl/Cmd+D pro duplicitu nebo táhnutím pro přesun",
|
||||
"lineEditor_nothingSelected": "Vyberte bod, který chcete upravit (podržením klávesy SHIFT vyberete více položek),\nnebo podržením klávesy Alt a kliknutím přidáte nové body",
|
||||
"placeImage": "Kliknutím umístěte obrázek, nebo klepnutím a přetažením ručně nastavíte jeho velikost",
|
||||
"publishLibrary": "Publikovat vlastní knihovnu",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"bindTextToElement": "Stiskněte Enter pro přidání textu",
|
||||
"deepBoxSelect": "Podržte Ctrl/Cmd pro hluboký výběr a pro zabránění táhnutí",
|
||||
"eraserRevert": "Podržením klávesy Alt vrátíte prvky označené pro smazání",
|
||||
"firefox_clipboard_write": "Tato funkce může být povolena nastavením vlajky \"dom.events.asyncClipboard.clipboardItem\" na \"true\". Chcete-li změnit vlajky prohlížeče ve Firefoxu, navštivte stránku \"about:config\".",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": ""
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "Náhled nelze zobrazit",
|
||||
@@ -378,12 +299,9 @@
|
||||
"openIssueMessage": "Byli jsme velmi opatrní, abychom neuváděli informace o Vaší scéně. Pokud vaše scéna není soukromá, zvažte prosím sledování na našem <button>bug trackeru</button>. Uveďte prosím níže uvedené informace kopírováním a vložením do problému na GitHubu.",
|
||||
"sceneContent": "Obsah scény:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": ""
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "",
|
||||
"desc_privacy": "",
|
||||
"desc_intro": "Můžete pozvat lidi na vaši aktuální scénu ke spolupráci s vámi.",
|
||||
"desc_privacy": "Nebojte se, relace používá end-to-end šifrování, takže cokoliv nakreslíte zůstane soukromé. Ani náš server nebude schopen vidět, s čím budete pracovat.",
|
||||
"button_startSession": "Zahájit relaci",
|
||||
"button_stopSession": "Ukončit relaci",
|
||||
"desc_inProgressIntro": "Živá spolupráce právě probíhá.",
|
||||
@@ -410,14 +328,12 @@
|
||||
"click": "kliknutí",
|
||||
"deepSelect": "Hluboký výběr",
|
||||
"deepBoxSelect": "Hluboký výběr uvnitř boxu a zabránění táhnnutí",
|
||||
"createFlowchart": "",
|
||||
"navigateFlowchart": "",
|
||||
"curvedArrow": "Zakřivená šipka",
|
||||
"curvedLine": "Zakřivená čára",
|
||||
"documentation": "Dokumentace",
|
||||
"doubleClick": "dvojklik",
|
||||
"drag": "tažení",
|
||||
"editor": "",
|
||||
"editor": "Editor",
|
||||
"editLineArrowPoints": "Upravit body linií/šipek",
|
||||
"editText": "Upravit text / přidat popis",
|
||||
"github": "Našel jsi problém? Nahlaš ho",
|
||||
@@ -434,9 +350,7 @@
|
||||
"zoomToSelection": "Přiblížit na výběr",
|
||||
"toggleElementLock": "Zamknout/odemknout výběr",
|
||||
"movePageUpDown": "Posunout stránku nahoru/dolů",
|
||||
"movePageLeftRight": "Přesunout stránku doleva/doprava",
|
||||
"cropStart": "",
|
||||
"cropFinish": ""
|
||||
"movePageLeftRight": "Přesunout stránku doleva/doprava"
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": "Vymazat plátno"
|
||||
@@ -507,15 +421,13 @@
|
||||
},
|
||||
"stats": {
|
||||
"angle": "Úhel",
|
||||
"shapes": "Tvary",
|
||||
"element": "Prvek",
|
||||
"elements": "Prvky",
|
||||
"height": "Výška",
|
||||
"scene": "Scéna",
|
||||
"selected": "Vybráno",
|
||||
"storage": "Úložiště",
|
||||
"fullTitle": "Vlastnosti plátna a tvarů",
|
||||
"title": "Vlastnosti",
|
||||
"generalStats": "Obecné",
|
||||
"elementProperties": "Vlastnosti tvaru",
|
||||
"title": "Statistika pro nerdy",
|
||||
"total": "Celkem",
|
||||
"version": "Verze",
|
||||
"versionCopy": "Kliknutím zkopírujete",
|
||||
@@ -527,15 +439,13 @@
|
||||
"copyStyles": "Styly byly zkopírovány.",
|
||||
"copyToClipboard": "Zkopírováno do schránky.",
|
||||
"copyToClipboardAsPng": "{{exportSelection}} zkopírován do schránky jako PNG\n({{exportColorScheme}})",
|
||||
"copyToClipboardAsSvg": "",
|
||||
"fileSaved": "Soubor byl uložen.",
|
||||
"fileSavedToFilename": "Uloženo do {filename}",
|
||||
"canvas": "plátno",
|
||||
"selection": "výběr",
|
||||
"pasteAsSingleElement": "Pomocí {{shortcut}} vložte jako jeden prvek,\nnebo vložte do existujícího textového editoru",
|
||||
"unableToEmbed": "",
|
||||
"unrecognizedLinkFormat": "",
|
||||
"elementLinkCopied": ""
|
||||
"unrecognizedLinkFormat": ""
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "Průhledná",
|
||||
@@ -568,7 +478,6 @@
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "Nejpoužívanější vlastní barvy",
|
||||
"colors": "Barvy",
|
||||
"shades": "Stíny",
|
||||
@@ -595,70 +504,22 @@
|
||||
},
|
||||
"modal": {
|
||||
"loadFromFile": {
|
||||
"title": "Načíst ze souboru",
|
||||
"button": "Načíst ze souboru",
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
},
|
||||
"shareableLink": {
|
||||
"title": "Načíst z odkazu",
|
||||
"button": "Nahradit můj obsah",
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"mermaid": {
|
||||
"title": "",
|
||||
"button": "Vložit",
|
||||
"button": "",
|
||||
"description": "",
|
||||
"syntax": "Mermaid syntaxe",
|
||||
"preview": "Náhled"
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": "Rychlé vyhledávání"
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": "staré"
|
||||
},
|
||||
"sceneFonts": "V této scéně",
|
||||
"availableFonts": "Dostupná písma",
|
||||
"empty": "Nebyla nalezena žádná písma"
|
||||
},
|
||||
"userList": {
|
||||
"empty": "Nebyli nalezeni žádní uživatelé",
|
||||
"hint": {
|
||||
"text": "Klikněte na uživatele pro sledování",
|
||||
"followStatus": "Právě sledujete tohoto uživatele",
|
||||
"inCall": "Uživatel je v hovoru",
|
||||
"micMuted": "Mikrofon uživatele je ztlumen",
|
||||
"isSpeaking": "Uživatel hovoří"
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "Paleta příkazů",
|
||||
"shortcuts": {
|
||||
"select": "Vybrat",
|
||||
"confirm": "Potvrdit",
|
||||
"close": "Zavřít"
|
||||
},
|
||||
"recents": "Naposledy použito",
|
||||
"search": {
|
||||
"placeholder": "",
|
||||
"noMatch": "Žádné odpovídající příkazy..."
|
||||
},
|
||||
"itemNotAvailable": "Příkaz není k dispozici...",
|
||||
"shortcutHint": ""
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
"syntax": "",
|
||||
"preview": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,9 +21,7 @@
|
||||
"copyStyles": "Kopier stil",
|
||||
"pasteStyles": "Indsæt stil",
|
||||
"stroke": "Linje",
|
||||
"changeStroke": "Ændr stregfarve",
|
||||
"background": "Baggrund",
|
||||
"changeBackground": "Ændr baggrundsfarve",
|
||||
"fill": "Udfyld",
|
||||
"strokeWidth": "Linjebredde",
|
||||
"strokeStyle": "Linjeform",
|
||||
@@ -40,20 +38,12 @@
|
||||
"arrowhead_none": "Ingen",
|
||||
"arrowhead_arrow": "Pil",
|
||||
"arrowhead_bar": "Bjælke",
|
||||
"arrowhead_circle": "Cirkel",
|
||||
"arrowhead_circle_outline": "Cirkel (omrids)",
|
||||
"arrowhead_circle": "",
|
||||
"arrowhead_circle_outline": "",
|
||||
"arrowhead_triangle": "Trekant",
|
||||
"arrowhead_triangle_outline": "Trekant (omrids)",
|
||||
"arrowhead_diamond": "Diamant",
|
||||
"arrowhead_diamond_outline": "Diamant (omrids)",
|
||||
"arrowhead_crowfoot_many": "Kragefod (mange)",
|
||||
"arrowhead_crowfoot_one": "Kragefod (én)",
|
||||
"arrowhead_crowfoot_one_or_many": "Kragefod (én eller mange)",
|
||||
"more_options": "Flere muligheder",
|
||||
"arrowtypes": "Pile type",
|
||||
"arrowtype_sharp": "Skarp pil",
|
||||
"arrowtype_round": "Buet pil",
|
||||
"arrowtype_elbowed": "Albuepil",
|
||||
"arrowhead_triangle_outline": "",
|
||||
"arrowhead_diamond": "",
|
||||
"arrowhead_diamond_outline": "",
|
||||
"fontSize": "Skriftstørrelse",
|
||||
"fontFamily": "Skrifttypefamilie",
|
||||
"addWatermark": "Tilføj \"Lavet med Excalidraw\"",
|
||||
@@ -82,7 +72,6 @@
|
||||
"canvasColors": "Brugt på lærred",
|
||||
"canvasBackground": "Lærredsbaggrund",
|
||||
"drawingCanvas": "Tegnelærred",
|
||||
"clearCanvas": "Ryd lærred",
|
||||
"layers": "Lag",
|
||||
"actions": "Handlinger",
|
||||
"language": "Sprog",
|
||||
@@ -92,122 +81,79 @@
|
||||
"name": "Navn",
|
||||
"yourName": "Dit navn",
|
||||
"madeWithExcalidraw": "Fremstillet med Excalidraw",
|
||||
"group": "Gruppér valgte",
|
||||
"ungroup": "Afgruppér valgte",
|
||||
"collaborators": "Samarbejdspartnere",
|
||||
"toggleGrid": "Slå gitter til/fra",
|
||||
"addToLibrary": "Føj til bibliotek",
|
||||
"group": "Grupper valgte",
|
||||
"ungroup": "Opløs gruppe",
|
||||
"collaborators": "Deltagere",
|
||||
"showGrid": "Vis gitter",
|
||||
"addToLibrary": "Føj til Bibliotek",
|
||||
"removeFromLibrary": "Fjern fra biblioteket",
|
||||
"libraryLoadingMessage": "Indlæser bibliotek…",
|
||||
"libraries": "Gennemse biblioteker",
|
||||
"loadingScene": "Indlæser scene…",
|
||||
"loadScene": "Indlæs scene fra fil",
|
||||
"align": "Justér",
|
||||
"alignTop": "Juster til top",
|
||||
"alignBottom": "Juster til bund",
|
||||
"alignLeft": "Venstrejusteret",
|
||||
"alignRight": "Højrejustér",
|
||||
"centerVertically": "Centrér vertikalt",
|
||||
"centerHorizontally": "Centrér horisontalt",
|
||||
"alignRight": "Juster højre",
|
||||
"centerVertically": "Center vertikalt",
|
||||
"centerHorizontally": "Vandret centreret",
|
||||
"distributeHorizontally": "Distribuer vandret",
|
||||
"distributeVertically": "Distribuer lodret",
|
||||
"flipHorizontal": "Vend horisontalt",
|
||||
"flipVertical": "Vend vertikalt",
|
||||
"flipHorizontal": "Spejlvend horisontalt",
|
||||
"flipVertical": "Vend lodret",
|
||||
"viewMode": "Visningstilstand",
|
||||
"share": "Del",
|
||||
"showStroke": "Vis stregfarve-vælger",
|
||||
"showBackground": "Vis baggrundsfarve-vælger",
|
||||
"showFonts": "Vis skrifttypevælger",
|
||||
"toggleTheme": "Slå lys/mørkt tema til/fra",
|
||||
"theme": "Tema",
|
||||
"toggleTheme": "Skift tema",
|
||||
"personalLib": "Personligt bibliotek",
|
||||
"excalidrawLib": "",
|
||||
"decreaseFontSize": "",
|
||||
"increaseFontSize": "",
|
||||
"unbindText": "",
|
||||
"bindText": "",
|
||||
"createContainerFromText": "",
|
||||
"excalidrawLib": "Excalidraw Bibliotek",
|
||||
"decreaseFontSize": "Gør skriften mindre",
|
||||
"increaseFontSize": "Gør skriften større",
|
||||
"unbindText": "Frigør tekst",
|
||||
"bindText": "Bind tekst til beholderen",
|
||||
"createContainerFromText": "Ombryd tekst i en beholder",
|
||||
"link": {
|
||||
"edit": "",
|
||||
"editEmbed": "",
|
||||
"create": "",
|
||||
"label": "",
|
||||
"labelEmbed": "",
|
||||
"empty": "",
|
||||
"hint": "",
|
||||
"goToElement": ""
|
||||
"edit": "Redigér link",
|
||||
"editEmbed": "Redigér link & indlejret",
|
||||
"create": "Link oprettet",
|
||||
"createEmbed": "Opret link & indlejret",
|
||||
"label": "Links",
|
||||
"labelEmbed": "Link & indlejret",
|
||||
"empty": "Intet link angivet"
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "",
|
||||
"editArrow": ""
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"edit": "Rediger Linje",
|
||||
"exit": "Afslut linjeeditor"
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "",
|
||||
"unlock": "",
|
||||
"lockAll": "",
|
||||
"unlockAll": ""
|
||||
"lock": "Lås",
|
||||
"unlock": "Lås op",
|
||||
"lockAll": "Lås alle",
|
||||
"unlockAll": "Lås alle op"
|
||||
},
|
||||
"statusPublished": "",
|
||||
"sidebarLock": "",
|
||||
"selectAllElementsInFrame": "",
|
||||
"removeAllElementsFromFrame": "",
|
||||
"eyeDropper": "",
|
||||
"textToDiagram": "",
|
||||
"prompt": "",
|
||||
"followUs": "",
|
||||
"discordChat": "",
|
||||
"zoomToFitViewport": "",
|
||||
"zoomToFitSelection": "",
|
||||
"zoomToFit": "",
|
||||
"installPWA": "",
|
||||
"autoResize": "",
|
||||
"imageCropping": "",
|
||||
"unCroppedDimension": "",
|
||||
"copyElementLink": "",
|
||||
"linkToElement": "",
|
||||
"wrapSelectionInFrame": "",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "",
|
||||
"desc": "",
|
||||
"notFound": ""
|
||||
"statusPublished": "Udgiver",
|
||||
"sidebarLock": "Hold sidepanel åben",
|
||||
"selectAllElementsInFrame": "Vælg alle elementer i rammen",
|
||||
"removeAllElementsFromFrame": "Fjern alle elementer fra ramme",
|
||||
"eyeDropper": "Vælg farve fra lærred",
|
||||
"textToDiagram": "Tekst til diagram",
|
||||
"prompt": "Prompt"
|
||||
},
|
||||
"library": {
|
||||
"noItems": "",
|
||||
"hint_emptyLibrary": "",
|
||||
"hint_emptyPrivateLibrary": "",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "",
|
||||
"noMatch": "",
|
||||
"singleResult": "",
|
||||
"multipleResults": "",
|
||||
"placeholder": "",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"noItems": "Ingen varer tilføjet endnu...",
|
||||
"hint_emptyLibrary": "Vælg et element på lærred for at tilføje det her, eller installer et bibliotek fra det offentlige arkiv, nedenfor.",
|
||||
"hint_emptyPrivateLibrary": "Vælg et element på lærred for at tilføje det her."
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "",
|
||||
"exportJSON": "",
|
||||
"exportImage": "",
|
||||
"export": "",
|
||||
"clearReset": "Nulstil lærredet",
|
||||
"exportJSON": "Eksportér til fil",
|
||||
"exportImage": "Eksporter billede...",
|
||||
"export": "Gem til...",
|
||||
"copyToClipboard": "Kopier til klippebord",
|
||||
"copyLink": "",
|
||||
"save": "",
|
||||
"save": "Gem til nuværende fil",
|
||||
"saveAs": "Gem som",
|
||||
"load": "",
|
||||
"load": "Åbn",
|
||||
"getShareableLink": "Lav et delbart link",
|
||||
"close": "Luk",
|
||||
"selectLanguage": "Vælg sprog",
|
||||
@@ -215,7 +161,7 @@
|
||||
"zoomIn": "Zoom ind",
|
||||
"zoomOut": "Zoom ud",
|
||||
"resetZoom": "Nulstil zoom",
|
||||
"menu": "",
|
||||
"menu": "Menu",
|
||||
"done": "Færdig",
|
||||
"edit": "Rediger",
|
||||
"undo": "Fortryd",
|
||||
@@ -225,19 +171,17 @@
|
||||
"fullScreen": "Fuld skærm",
|
||||
"darkMode": "Mørk tilstand",
|
||||
"lightMode": "Lys baggrund",
|
||||
"systemMode": "",
|
||||
"zenMode": "Zentilstand",
|
||||
"objectsSnapMode": "",
|
||||
"objectsSnapMode": "Fastgør til objekter",
|
||||
"exitZenMode": "Stop zentilstand",
|
||||
"cancel": "Annuller",
|
||||
"saveLibNames": "",
|
||||
"clear": "Ryd",
|
||||
"remove": "Fjern",
|
||||
"embed": "",
|
||||
"publishLibrary": "",
|
||||
"embed": "Slå indlejring til/fra",
|
||||
"publishLibrary": "Publicér",
|
||||
"submit": "Gem",
|
||||
"confirm": "Bekræft",
|
||||
"embeddableInteractionButton": ""
|
||||
"embeddableInteractionButton": "Klik for at interagere"
|
||||
},
|
||||
"alerts": {
|
||||
"clearReset": "Dette vil rydde hele lærredet. Er du sikker?",
|
||||
@@ -245,105 +189,85 @@
|
||||
"couldNotCreateShareableLinkTooBig": "Kunne ikke oprette delbart link: scenen er for stor",
|
||||
"couldNotLoadInvalidFile": "Kunne ikke indlæse ugyldig fil",
|
||||
"importBackendFailed": "Import fra backend mislykkedes.",
|
||||
"cannotExportEmptyCanvas": "",
|
||||
"couldNotCopyToClipboard": "",
|
||||
"decryptFailed": "",
|
||||
"uploadedSecurly": "",
|
||||
"loadSceneOverridePrompt": "",
|
||||
"collabStopOverridePrompt": "",
|
||||
"errorAddingToLibrary": "",
|
||||
"errorRemovingFromLibrary": "",
|
||||
"confirmAddLibrary": "",
|
||||
"imageDoesNotContainScene": "",
|
||||
"cannotRestoreFromImage": "",
|
||||
"invalidSceneUrl": "",
|
||||
"resetLibrary": "",
|
||||
"removeItemsFromsLibrary": "",
|
||||
"invalidEncryptionKey": "",
|
||||
"collabOfflineWarning": "",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"cannotExportEmptyCanvas": "Kan ikke eksportere tomt lærred.",
|
||||
"couldNotCopyToClipboard": "Kunne ikke kopiere til udklipsholderen.",
|
||||
"decryptFailed": "Kunne ikke dekryptere data.",
|
||||
"uploadedSecurly": "Upload er blevet sikret med ende-til-ende kryptering, hvilket betyder, at Excalidraw server og tredjeparter ikke kan læse indholdet.",
|
||||
"loadSceneOverridePrompt": "Indlæsning af ekstern tegning erstatter dit eksisterende indhold. Ønsker du at fortsætte?",
|
||||
"collabStopOverridePrompt": "Stopper sessionen vil overskrive din tidligere, lokalt gemte tegning. Er du sikker?\n\n(Hvis du ønsker at beholde din lokale tegning, skal du blot lukke browserfanen i stedet.)",
|
||||
"errorAddingToLibrary": "Kunne ikke tilføje element til biblioteket",
|
||||
"errorRemovingFromLibrary": "Kunne ikke fjerne element fra biblioteket",
|
||||
"confirmAddLibrary": "Dette vil tilføje {{numShapes}} form(er) til dit bibliotek. Er du sikker?",
|
||||
"imageDoesNotContainScene": "Dette billede synes ikke at indeholde scene data. Har du aktiveret scene indlejring under eksport?",
|
||||
"cannotRestoreFromImage": "Scene kunne ikke gendannes fra denne billedfil",
|
||||
"invalidSceneUrl": "Kunne ikke importere scene fra den angivne URL. Det er enten misdannet eller indeholder ikke gyldige Excalidraw JSON data.",
|
||||
"resetLibrary": "Dette vil rydde hele lærredet. Er du sikker?",
|
||||
"removeItemsFromsLibrary": "Slet {{count}} vare(r) fra biblioteket?",
|
||||
"invalidEncryptionKey": "Krypteringsnøglen skal være på 22 tegn. Live-samarbejde er deaktiveret.",
|
||||
"collabOfflineWarning": "Ingen internetforbindelse tilgængelig.\nDine ændringer vil ikke blive gemt!"
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "",
|
||||
"imageInsertError": "",
|
||||
"fileTooBig": "",
|
||||
"svgImageInsertError": "",
|
||||
"failedToFetchImage": "",
|
||||
"cannotResolveCollabServer": "",
|
||||
"importLibraryError": "",
|
||||
"saveLibraryError": "",
|
||||
"collabSaveFailed": "",
|
||||
"collabSaveFailed_sizeExceeded": "",
|
||||
"imageToolNotSupported": "",
|
||||
"unsupportedFileType": "Filtypen er ikke understøttet.",
|
||||
"imageInsertError": "Billedet kunne ikke indsættes. Prøv igen senere...",
|
||||
"fileTooBig": "Filen er for stor. Maksimal tilladt størrelse er {{maxSize}}.",
|
||||
"svgImageInsertError": "Kunne ikke indsætte SVG-billede. SVG-markup'en ser ugyldig ud.",
|
||||
"failedToFetchImage": "Dataene blev ikke hentet.",
|
||||
"invalidSVGString": "Ugyldig SVG.",
|
||||
"cannotResolveCollabServer": "Kunne ikke oprette forbindelse til samarbejdsserveren. Genindlæs siden og prøv igen.",
|
||||
"importLibraryError": "Biblioteket kunne ikke indlæses",
|
||||
"collabSaveFailed": "Kunne ikke gemme i databasen. Hvis problemerne fortsætter, bør du gemme din fil lokalt for at sikre, at du ikke mister dit arbejde.",
|
||||
"collabSaveFailed_sizeExceeded": "Kunne ikke gemme i databasen, lærredet lader til at være for stort. Du bør gemme filen lokalt for at sikre, at du ikke mister dit arbejde.",
|
||||
"imageToolNotSupported": "Billeder er deaktiveret.",
|
||||
"brave_measure_text_error": {
|
||||
"line1": "",
|
||||
"line2": "",
|
||||
"line3": "",
|
||||
"line4": ""
|
||||
"line1": "Det ser ud til, at du bruger Brave browser med indstillingen <bold>Aggressively Block Fingerprinting</bold> aktiveret.",
|
||||
"line2": "Dette kan resultere i brud på <bold>tekstelementerne</bold> i dine tegninger.",
|
||||
"line3": "Vi anbefaler kraftigt at deaktivere denne indstilling. Du kan følge <link>disse trin</link> om, hvordan du gør det.",
|
||||
"line4": "Hvis deaktivering af denne indstilling ikke løser visning af tekstelementer, åbn venligst et <issueLink>issue</issueLink> på vores GitHub, eller skriv os på <discordLink>Discord</discordLink>"
|
||||
},
|
||||
"libraryElementTypeError": {
|
||||
"embeddable": "",
|
||||
"iframe": "",
|
||||
"image": ""
|
||||
"embeddable": "Indlejringselementer kan ikke tilføjes til biblioteket.",
|
||||
"iframe": "IFrame elementer kan ikke tilføjes til biblioteket.",
|
||||
"image": "Understøttelse af at tilføje billeder til biblioteket kommer snart!"
|
||||
},
|
||||
"asyncPasteFailedOnRead": "",
|
||||
"asyncPasteFailedOnParse": "",
|
||||
"copyToSystemClipboardFailed": ""
|
||||
"asyncPasteFailedOnRead": "Kunne ikke indsætte (kan ikke læse fra systemets udklipsholder).",
|
||||
"asyncPasteFailedOnParse": "Kunne ikke indsætte.",
|
||||
"copyToSystemClipboardFailed": "Kunne ikke kopiere til udklipsholderen."
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "",
|
||||
"lasso": "",
|
||||
"image": "",
|
||||
"rectangle": "",
|
||||
"diamond": "",
|
||||
"ellipse": "",
|
||||
"arrow": "",
|
||||
"line": "",
|
||||
"freedraw": "",
|
||||
"text": "",
|
||||
"library": "",
|
||||
"lock": "",
|
||||
"penMode": "",
|
||||
"link": "",
|
||||
"eraser": "",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"laser": "",
|
||||
"hand": "",
|
||||
"extraTools": "",
|
||||
"mermaidToExcalidraw": "",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "",
|
||||
"diamond": "",
|
||||
"ellipse": "",
|
||||
"arrow": "",
|
||||
"line": "",
|
||||
"freedraw": "",
|
||||
"text": "",
|
||||
"image": "",
|
||||
"group": "",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"selection": "",
|
||||
"iframe": ""
|
||||
"selection": "&Udvalg",
|
||||
"image": "Indsæt billeder",
|
||||
"rectangle": "Rektangler",
|
||||
"diamond": "Diamanter",
|
||||
"ellipse": "Ellipser",
|
||||
"arrow": "Pile",
|
||||
"line": "Linje",
|
||||
"freedraw": "Tegn",
|
||||
"text": "Tekster",
|
||||
"library": "~Bibliotek",
|
||||
"lock": "Behold valgte værktøj aktiv efter tegning",
|
||||
"penMode": "Pen-tilstand - forhindrer berøring",
|
||||
"link": "Tilføj/ Opdater link for en valgt form",
|
||||
"eraser": "Slet",
|
||||
"frame": "Rammeværktøj",
|
||||
"magicframe": "Wireframe til kode",
|
||||
"embeddable": "Web-indlejring",
|
||||
"laser": "Lasermarkør",
|
||||
"hand": "Hånd (panorering værktøj)",
|
||||
"extraTools": "Flere værktøjer",
|
||||
"mermaidToExcalidraw": "Mermaid til Excalidraw",
|
||||
"magicSettings": "AI indstillinger"
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "",
|
||||
"selectedShapeActions": "",
|
||||
"shapes": ""
|
||||
"canvasActions": "Lærred handlinger",
|
||||
"selectedShapeActions": "Valgte figurhandlinger",
|
||||
"shapes": "Former"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"linearElement": "",
|
||||
"arrowTool": "",
|
||||
"canvasPanning": "For at flytte lærred, hold musehjulet eller mellemrumstasten mens du trækker, eller brug håndværktøjet",
|
||||
"linearElement": "Klik for at starte flere punkter, træk for enkelt linje",
|
||||
"freeDraw": "Klik og træk, slip når du er færdig",
|
||||
"text": "",
|
||||
"embeddable": "",
|
||||
"text": "Tip: du kan også tilføje tekst ved at dobbeltklikke hvor som helst med det valgte værktøj",
|
||||
"embeddable": "Klik på træk for at oprette en hjemmeside indlejret",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
@@ -352,40 +276,34 @@
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"placeImage": "",
|
||||
"publishLibrary": "",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"firefox_clipboard_write": "",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": ""
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "",
|
||||
"canvasTooBig": "",
|
||||
"canvasTooBigTip": ""
|
||||
"cannotShowPreview": "Kan ikke vise forhåndsvisning",
|
||||
"canvasTooBig": "Lærredet kan være for stort.",
|
||||
"canvasTooBigTip": "Tip: Prøv at flytte de fjerneste elementer lidt tættere sammen."
|
||||
},
|
||||
"errorSplash": {
|
||||
"headingMain": "",
|
||||
"headingMain": "Der opstod en fejl. Prøv <button>at genindlæse siden</button>.",
|
||||
"clearCanvasMessage": "",
|
||||
"clearCanvasCaveat": "",
|
||||
"trackedToSentry": "",
|
||||
"openIssueMessage": "<button></button> Kopiere og indsæt venligst oplysningerne nedenfor i et GitHub problem.",
|
||||
"sceneContent": "Scene indhold:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": ""
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "",
|
||||
"desc_privacy": "",
|
||||
"button_startSession": "",
|
||||
"button_stopSession": "",
|
||||
"desc_intro": "Du kan invitere folk til din nuværende scene, så de kan samarbejde med dig.",
|
||||
"desc_privacy": "Bare rolig, sessionen bruger end-to-end kryptering, så uanset hvad du tegner vil det forblive privat. Ikke engang vores server vil kunne se, hvad du kommer op med.",
|
||||
"button_startSession": "Start session",
|
||||
"button_stopSession": "Stop session",
|
||||
"desc_inProgressIntro": "Live-samarbejde session er nu begyndt.",
|
||||
"desc_shareLink": "Del dette link med enhver, du ønsker at samarbejde med:",
|
||||
"desc_exitSession": "",
|
||||
@@ -410,8 +328,6 @@
|
||||
"click": "",
|
||||
"deepSelect": "",
|
||||
"deepBoxSelect": "",
|
||||
"createFlowchart": "",
|
||||
"navigateFlowchart": "",
|
||||
"curvedArrow": "",
|
||||
"curvedLine": "",
|
||||
"documentation": "",
|
||||
@@ -434,9 +350,7 @@
|
||||
"zoomToSelection": "",
|
||||
"toggleElementLock": "",
|
||||
"movePageUpDown": "",
|
||||
"movePageLeftRight": "",
|
||||
"cropStart": "",
|
||||
"cropFinish": ""
|
||||
"movePageLeftRight": ""
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": ""
|
||||
@@ -507,15 +421,13 @@
|
||||
},
|
||||
"stats": {
|
||||
"angle": "",
|
||||
"shapes": "",
|
||||
"element": "",
|
||||
"elements": "",
|
||||
"height": "",
|
||||
"scene": "",
|
||||
"selected": "",
|
||||
"storage": "",
|
||||
"fullTitle": "",
|
||||
"title": "",
|
||||
"generalStats": "",
|
||||
"elementProperties": "",
|
||||
"title": "Statistik for nørder",
|
||||
"total": "",
|
||||
"version": "",
|
||||
"versionCopy": "Klik for at kopiere",
|
||||
@@ -527,15 +439,13 @@
|
||||
"copyStyles": "Kopieret stilarter.",
|
||||
"copyToClipboard": "Kopieret til klippebord.",
|
||||
"copyToClipboardAsPng": "Kopieret {{exportSelection}} til klippebord som PNG\n({{exportColorScheme}})",
|
||||
"copyToClipboardAsSvg": "",
|
||||
"fileSaved": "Fil gemt.",
|
||||
"fileSavedToFilename": "Gemt som {filename}",
|
||||
"canvas": "",
|
||||
"canvas": "canvas",
|
||||
"selection": "markering",
|
||||
"pasteAsSingleElement": "",
|
||||
"unableToEmbed": "",
|
||||
"unrecognizedLinkFormat": "",
|
||||
"elementLinkCopied": ""
|
||||
"unrecognizedLinkFormat": ""
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "",
|
||||
@@ -568,7 +478,6 @@
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "",
|
||||
"colors": "",
|
||||
"shades": "",
|
||||
@@ -612,53 +521,5 @@
|
||||
"description": "",
|
||||
"syntax": "",
|
||||
"preview": ""
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": ""
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": ""
|
||||
},
|
||||
"sceneFonts": "",
|
||||
"availableFonts": "",
|
||||
"empty": ""
|
||||
},
|
||||
"userList": {
|
||||
"empty": "",
|
||||
"hint": {
|
||||
"text": "",
|
||||
"followStatus": "",
|
||||
"inCall": "",
|
||||
"micMuted": "",
|
||||
"isSpeaking": ""
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "",
|
||||
"shortcuts": {
|
||||
"select": "",
|
||||
"confirm": "",
|
||||
"close": ""
|
||||
},
|
||||
"recents": "",
|
||||
"search": {
|
||||
"placeholder": "",
|
||||
"noMatch": ""
|
||||
},
|
||||
"itemNotAvailable": "",
|
||||
"shortcutHint": ""
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,664 +0,0 @@
|
||||
{
|
||||
"labels": {
|
||||
"paste": "Einfügen",
|
||||
"pasteAsPlaintext": "Als unformatierten Text einfügen",
|
||||
"pasteCharts": "Diagramme einfügen",
|
||||
"selectAll": "Alle auswählen",
|
||||
"multiSelect": "Element zur Auswahl hinzufügen",
|
||||
"moveCanvas": "Leinwand verschieben",
|
||||
"cut": "Ausschneiden",
|
||||
"copy": "Kopieren",
|
||||
"copyAsPng": "In Zwischenablage kopieren (PNG)",
|
||||
"copyAsSvg": "In Zwischenablage kopieren (SVG)",
|
||||
"copyText": "In die Zwischenablage als Text kopieren",
|
||||
"copySource": "Quelle in Zwischenablage kopieren",
|
||||
"convertToCode": "In Code konvertieren",
|
||||
"bringForward": "Nach vorne",
|
||||
"sendToBack": "In den Hintergrund",
|
||||
"bringToFront": "In den Vordergrund",
|
||||
"sendBackward": "Nach hinten",
|
||||
"delete": "Löschen",
|
||||
"copyStyles": "Formatierung kopieren",
|
||||
"pasteStyles": "Formatierung übernehmen",
|
||||
"stroke": "Strich",
|
||||
"changeStroke": "Strichfarbe ändern",
|
||||
"background": "Hintergrund",
|
||||
"changeBackground": "Hintergrundfarbe ändern",
|
||||
"fill": "Füllung",
|
||||
"strokeWidth": "Strichstärke",
|
||||
"strokeStyle": "Konturstil",
|
||||
"strokeStyle_solid": "Durchgezogen",
|
||||
"strokeStyle_dashed": "Gestrichelt",
|
||||
"strokeStyle_dotted": "Gepunktet",
|
||||
"sloppiness": "Sauberkeit",
|
||||
"opacity": "Deckkraft",
|
||||
"textAlign": "Textausrichtung",
|
||||
"edges": "Kanten",
|
||||
"sharp": "Scharf",
|
||||
"round": "Rund",
|
||||
"arrowheads": "Pfeilspitzen",
|
||||
"arrowhead_none": "Keine",
|
||||
"arrowhead_arrow": "Pfeil",
|
||||
"arrowhead_bar": "Balken",
|
||||
"arrowhead_circle": "Kreis",
|
||||
"arrowhead_circle_outline": "Kreis (Umrandung)",
|
||||
"arrowhead_triangle": "Dreieck",
|
||||
"arrowhead_triangle_outline": "Dreieck (Umrandung)",
|
||||
"arrowhead_diamond": "Raute",
|
||||
"arrowhead_diamond_outline": "Raute (Umrandung)",
|
||||
"arrowhead_crowfoot_many": "Krähenfuß (viele)",
|
||||
"arrowhead_crowfoot_one": "Krähenfuß (einer)",
|
||||
"arrowhead_crowfoot_one_or_many": "Krähenfuß (einer oder viele)",
|
||||
"more_options": "Weitere Optionen",
|
||||
"arrowtypes": "Pfeiltyp",
|
||||
"arrowtype_sharp": "Scharfer Pfeil",
|
||||
"arrowtype_round": "Gebogener Pfeil",
|
||||
"arrowtype_elbowed": "Ellenbogen-Pfeil",
|
||||
"fontSize": "Schriftgröße",
|
||||
"fontFamily": "Schriftfamilie",
|
||||
"addWatermark": "\"Made with Excalidraw\" hinzufügen",
|
||||
"handDrawn": "Handgezeichnet",
|
||||
"normal": "Normal",
|
||||
"code": "Code",
|
||||
"small": "Klein",
|
||||
"medium": "Mittel",
|
||||
"large": "Groß",
|
||||
"veryLarge": "Sehr groß",
|
||||
"solid": "Deckend",
|
||||
"hachure": "Schraffiert",
|
||||
"zigzag": "Zickzack",
|
||||
"crossHatch": "Kreuzschraffiert",
|
||||
"thin": "Dünn",
|
||||
"bold": "Fett",
|
||||
"left": "Links",
|
||||
"center": "Zentriert",
|
||||
"right": "Rechts",
|
||||
"extraBold": "Extra Fett",
|
||||
"architect": "Architekt",
|
||||
"artist": "Künstler",
|
||||
"cartoonist": "Karikaturist",
|
||||
"fileTitle": "Dateiname",
|
||||
"colorPicker": "Farbauswähler",
|
||||
"canvasColors": "Auf Leinwand verwendet",
|
||||
"canvasBackground": "Zeichenflächenhintergrund",
|
||||
"drawingCanvas": "Leinwand",
|
||||
"clearCanvas": "Zeichenfläche löschen",
|
||||
"layers": "Ebenen",
|
||||
"actions": "Aktionen",
|
||||
"language": "Sprache",
|
||||
"liveCollaboration": "Live-Zusammenarbeit...",
|
||||
"duplicateSelection": "Duplizieren",
|
||||
"untitled": "Unbenannt",
|
||||
"name": "Name",
|
||||
"yourName": "Dein Name",
|
||||
"madeWithExcalidraw": "Made with Excalidraw",
|
||||
"group": "Auswahl gruppieren",
|
||||
"ungroup": "Gruppierung aufheben",
|
||||
"collaborators": "Mitarbeitende",
|
||||
"toggleGrid": "Raster umschalten",
|
||||
"addToLibrary": "Zur Bibliothek hinzufügen",
|
||||
"removeFromLibrary": "Aus Bibliothek entfernen",
|
||||
"libraryLoadingMessage": "Lade Bibliothek…",
|
||||
"libraries": "Bibliotheken durchsuchen",
|
||||
"loadingScene": "Lade Zeichnung…",
|
||||
"loadScene": "Szene aus Datei laden",
|
||||
"align": "Ausrichten",
|
||||
"alignTop": "Obere Kanten",
|
||||
"alignBottom": "Untere Kanten",
|
||||
"alignLeft": "Linke Kanten",
|
||||
"alignRight": "Rechte Kanten",
|
||||
"centerVertically": "Vertikal zentrieren",
|
||||
"centerHorizontally": "Horizontal zentrieren",
|
||||
"distributeHorizontally": "Horizontal verteilen",
|
||||
"distributeVertically": "Vertikal verteilen",
|
||||
"flipHorizontal": "Horizontal spiegeln",
|
||||
"flipVertical": "Vertikal spiegeln",
|
||||
"viewMode": "Ansichtsmodus",
|
||||
"share": "Teilen",
|
||||
"showStroke": "Auswahl für Strichfarbe anzeigen",
|
||||
"showBackground": "Hintergrundfarbe auswählen",
|
||||
"showFonts": "Schriftauswahl anzeigen",
|
||||
"toggleTheme": "Helles/dunkles Design umschalten",
|
||||
"theme": "Design",
|
||||
"personalLib": "Persönliche Bibliothek",
|
||||
"excalidrawLib": "Excalidraw Bibliothek",
|
||||
"decreaseFontSize": "Schriftgröße verringern",
|
||||
"increaseFontSize": "Schriftgröße erhöhen",
|
||||
"unbindText": "Text lösen",
|
||||
"bindText": "Text an Container binden",
|
||||
"createContainerFromText": "Text in Container einbetten",
|
||||
"link": {
|
||||
"edit": "Link bearbeiten",
|
||||
"editEmbed": "Einbettbaren Link bearbeiten",
|
||||
"create": "Link hinzufügen",
|
||||
"label": "Link",
|
||||
"labelEmbed": "Verlinken & einbetten",
|
||||
"empty": "Kein Link festgelegt",
|
||||
"hint": "Link hier eingeben oder einfügen",
|
||||
"goToElement": "Gehe zu Zielelement"
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "Linie bearbeiten",
|
||||
"editArrow": "Pfeil bearbeiten"
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "Sperren",
|
||||
"unlock": "Entsperren",
|
||||
"lockAll": "Alle sperren",
|
||||
"unlockAll": "Alle entsperren"
|
||||
},
|
||||
"statusPublished": "Veröffentlicht",
|
||||
"sidebarLock": "Seitenleiste offen lassen",
|
||||
"selectAllElementsInFrame": "Alle Elemente im Rahmen auswählen",
|
||||
"removeAllElementsFromFrame": "Alle Elemente aus dem Rahmen entfernen",
|
||||
"eyeDropper": "Farbe von der Zeichenfläche auswählen",
|
||||
"textToDiagram": "Text zu Diagramm",
|
||||
"prompt": "Eingabe",
|
||||
"followUs": "Folge uns",
|
||||
"discordChat": "Discord-Chat",
|
||||
"zoomToFitViewport": "Zoom auf Ansicht anpassen",
|
||||
"zoomToFitSelection": "Zoom auf Auswahl anpassen",
|
||||
"zoomToFit": "Zoom auf alle Elemente anpassen",
|
||||
"installPWA": "Excalidraw lokal installieren (PWA)",
|
||||
"autoResize": "Aktiviere automatische Textgrößenanpassung",
|
||||
"imageCropping": "Bild zuschneiden",
|
||||
"unCroppedDimension": "Nicht zugeschnittene Dimension",
|
||||
"copyElementLink": "Link zum Objekt kopieren",
|
||||
"linkToElement": "Link zum Objekt",
|
||||
"wrapSelectionInFrame": "Auswahl in Rahmen einbetten",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "Link zum Objekt",
|
||||
"desc": "Klicke auf eine Form auf der Zeichenfläche oder füge einen Link ein.",
|
||||
"notFound": "Verknüpftes Objekt wurde nicht auf der Zeichenfläche gefunden."
|
||||
},
|
||||
"library": {
|
||||
"noItems": "Noch keine Elemente hinzugefügt...",
|
||||
"hint_emptyLibrary": "Wähle ein Element auf der Zeichenfläche, um es hier hinzuzufügen. Oder installiere eine Bibliothek aus dem öffentlichen Verzeichnis.",
|
||||
"hint_emptyPrivateLibrary": "Wähle ein Element von der Zeichenfläche, um es hier hinzuzufügen.",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "Auf Zeichenfläche suchen",
|
||||
"noMatch": "Keine Treffer gefunden...",
|
||||
"singleResult": "Ergebnis",
|
||||
"multipleResults": "Ergebnisse",
|
||||
"placeholder": "Text auf Zeichenfläche suchen...",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "Zeichenfläche löschen & Hintergrundfarbe zurücksetzen",
|
||||
"exportJSON": "In Datei exportieren",
|
||||
"exportImage": "Exportiere Bild...",
|
||||
"export": "Speichern als...",
|
||||
"copyToClipboard": "In Zwischenablage kopieren",
|
||||
"copyLink": "Link kopieren",
|
||||
"save": "In aktueller Datei speichern",
|
||||
"saveAs": "Speichern unter",
|
||||
"load": "Öffnen",
|
||||
"getShareableLink": "Teilbaren Link erhalten",
|
||||
"close": "Schließen",
|
||||
"selectLanguage": "Sprache auswählen",
|
||||
"scrollBackToContent": "Zurück zum Inhalt",
|
||||
"zoomIn": "Vergrößern",
|
||||
"zoomOut": "Verkleinern",
|
||||
"resetZoom": "Zoom zurücksetzen",
|
||||
"menu": "Menü",
|
||||
"done": "Fertig",
|
||||
"edit": "Bearbeiten",
|
||||
"undo": "Rückgängig machen",
|
||||
"redo": "Wiederholen",
|
||||
"resetLibrary": "Bibliothek zurücksetzen",
|
||||
"createNewRoom": "Neuen Raum erstellen",
|
||||
"fullScreen": "Vollbildanzeige",
|
||||
"darkMode": "Dunkles Design",
|
||||
"lightMode": "Helles Design",
|
||||
"systemMode": "System-Modus",
|
||||
"zenMode": "Zen-Modus",
|
||||
"objectsSnapMode": "Einrasten an Objekten",
|
||||
"exitZenMode": "Zen-Modus verlassen",
|
||||
"cancel": "Abbrechen",
|
||||
"saveLibNames": "",
|
||||
"clear": "Löschen",
|
||||
"remove": "Entfernen",
|
||||
"embed": "Einbettung umschalten",
|
||||
"publishLibrary": "",
|
||||
"submit": "Absenden",
|
||||
"confirm": "Bestätigen",
|
||||
"embeddableInteractionButton": "Klicken, um zu interagieren"
|
||||
},
|
||||
"alerts": {
|
||||
"clearReset": "Dies wird die ganze Zeichenfläche löschen. Bist du dir sicher?",
|
||||
"couldNotCreateShareableLink": "Konnte keinen teilbaren Link erstellen.",
|
||||
"couldNotCreateShareableLinkTooBig": "Konnte keinen teilbaren Link erstellen: Die Zeichnung ist zu groß",
|
||||
"couldNotLoadInvalidFile": "Ungültige Datei konnte nicht geladen werden",
|
||||
"importBackendFailed": "Import vom Server ist fehlgeschlagen.",
|
||||
"cannotExportEmptyCanvas": "Leere Zeichenfläche kann nicht exportiert werden.",
|
||||
"couldNotCopyToClipboard": "Kopieren in die Zwischenablage fehlgeschlagen.",
|
||||
"decryptFailed": "Daten konnten nicht entschlüsselt werden.",
|
||||
"uploadedSecurly": "Der Upload wurde mit Ende-zu-Ende-Verschlüsselung gespeichert. Weder Excalidraw noch Dritte können den Inhalt einsehen.",
|
||||
"loadSceneOverridePrompt": "Das Laden einer externen Zeichnung ersetzt den vorhandenen Inhalt. Möchtest du fortfahren?",
|
||||
"collabStopOverridePrompt": "Das Stoppen der Sitzung wird deine vorherige, lokal gespeicherte Zeichnung überschreiben. Bist du dir sicher?\n\n(Wenn du deine lokale Zeichnung behalten möchtest, schließe stattdessen den Browser-Tab.)",
|
||||
"errorAddingToLibrary": "Das Element konnte nicht zur Bibliothek hinzugefügt werden",
|
||||
"errorRemovingFromLibrary": "Das Element konnte nicht aus der Bibliothek entfernt werden",
|
||||
"confirmAddLibrary": "Dies fügt {{numShapes}} Form(en) zu deiner Bibliothek hinzu. Bist du dir sicher?",
|
||||
"imageDoesNotContainScene": "Dieses Bild scheint keine Szenendaten zu enthalten. Hast Du das Einbetten der Szene während des Exports aktiviert?",
|
||||
"cannotRestoreFromImage": "Die Zeichnung konnte aus dieser Bilddatei nicht wiederhergestellt werden",
|
||||
"invalidSceneUrl": "Die Szene konnte nicht von der angegebenen URL importiert werden. Sie ist entweder fehlerhaft oder enthält keine gültigen Excalidraw JSON-Daten.",
|
||||
"resetLibrary": "Dieses löscht deine Bibliothek. Bist du sicher?",
|
||||
"removeItemsFromsLibrary": "{{count}} Element(e) aus der Bibliothek löschen?",
|
||||
"invalidEncryptionKey": "Verschlüsselungsschlüssel muss 22 Zeichen lang sein. Die Live-Zusammenarbeit ist deaktiviert.",
|
||||
"collabOfflineWarning": "Keine Internetverbindung verfügbar.\nDeine Änderungen werden nicht gespeichert!",
|
||||
"localStorageQuotaExceeded": ""
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "Nicht unterstützter Dateityp.",
|
||||
"imageInsertError": "Das Bild konnte nicht eingefügt werden. Versuche es später erneut...",
|
||||
"fileTooBig": "Die Datei ist zu groß. Die maximal zulässige Größe ist {{maxSize}}.",
|
||||
"svgImageInsertError": "SVG-Bild konnte nicht eingefügt werden. Das SVG-Markup sieht ungültig aus.",
|
||||
"failedToFetchImage": "Bild konnte nicht abgerufen werden.",
|
||||
"cannotResolveCollabServer": "Konnte keine Verbindung zum Collab-Server herstellen. Bitte lade die Seite neu und versuche es erneut.",
|
||||
"importLibraryError": "Bibliothek konnte nicht geladen werden",
|
||||
"saveLibraryError": "Bibliothek konnte nicht gespeichert werden. Bitte speichere deine Bibliothek lokal in einer Datei, um sicherzustellen, dass keine Änderungen verloren gehen.",
|
||||
"collabSaveFailed": "Keine Speicherung in der Backend-Datenbank möglich. Wenn die Probleme weiterhin bestehen, solltest Du Deine Datei lokal speichern, um sicherzustellen, dass Du Deine Arbeit nicht verlierst.",
|
||||
"collabSaveFailed_sizeExceeded": "Keine Speicherung in der Backend-Datenbank möglich, die Zeichenfläche scheint zu groß zu sein. Du solltest Deine Datei lokal speichern, um sicherzustellen, dass Du Deine Arbeit nicht verlierst.",
|
||||
"imageToolNotSupported": "Bilder sind deaktiviert.",
|
||||
"brave_measure_text_error": {
|
||||
"line1": "Sieht so aus, als ob Du den Brave-Browser verwendest und die <bold>aggressive Blockierung von Fingerabdrücken</bold> aktiviert hast.",
|
||||
"line2": "Dies könnte dazu führen, dass die <bold>Textelemente</bold> in Ihren Zeichnungen zerstört werden.",
|
||||
"line3": "Wir empfehlen dringend, diese Einstellung zu deaktivieren. Dazu kannst Du <link>diesen Schritten</link> folgen.",
|
||||
"line4": "Wenn die Deaktivierung dieser Einstellung die fehlerhafte Anzeige von Textelementen nicht behebt, öffne bitte ein <issueLink>Ticket</issueLink> auf unserem GitHub oder schreibe uns auf <discordLink>Discord</discordLink>"
|
||||
},
|
||||
"libraryElementTypeError": {
|
||||
"embeddable": "Einbettbare Elemente können der Bibliothek nicht hinzugefügt werden.",
|
||||
"iframe": "IFrame-Elemente können nicht zur Bibliothek hinzugefügt werden.",
|
||||
"image": "Unterstützung für das Hinzufügen von Bildern in die Bibliothek kommt bald!"
|
||||
},
|
||||
"asyncPasteFailedOnRead": "Einfügen fehlgeschlagen (konnte aus der Zwischenablage des Systems nicht gelesen werden).",
|
||||
"asyncPasteFailedOnParse": "Einfügen fehlgeschlagen.",
|
||||
"copyToSystemClipboardFailed": "Kopieren in die Zwischenablage fehlgeschlagen."
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "Auswahl",
|
||||
"lasso": "",
|
||||
"image": "Bild einfügen",
|
||||
"rectangle": "Rechteck",
|
||||
"diamond": "Raute",
|
||||
"ellipse": "Ellipse",
|
||||
"arrow": "Pfeil",
|
||||
"line": "Linie",
|
||||
"freedraw": "Zeichnen",
|
||||
"text": "Text",
|
||||
"library": "Bibliothek",
|
||||
"lock": "Ausgewähltes Werkzeug nach Zeichnen aktiv lassen",
|
||||
"penMode": "Stift-Modus - Berührung verhindern",
|
||||
"link": "Link für ausgewählte Form hinzufügen / aktualisieren",
|
||||
"eraser": "Radierer",
|
||||
"frame": "Rahmenwerkzeug",
|
||||
"magicframe": "Wireframe zu Code",
|
||||
"embeddable": "Web-Einbettung",
|
||||
"laser": "Laserpointer",
|
||||
"hand": "Hand (Schwenkwerkzeug)",
|
||||
"extraTools": "Weitere Werkzeuge",
|
||||
"mermaidToExcalidraw": "Mermaid zu Excalidraw",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "Rechteck",
|
||||
"diamond": "Raute",
|
||||
"ellipse": "Ellipse",
|
||||
"arrow": "Pfeil",
|
||||
"line": "Linie",
|
||||
"freedraw": "Frei zeichnen",
|
||||
"text": "Text",
|
||||
"image": "Bild",
|
||||
"group": "Gruppe",
|
||||
"frame": "Rahmen",
|
||||
"magicframe": "Wireframe zu Code",
|
||||
"embeddable": "Web-Einbettung",
|
||||
"selection": "Auswahl",
|
||||
"iframe": "IFrame"
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "Aktionen für Zeichenfläche",
|
||||
"selectedShapeActions": "Aktionen für Auswahl",
|
||||
"shapes": "Formen"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"linearElement": "Klicken für Linie mit mehreren Punkten, Ziehen für einzelne Linie",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "Klicke und ziehe. Lass los, wenn du fertig bist",
|
||||
"text": "Tipp: Du kannst auch Text hinzufügen, indem du mit dem Auswahlwerkzeug auf eine beliebige Stelle doppelklickst",
|
||||
"embeddable": "Klicken und ziehen, um eine Webseiten-Einbettung zu erstellen",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"publishLibrary": "Veröffentliche deine eigene Bibliothek",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"firefox_clipboard_write": "Diese Funktion kann wahrscheinlich aktiviert werden, indem die Einstellung \"dom.events.asyncClipboard.clipboardItem\" auf \"true\" gesetzt wird. Um die Browsereinstellungen in Firefox zu ändern, besuche die Seite \"about:config\".",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "Vorschau kann nicht angezeigt werden",
|
||||
"canvasTooBig": "Die Leinwand ist möglicherweise zu groß.",
|
||||
"canvasTooBigTip": "Tipp: Schiebe die am weitesten entfernten Elemente ein wenig näher zusammen."
|
||||
},
|
||||
"errorSplash": {
|
||||
"headingMain": "Es ist ein Fehler aufgetreten. Versuche <button>die Seite neu zu laden.</button>",
|
||||
"clearCanvasMessage": "Wenn das Neuladen nicht funktioniert, versuche <button>die Zeichenfläche zu löschen.</button>",
|
||||
"clearCanvasCaveat": " Dies wird zum Verlust von Daten führen ",
|
||||
"trackedToSentry": "Der Fehler mit der Kennung {{eventId}} wurde in unserem System registriert.",
|
||||
"openIssueMessage": "Wir waren sehr vorsichtig und haben deine Zeichnungsinformationen nicht in die Fehlerinformationen aufgenommen. Wenn deine Zeichnung nicht privat ist, unterstütze uns bitte über unseren <button>Bug-Tracker</button>. Bitte teile die unten stehenden Informationen mit uns im GitHub Issue (Kopieren und Einfügen).",
|
||||
"sceneContent": "Zeichnungsinhalt:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": "Oder"
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "Lade Leute ein, an deiner Zeichnung mitzuarbeiten.",
|
||||
"desc_privacy": "Keine Sorge, die Sitzung ist Ende-zu-Ende verschlüsselt und vollständig privat. Nicht einmal unser Server kann sehen, was du zeichnest.",
|
||||
"button_startSession": "Sitzung starten",
|
||||
"button_stopSession": "Sitzung beenden",
|
||||
"desc_inProgressIntro": "Die Live-Sitzung wird nun ausgeführt.",
|
||||
"desc_shareLink": "Teile diesen Link mit allen, mit denen du zusammenarbeiten möchtest:",
|
||||
"desc_exitSession": "Wenn du die Sitzung beendest, wird deine Verbindung zum Raum getrennt. Du kannst jedoch lokal weiter an der Zeichnung arbeiten. Beachte, dass dies keine Auswirkungen auf andere hat und diese weiterhin gemeinsam an ihrer Version arbeiten können.",
|
||||
"shareTitle": "An einer Live-Kollaborationssitzung auf Excalidraw teilnehmen"
|
||||
},
|
||||
"errorDialog": {
|
||||
"title": "Fehler"
|
||||
},
|
||||
"exportDialog": {
|
||||
"disk_title": "Auf Festplatte speichern",
|
||||
"disk_details": "Exportiere die Zeichnungsdaten in eine Datei, die Du später importieren kannst.",
|
||||
"disk_button": "Als Datei speichern",
|
||||
"link_title": "Teilbarer Link",
|
||||
"link_details": "Als schreibgeschützten Link exportieren.",
|
||||
"link_button": "Als Link exportieren",
|
||||
"excalidrawplus_description": "Speichere die Szene in deinem Excalidraw+ Arbeitsbereich.",
|
||||
"excalidrawplus_button": "Exportieren",
|
||||
"excalidrawplus_exportError": "Konnte nicht nach Excalidraw+ exportieren..."
|
||||
},
|
||||
"helpDialog": {
|
||||
"blog": "Lies unseren Blog",
|
||||
"click": "klicken",
|
||||
"deepSelect": "Auswahl innerhalb der Gruppe",
|
||||
"deepBoxSelect": "Auswahl innerhalb der Gruppe, und Ziehen vermeiden",
|
||||
"createFlowchart": "Erstelle ein Flussdiagramm aus einem generischen Element",
|
||||
"navigateFlowchart": "Durchsuche ein Flussdiagramm",
|
||||
"curvedArrow": "Gebogener Pfeil",
|
||||
"curvedLine": "Gebogene Linie",
|
||||
"documentation": "Dokumentation",
|
||||
"doubleClick": "doppelklicken",
|
||||
"drag": "ziehen",
|
||||
"editor": "Editor",
|
||||
"editLineArrowPoints": "Linien-/Pfeil-Punkte bearbeiten",
|
||||
"editText": "Text bearbeiten / Label hinzufügen",
|
||||
"github": "Ein Problem gefunden? Informiere uns",
|
||||
"howto": "Folge unseren Anleitungen",
|
||||
"or": "oder",
|
||||
"preventBinding": "Pfeil-Bindung verhindern",
|
||||
"tools": "Werkzeuge",
|
||||
"shortcuts": "Tastaturkürzel",
|
||||
"textFinish": "Bearbeitung beenden (Texteditor)",
|
||||
"textNewLine": "Neue Zeile hinzufügen (Texteditor)",
|
||||
"title": "Hilfe",
|
||||
"view": "Ansicht",
|
||||
"zoomToFit": "Zoomen um alle Elemente einzupassen",
|
||||
"zoomToSelection": "Auf Auswahl zoomen",
|
||||
"toggleElementLock": "Auswahl sperren/entsperren",
|
||||
"movePageUpDown": "Seite nach oben/unten verschieben",
|
||||
"movePageLeftRight": "Seite nach links/rechts verschieben",
|
||||
"cropStart": "Bild zuschneiden",
|
||||
"cropFinish": "Zuschneiden des Bildes beenden"
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": "Zeichenfläche löschen"
|
||||
},
|
||||
"publishDialog": {
|
||||
"title": "Bibliothek veröffentlichen",
|
||||
"itemName": "Elementname",
|
||||
"authorName": "Name des Autors",
|
||||
"githubUsername": "GitHub-Benutzername",
|
||||
"twitterUsername": "Twitter-Benutzername",
|
||||
"libraryName": "Name der Bibliothek",
|
||||
"libraryDesc": "Beschreibung der Bibliothek",
|
||||
"website": "Webseite",
|
||||
"placeholder": {
|
||||
"authorName": "Dein Name oder Benutzername",
|
||||
"libraryName": "Name deiner Bibliothek",
|
||||
"libraryDesc": "Beschreibung deiner Bibliothek, um anderen Nutzern bei der Verwendung zu helfen",
|
||||
"githubHandle": "GitHub-Handle (optional), damit du die Bibliothek bearbeiten kannst, wenn sie zur Überprüfung eingereicht wurde",
|
||||
"twitterHandle": "Twitter-Benutzername (optional), damit wir wissen, wen wir bei Werbung über Twitter nennen können",
|
||||
"website": "Link zu deiner persönlichen Webseite oder zu anderer Seite (optional)"
|
||||
},
|
||||
"errors": {
|
||||
"required": "Erforderlich",
|
||||
"website": "Gültige URL eingeben"
|
||||
},
|
||||
"noteDescription": "Sende deine Bibliothek ein, um in die <link>öffentliche Bibliotheks-Repository aufgenommen zu werden</link>damit andere Nutzer sie in ihren Zeichnungen verwenden können.",
|
||||
"noteGuidelines": "Die Bibliothek muss zuerst manuell freigegeben werden. Bitte lies die <link>Richtlinien</link> vor dem Absenden. Du benötigst ein GitHub-Konto, um zu kommunizieren und Änderungen vorzunehmen, falls erforderlich, aber es ist nicht unbedingt erforderlich.",
|
||||
"noteLicense": "Mit dem Absenden stimmst du zu, dass die Bibliothek unter der <link>MIT-Lizenz, </link>die zusammengefasst beinhaltet, dass jeder sie ohne Einschränkungen nutzen kann.",
|
||||
"noteItems": "Jedes Bibliothekselement muss einen eigenen Namen haben, damit es gefiltert werden kann. Die folgenden Bibliothekselemente werden hinzugefügt:",
|
||||
"atleastOneLibItem": "Bitte wähle mindestens ein Bibliothekselement aus, um zu beginnen",
|
||||
"republishWarning": "Hinweis: Einige der ausgewählten Elemente sind bereits als veröffentlicht/eingereicht markiert. Du solltest Elemente nur erneut einreichen, wenn Du eine existierende Bibliothek oder Einreichung aktualisierst."
|
||||
},
|
||||
"publishSuccessDialog": {
|
||||
"title": "Bibliothek übermittelt",
|
||||
"content": "Vielen Dank {{authorName}}. Deine Bibliothek wurde zur Überprüfung eingereicht. Du kannst den Status verfolgen<link>hier</link>"
|
||||
},
|
||||
"confirmDialog": {
|
||||
"resetLibrary": "Bibliothek zurücksetzen",
|
||||
"removeItemsFromLib": "Ausgewählte Elemente aus der Bibliothek entfernen"
|
||||
},
|
||||
"imageExportDialog": {
|
||||
"header": "Bild exportieren",
|
||||
"label": {
|
||||
"withBackground": "Hintergrund",
|
||||
"onlySelected": "Nur ausgewählte",
|
||||
"darkMode": "Dunkler Modus",
|
||||
"embedScene": "Szene einbetten",
|
||||
"scale": "Skalierung",
|
||||
"padding": "Abstand"
|
||||
},
|
||||
"tooltip": {
|
||||
"embedScene": "Die Zeichnungsdaten werden in der exportierten PNG/SVG-Datei gespeichert, sodass das Dokument später weiter bearbeitet werden kann. \nDieses wird die exportierte Datei vergrößern."
|
||||
},
|
||||
"title": {
|
||||
"exportToPng": "Als PNG exportieren",
|
||||
"exportToSvg": "Als SVG exportieren",
|
||||
"copyPngToClipboard": "PNG in die Zwischenablage kopieren"
|
||||
},
|
||||
"button": {
|
||||
"exportToPng": "PNG",
|
||||
"exportToSvg": "SVG",
|
||||
"copyPngToClipboard": "In Zwischenablage kopieren"
|
||||
}
|
||||
},
|
||||
"encrypted": {
|
||||
"tooltip": "Da deine Zeichnungen Ende-zu-Ende verschlüsselt werden, sehen auch unsere Excalidraw-Server sie niemals.",
|
||||
"link": "Blogbeitrag über Ende-zu-Ende-Verschlüsselung in Excalidraw"
|
||||
},
|
||||
"stats": {
|
||||
"angle": "Winkel",
|
||||
"shapes": "Formen",
|
||||
"height": "Höhe",
|
||||
"scene": "Zeichnung",
|
||||
"selected": "Ausgewählt",
|
||||
"storage": "Speicher",
|
||||
"fullTitle": "Zeichenflächen- & Formeigenschaften",
|
||||
"title": "Eigenschaften",
|
||||
"generalStats": "Allgemein",
|
||||
"elementProperties": "Formeigenschaften",
|
||||
"total": "Gesamt",
|
||||
"version": "Version",
|
||||
"versionCopy": "Zum Kopieren klicken",
|
||||
"versionNotAvailable": "Version nicht verfügbar",
|
||||
"width": "Breite"
|
||||
},
|
||||
"toast": {
|
||||
"addedToLibrary": "Zur Bibliothek hinzugefügt",
|
||||
"copyStyles": "Formatierungen kopiert.",
|
||||
"copyToClipboard": "In die Zwischenablage kopiert.",
|
||||
"copyToClipboardAsPng": "{{exportSelection}} als PNG in die Zwischenablage kopiert\n({{exportColorScheme}})",
|
||||
"copyToClipboardAsSvg": "{{exportSelection}} als SVG in die Zwischenablage kopiert ({{exportColorScheme}})",
|
||||
"fileSaved": "Datei gespeichert.",
|
||||
"fileSavedToFilename": "Als {filename} gespeichert",
|
||||
"canvas": "Zeichenfläche",
|
||||
"selection": "Auswahl",
|
||||
"pasteAsSingleElement": "Verwende {{shortcut}} , um als einzelnes Element\neinzufügen oder in einen existierenden Texteditor einzufügen",
|
||||
"unableToEmbed": "Einbetten dieser URL ist derzeit nicht zulässig. Erstelle einen Issue auf GitHub, um die URL freigeben zu lassen",
|
||||
"unrecognizedLinkFormat": "Der Link, den Du eingebettet hast, stimmt nicht mit dem erwarteten Format überein. Bitte versuche den 'embed' String einzufügen, der von der Quellseite zur Verfügung gestellt wird",
|
||||
"elementLinkCopied": "Link in Zwischenablage kopiert"
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "Transparent",
|
||||
"black": "Schwarz",
|
||||
"white": "Weiß",
|
||||
"red": "Rot",
|
||||
"pink": "Pink",
|
||||
"grape": "Traube",
|
||||
"violet": "Violett",
|
||||
"gray": "Grau",
|
||||
"blue": "Blau",
|
||||
"cyan": "Cyan",
|
||||
"teal": "Blaugrün",
|
||||
"green": "Grün",
|
||||
"yellow": "Gelb",
|
||||
"orange": "Orange",
|
||||
"bronze": "Bronze"
|
||||
},
|
||||
"welcomeScreen": {
|
||||
"app": {
|
||||
"center_heading": "Alle Daten werden lokal in Deinem Browser gespeichert.",
|
||||
"center_heading_plus": "Möchtest du stattdessen zu Excalidraw+ gehen?",
|
||||
"menuHint": "Exportieren, Einstellungen, Sprachen, ..."
|
||||
},
|
||||
"defaults": {
|
||||
"menuHint": "Exportieren, Einstellungen und mehr...",
|
||||
"center_heading": "Diagramme. Einfach. Gemacht.",
|
||||
"toolbarHint": "Wähle ein Werkzeug & beginne zu zeichnen!",
|
||||
"helpHint": "Kurzbefehle & Hilfe"
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "Beliebteste benutzerdefinierte Farben",
|
||||
"colors": "Farben",
|
||||
"shades": "Schattierungen",
|
||||
"hexCode": "Hex-Code",
|
||||
"noShades": "Keine Schattierungen für diese Farbe verfügbar"
|
||||
},
|
||||
"overwriteConfirm": {
|
||||
"action": {
|
||||
"exportToImage": {
|
||||
"title": "Als Bild exportieren",
|
||||
"button": "Als Bild exportieren",
|
||||
"description": "Exportiere die Zeichnungsdaten als ein Bild, von dem Du später importieren kannst."
|
||||
},
|
||||
"saveToDisk": {
|
||||
"title": "Auf Festplatte speichern",
|
||||
"button": "Auf Festplatte speichern",
|
||||
"description": "Exportiere die Zeichnungsdaten in eine Datei, von der Du später importieren kannst."
|
||||
},
|
||||
"excalidrawPlus": {
|
||||
"title": "Excalidraw+",
|
||||
"button": "Export nach Excalidraw+",
|
||||
"description": "Speichere die Szene in deinem Excalidraw+-Arbeitsbereich."
|
||||
}
|
||||
},
|
||||
"modal": {
|
||||
"loadFromFile": {
|
||||
"title": "Aus Datei laden",
|
||||
"button": "Aus Datei laden",
|
||||
"description": "Das Laden aus einer Datei wird <bold>Deinen vorhandenen Inhalt ersetzen</bold>.<br></br>Du kannst Deine Zeichnung zuerst mit einer der folgenden Optionen sichern."
|
||||
},
|
||||
"shareableLink": {
|
||||
"title": "Aus Link laden",
|
||||
"button": "Meinen Inhalt ersetzen",
|
||||
"description": "Das Laden einer externen Zeichnung wird <bold>Deinen vorhandenen Inhalt ersetzen</bold>.<br></br>Du kannst Deine Zeichnung zuerst mit einer der folgenden Optionen sichern."
|
||||
}
|
||||
}
|
||||
},
|
||||
"mermaid": {
|
||||
"title": "Mermaid zu Excalidraw",
|
||||
"button": "Einfügen",
|
||||
"description": "Derzeit werden nur <flowchartLink>Flussdiagramme</flowchartLink>, <sequenceLink>Sequenzdiagramme</sequenceLink> und <classLink>Klassendiagramme</classLink> unterstützt. Die anderen Typen werden als Bild in Excalidraw dargestellt.",
|
||||
"syntax": "Mermaid-Syntax",
|
||||
"preview": "Vorschau"
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": "Schnellsuche"
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": "alt"
|
||||
},
|
||||
"sceneFonts": "In dieser Szene",
|
||||
"availableFonts": "Verfügbare Schriftarten",
|
||||
"empty": "Keine Schriftarten gefunden"
|
||||
},
|
||||
"userList": {
|
||||
"empty": "Keine Benutzer gefunden",
|
||||
"hint": {
|
||||
"text": "Klicke auf Benutzer um zu folgen",
|
||||
"followStatus": "Du folgst derzeit diesem Benutzer",
|
||||
"inCall": "Benutzer ist in einem Sprachanruf",
|
||||
"micMuted": "Mikrofon des Benutzers ist stumm geschaltet",
|
||||
"isSpeaking": "Benutzer spricht"
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "Befehlspalette",
|
||||
"shortcuts": {
|
||||
"select": "Auswählen",
|
||||
"confirm": "Bestätigen",
|
||||
"close": "Schließen"
|
||||
},
|
||||
"recents": "Zuletzt verwendet",
|
||||
"search": {
|
||||
"placeholder": "Suche in Menüs und Befehlen, entdecke versteckte Funktionen",
|
||||
"noMatch": "Keine passenden Befehle..."
|
||||
},
|
||||
"itemNotAvailable": "Befehl ist nicht verfügbar...",
|
||||
"shortcutHint": "Benutze {{shortcut}} für Befehlspalette"
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"labels": {
|
||||
"paste": "Einfügen",
|
||||
"pasteAsPlaintext": "Als unformatierten Text einfügen",
|
||||
"pasteAsPlaintext": "Als reinen Text einfügen",
|
||||
"pasteCharts": "Diagramme einfügen",
|
||||
"selectAll": "Alle auswählen",
|
||||
"multiSelect": "Element zur Auswahl hinzufügen",
|
||||
@@ -21,9 +21,7 @@
|
||||
"copyStyles": "Formatierung kopieren",
|
||||
"pasteStyles": "Formatierung übernehmen",
|
||||
"stroke": "Strich",
|
||||
"changeStroke": "Strichfarbe ändern",
|
||||
"background": "Hintergrund",
|
||||
"changeBackground": "Hintergrundfarbe ändern",
|
||||
"fill": "Füllung",
|
||||
"strokeWidth": "Strichstärke",
|
||||
"strokeStyle": "Konturstil",
|
||||
@@ -46,14 +44,6 @@
|
||||
"arrowhead_triangle_outline": "Dreieck (Umrandung)",
|
||||
"arrowhead_diamond": "Raute",
|
||||
"arrowhead_diamond_outline": "Raute (Umrandung)",
|
||||
"arrowhead_crowfoot_many": "Krähenfuß (viele)",
|
||||
"arrowhead_crowfoot_one": "Krähenfuß (einer)",
|
||||
"arrowhead_crowfoot_one_or_many": "Krähenfuß (einer oder viele)",
|
||||
"more_options": "Weitere Optionen",
|
||||
"arrowtypes": "Pfeiltyp",
|
||||
"arrowtype_sharp": "Scharfer Pfeil",
|
||||
"arrowtype_round": "Gebogener Pfeil",
|
||||
"arrowtype_elbowed": "Ellenbogen-Pfeil",
|
||||
"fontSize": "Schriftgröße",
|
||||
"fontFamily": "Schriftfamilie",
|
||||
"addWatermark": "\"Made with Excalidraw\" hinzufügen",
|
||||
@@ -82,7 +72,6 @@
|
||||
"canvasColors": "Auf Leinwand verwendet",
|
||||
"canvasBackground": "Zeichenflächenhintergrund",
|
||||
"drawingCanvas": "Leinwand",
|
||||
"clearCanvas": "Zeichenfläche löschen",
|
||||
"layers": "Ebenen",
|
||||
"actions": "Aktionen",
|
||||
"language": "Sprache",
|
||||
@@ -95,13 +84,12 @@
|
||||
"group": "Auswahl gruppieren",
|
||||
"ungroup": "Gruppierung aufheben",
|
||||
"collaborators": "Mitarbeitende",
|
||||
"toggleGrid": "Raster umschalten",
|
||||
"showGrid": "Raster anzeigen",
|
||||
"addToLibrary": "Zur Bibliothek hinzufügen",
|
||||
"removeFromLibrary": "Aus Bibliothek entfernen",
|
||||
"libraryLoadingMessage": "Lade Bibliothek…",
|
||||
"libraries": "Bibliotheken durchsuchen",
|
||||
"loadingScene": "Lade Zeichnung…",
|
||||
"loadScene": "Szene aus Datei laden",
|
||||
"align": "Ausrichten",
|
||||
"alignTop": "Obere Kanten",
|
||||
"alignBottom": "Untere Kanten",
|
||||
@@ -117,33 +105,26 @@
|
||||
"share": "Teilen",
|
||||
"showStroke": "Auswahl für Strichfarbe anzeigen",
|
||||
"showBackground": "Hintergrundfarbe auswählen",
|
||||
"showFonts": "Schriftauswahl anzeigen",
|
||||
"toggleTheme": "Helles/dunkles Design umschalten",
|
||||
"theme": "Design",
|
||||
"toggleTheme": "Design umschalten",
|
||||
"personalLib": "Persönliche Bibliothek",
|
||||
"excalidrawLib": "Excalidraw Bibliothek",
|
||||
"decreaseFontSize": "Schriftgröße verringern",
|
||||
"increaseFontSize": "Schriftgröße erhöhen",
|
||||
"decreaseFontSize": "Schriftgröße verkleinern",
|
||||
"increaseFontSize": "Schrift vergrößern",
|
||||
"unbindText": "Text lösen",
|
||||
"bindText": "Text an Container binden",
|
||||
"createContainerFromText": "Text in Container einbetten",
|
||||
"link": {
|
||||
"edit": "Link bearbeiten",
|
||||
"editEmbed": "Einbettbaren Link bearbeiten",
|
||||
"create": "Link hinzufügen",
|
||||
"editEmbed": "Link bearbeiten & einbetten",
|
||||
"create": "Link erstellen",
|
||||
"createEmbed": "Link erstellen & einbetten",
|
||||
"label": "Link",
|
||||
"labelEmbed": "Verlinken & einbetten",
|
||||
"empty": "Kein Link festgelegt",
|
||||
"hint": "Link hier eingeben oder einfügen",
|
||||
"goToElement": "Gehe zu Zielelement"
|
||||
"empty": "Kein Link festgelegt"
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "Linie bearbeiten",
|
||||
"editArrow": "Pfeil bearbeiten"
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"exit": "Linieneditor verlassen"
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "Sperren",
|
||||
@@ -157,46 +138,12 @@
|
||||
"removeAllElementsFromFrame": "Alle Elemente aus dem Rahmen entfernen",
|
||||
"eyeDropper": "Farbe von der Zeichenfläche auswählen",
|
||||
"textToDiagram": "Text zu Diagramm",
|
||||
"prompt": "Eingabe",
|
||||
"followUs": "Folge uns",
|
||||
"discordChat": "Discord-Chat",
|
||||
"zoomToFitViewport": "Zoom auf Ansicht anpassen",
|
||||
"zoomToFitSelection": "Zoom auf Auswahl anpassen",
|
||||
"zoomToFit": "Zoom auf alle Elemente anpassen",
|
||||
"installPWA": "Excalidraw lokal installieren (PWA)",
|
||||
"autoResize": "Aktiviere automatische Textgrößenanpassung",
|
||||
"imageCropping": "Bild zuschneiden",
|
||||
"unCroppedDimension": "Nicht zugeschnittene Dimension",
|
||||
"copyElementLink": "Link zum Objekt kopieren",
|
||||
"linkToElement": "Link zum Objekt",
|
||||
"wrapSelectionInFrame": "Auswahl in Rahmen einbetten",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "Link zum Objekt",
|
||||
"desc": "Klicke auf eine Form auf der Zeichenfläche oder füge einen Link ein.",
|
||||
"notFound": "Verknüpftes Objekt wurde nicht auf der Zeichenfläche gefunden."
|
||||
"prompt": "Eingabe"
|
||||
},
|
||||
"library": {
|
||||
"noItems": "Noch keine Elemente hinzugefügt...",
|
||||
"hint_emptyLibrary": "Wähle ein Element auf der Zeichenfläche, um es hier hinzuzufügen. Oder installiere eine Bibliothek aus dem öffentlichen Verzeichnis.",
|
||||
"hint_emptyPrivateLibrary": "Wähle ein Element von der Zeichenfläche, um es hier hinzuzufügen.",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "Auf Zeichenfläche suchen",
|
||||
"noMatch": "Keine Treffer gefunden...",
|
||||
"singleResult": "Ergebnis",
|
||||
"multipleResults": "Ergebnisse",
|
||||
"placeholder": "Text auf Zeichenfläche suchen...",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"hint_emptyPrivateLibrary": "Wähle ein Element von der Zeichenfläche, um es hier hinzuzufügen."
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "Zeichenfläche löschen & Hintergrundfarbe zurücksetzen",
|
||||
@@ -204,7 +151,6 @@
|
||||
"exportImage": "Exportiere Bild...",
|
||||
"export": "Speichern als...",
|
||||
"copyToClipboard": "In Zwischenablage kopieren",
|
||||
"copyLink": "Link kopieren",
|
||||
"save": "In aktueller Datei speichern",
|
||||
"saveAs": "Speichern unter",
|
||||
"load": "Öffnen",
|
||||
@@ -225,16 +171,14 @@
|
||||
"fullScreen": "Vollbildanzeige",
|
||||
"darkMode": "Dunkles Design",
|
||||
"lightMode": "Helles Design",
|
||||
"systemMode": "System-Modus",
|
||||
"zenMode": "Zen-Modus",
|
||||
"objectsSnapMode": "Einrasten an Objekten",
|
||||
"exitZenMode": "Zen-Modus verlassen",
|
||||
"cancel": "Abbrechen",
|
||||
"saveLibNames": "",
|
||||
"clear": "Löschen",
|
||||
"remove": "Entfernen",
|
||||
"embed": "Einbettung umschalten",
|
||||
"publishLibrary": "",
|
||||
"publishLibrary": "Veröffentlichen",
|
||||
"submit": "Absenden",
|
||||
"confirm": "Bestätigen",
|
||||
"embeddableInteractionButton": "Klicken, um zu interagieren"
|
||||
@@ -260,8 +204,7 @@
|
||||
"resetLibrary": "Dieses löscht deine Bibliothek. Bist du sicher?",
|
||||
"removeItemsFromsLibrary": "{{count}} Element(e) aus der Bibliothek löschen?",
|
||||
"invalidEncryptionKey": "Verschlüsselungsschlüssel muss 22 Zeichen lang sein. Die Live-Zusammenarbeit ist deaktiviert.",
|
||||
"collabOfflineWarning": "Keine Internetverbindung verfügbar.\nDeine Änderungen werden nicht gespeichert!",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"collabOfflineWarning": "Keine Internetverbindung verfügbar.\nDeine Änderungen werden nicht gespeichert!"
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "Nicht unterstützter Dateityp.",
|
||||
@@ -269,9 +212,9 @@
|
||||
"fileTooBig": "Die Datei ist zu groß. Die maximal zulässige Größe ist {{maxSize}}.",
|
||||
"svgImageInsertError": "SVG-Bild konnte nicht eingefügt werden. Das SVG-Markup sieht ungültig aus.",
|
||||
"failedToFetchImage": "Bild konnte nicht abgerufen werden.",
|
||||
"invalidSVGString": "Ungültige SVG.",
|
||||
"cannotResolveCollabServer": "Konnte keine Verbindung zum Collab-Server herstellen. Bitte lade die Seite neu und versuche es erneut.",
|
||||
"importLibraryError": "Bibliothek konnte nicht geladen werden",
|
||||
"saveLibraryError": "Bibliothek konnte nicht gespeichert werden. Bitte speichere deine Bibliothek lokal in einer Datei, um sicherzustellen, dass keine Änderungen verloren gehen.",
|
||||
"collabSaveFailed": "Keine Speicherung in der Backend-Datenbank möglich. Wenn die Probleme weiterhin bestehen, solltest Du Deine Datei lokal speichern, um sicherzustellen, dass Du Deine Arbeit nicht verlierst.",
|
||||
"collabSaveFailed_sizeExceeded": "Keine Speicherung in der Backend-Datenbank möglich, die Zeichenfläche scheint zu groß zu sein. Du solltest Deine Datei lokal speichern, um sicherzustellen, dass Du Deine Arbeit nicht verlierst.",
|
||||
"imageToolNotSupported": "Bilder sind deaktiviert.",
|
||||
@@ -292,7 +235,6 @@
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "Auswahl",
|
||||
"lasso": "",
|
||||
"image": "Bild einfügen",
|
||||
"rectangle": "Rechteck",
|
||||
"diamond": "Raute",
|
||||
@@ -313,23 +255,7 @@
|
||||
"hand": "Hand (Schwenkwerkzeug)",
|
||||
"extraTools": "Weitere Werkzeuge",
|
||||
"mermaidToExcalidraw": "Mermaid zu Excalidraw",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "Rechteck",
|
||||
"diamond": "Raute",
|
||||
"ellipse": "Ellipse",
|
||||
"arrow": "Pfeil",
|
||||
"line": "Linie",
|
||||
"freedraw": "Frei zeichnen",
|
||||
"text": "Text",
|
||||
"image": "Bild",
|
||||
"group": "Gruppe",
|
||||
"frame": "Rahmen",
|
||||
"magicframe": "Wireframe zu Code",
|
||||
"embeddable": "Web-Einbettung",
|
||||
"selection": "Auswahl",
|
||||
"iframe": "IFrame"
|
||||
"magicSettings": "KI-Einstellungen"
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "Aktionen für Zeichenfläche",
|
||||
@@ -337,33 +263,28 @@
|
||||
"shapes": "Formen"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"canvasPanning": "Um die Zeichenfläche zu verschieben, halte das Mausrad oder die Leertaste während des Ziehens, oder verwende das Hand-Werkzeug",
|
||||
"linearElement": "Klicken für Linie mit mehreren Punkten, Ziehen für einzelne Linie",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "Klicke und ziehe. Lass los, wenn du fertig bist",
|
||||
"text": "Tipp: Du kannst auch Text hinzufügen, indem du mit dem Auswahlwerkzeug auf eine beliebige Stelle doppelklickst",
|
||||
"embeddable": "Klicken und ziehen, um eine Webseiten-Einbettung zu erstellen",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"text_selected": "Doppelklicken oder Eingabetaste drücken, um Text zu bearbeiten",
|
||||
"text_editing": "Drücke Escape oder CtrlOrCmd+Eingabetaste, um die Bearbeitung abzuschließen",
|
||||
"linearElementMulti": "Zum Beenden auf den letzten Punkt klicken oder Escape oder Eingabe drücken",
|
||||
"lockAngle": "Du kannst Winkel einschränken, indem du SHIFT gedrückt hältst",
|
||||
"resize": "Du kannst die Proportionen einschränken, indem du SHIFT während der Größenänderung gedrückt hältst. Halte ALT gedrückt, um die Größe vom Zentrum aus zu ändern",
|
||||
"resizeImage": "Du kannst die Größe frei ändern, indem du SHIFT gedrückt hältst; halte ALT, um die Größe vom Zentrum aus zu ändern",
|
||||
"rotate": "Du kannst Winkel einschränken, indem du SHIFT während der Drehung gedrückt hältst",
|
||||
"lineEditor_info": "CtrlOrCmd halten und Doppelklick oder CtrlOrCmd + Eingabe drücken, um Punkte zu bearbeiten",
|
||||
"lineEditor_pointSelected": "Drücke Löschen, um Punkt(e) zu entfernen, CtrlOrCmd+D zum Duplizieren oder ziehe zum Verschieben",
|
||||
"lineEditor_nothingSelected": "Wähle einen zu bearbeitenden Punkt (halte SHIFT gedrückt um mehrere Punkte auszuwählen),\noder halte Alt gedrückt und klicke um neue Punkte hinzuzufügen",
|
||||
"placeImage": "Klicken, um das Bild zu platzieren oder klicken und ziehen um seine Größe manuell zu setzen",
|
||||
"publishLibrary": "Veröffentliche deine eigene Bibliothek",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"bindTextToElement": "Zum Hinzufügen Eingabetaste drücken",
|
||||
"deepBoxSelect": "Halte CtrlOrCmd gedrückt, um innerhalb der Gruppe auszuwählen, und um Ziehen zu vermeiden",
|
||||
"eraserRevert": "Halte Alt gedrückt, um die zum Löschen markierten Elemente zurückzusetzen",
|
||||
"firefox_clipboard_write": "Diese Funktion kann wahrscheinlich aktiviert werden, indem die Einstellung \"dom.events.asyncClipboard.clipboardItem\" auf \"true\" gesetzt wird. Um die Browsereinstellungen in Firefox zu ändern, besuche die Seite \"about:config\".",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": "Halte CtrlOrCmd gedrückt, um das Einrasten zu deaktivieren"
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "Vorschau kann nicht angezeigt werden",
|
||||
@@ -378,12 +299,9 @@
|
||||
"openIssueMessage": "Wir waren sehr vorsichtig und haben deine Zeichnungsinformationen nicht in die Fehlerinformationen aufgenommen. Wenn deine Zeichnung nicht privat ist, unterstütze uns bitte über unseren <button>Bug-Tracker</button>. Bitte teile die unten stehenden Informationen mit uns im GitHub Issue (Kopieren und Einfügen).",
|
||||
"sceneContent": "Zeichnungsinhalt:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": "Oder"
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "Lade Leute ein, an deiner Zeichnung mitzuarbeiten.",
|
||||
"desc_privacy": "Keine Sorge, die Sitzung ist Ende-zu-Ende verschlüsselt und vollständig privat. Nicht einmal unser Server kann sehen, was du zeichnest.",
|
||||
"desc_intro": "Du kannst Leute zu deiner aktuellen Zeichnung einladen um mit ihnen zusammenzuarbeiten.",
|
||||
"desc_privacy": "Keine Sorge, die Sitzung nutzt eine Ende-zu-Ende-Verschlüsselung. Alles was du zeichnest, bleibt privat. Auch unser Server sieht nicht, was du dir einfallen lässt.",
|
||||
"button_startSession": "Sitzung starten",
|
||||
"button_stopSession": "Sitzung beenden",
|
||||
"desc_inProgressIntro": "Die Live-Sitzung wird nun ausgeführt.",
|
||||
@@ -410,8 +328,6 @@
|
||||
"click": "klicken",
|
||||
"deepSelect": "Auswahl innerhalb der Gruppe",
|
||||
"deepBoxSelect": "Auswahl innerhalb der Gruppe, und Ziehen vermeiden",
|
||||
"createFlowchart": "Erstelle ein Flussdiagramm aus einem generischen Element",
|
||||
"navigateFlowchart": "Durchsuche ein Flussdiagramm",
|
||||
"curvedArrow": "Gebogener Pfeil",
|
||||
"curvedLine": "Gebogene Linie",
|
||||
"documentation": "Dokumentation",
|
||||
@@ -434,9 +350,7 @@
|
||||
"zoomToSelection": "Auf Auswahl zoomen",
|
||||
"toggleElementLock": "Auswahl sperren/entsperren",
|
||||
"movePageUpDown": "Seite nach oben/unten verschieben",
|
||||
"movePageLeftRight": "Seite nach links/rechts verschieben",
|
||||
"cropStart": "Bild zuschneiden",
|
||||
"cropFinish": "Zuschneiden des Bildes beenden"
|
||||
"movePageLeftRight": "Seite nach links/rechts verschieben"
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": "Zeichenfläche löschen"
|
||||
@@ -507,15 +421,13 @@
|
||||
},
|
||||
"stats": {
|
||||
"angle": "Winkel",
|
||||
"shapes": "Formen",
|
||||
"element": "Element",
|
||||
"elements": "Elemente",
|
||||
"height": "Höhe",
|
||||
"scene": "Zeichnung",
|
||||
"selected": "Ausgewählt",
|
||||
"storage": "Speicher",
|
||||
"fullTitle": "Zeichenflächen- & Formeigenschaften",
|
||||
"title": "Eigenschaften",
|
||||
"generalStats": "Allgemein",
|
||||
"elementProperties": "Formeigenschaften",
|
||||
"title": "Statistiken für Nerds",
|
||||
"total": "Gesamt",
|
||||
"version": "Version",
|
||||
"versionCopy": "Zum Kopieren klicken",
|
||||
@@ -527,15 +439,13 @@
|
||||
"copyStyles": "Formatierungen kopiert.",
|
||||
"copyToClipboard": "In die Zwischenablage kopiert.",
|
||||
"copyToClipboardAsPng": "{{exportSelection}} als PNG in die Zwischenablage kopiert\n({{exportColorScheme}})",
|
||||
"copyToClipboardAsSvg": "{{exportSelection}} als SVG in die Zwischenablage kopiert ({{exportColorScheme}})",
|
||||
"fileSaved": "Datei gespeichert.",
|
||||
"fileSavedToFilename": "Als {filename} gespeichert",
|
||||
"canvas": "Zeichenfläche",
|
||||
"selection": "Auswahl",
|
||||
"pasteAsSingleElement": "Verwende {{shortcut}} , um als einzelnes Element\neinzufügen oder in einen existierenden Texteditor einzufügen",
|
||||
"unableToEmbed": "Einbetten dieser URL ist derzeit nicht zulässig. Erstelle einen Issue auf GitHub, um die URL freigeben zu lassen",
|
||||
"unrecognizedLinkFormat": "Der Link, den Du eingebettet hast, stimmt nicht mit dem erwarteten Format überein. Bitte versuche den 'embed' String einzufügen, der von der Quellseite zur Verfügung gestellt wird",
|
||||
"elementLinkCopied": "Link in Zwischenablage kopiert"
|
||||
"unrecognizedLinkFormat": "Der Link, den Du eingebettet hast, stimmt nicht mit dem erwarteten Format überein. Bitte versuche den 'embed' String einzufügen, der von der Quellseite zur Verfügung gestellt wird"
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "Transparent",
|
||||
@@ -568,7 +478,6 @@
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "Beliebteste benutzerdefinierte Farben",
|
||||
"colors": "Farben",
|
||||
"shades": "Schattierungen",
|
||||
@@ -612,53 +521,5 @@
|
||||
"description": "Derzeit werden nur <flowchartLink>Flussdiagramme</flowchartLink>, <sequenceLink>Sequenzdiagramme</sequenceLink> und <classLink>Klassendiagramme</classLink> unterstützt. Die anderen Typen werden als Bild in Excalidraw dargestellt.",
|
||||
"syntax": "Mermaid-Syntax",
|
||||
"preview": "Vorschau"
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": "Schnellsuche"
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": "alt"
|
||||
},
|
||||
"sceneFonts": "In dieser Szene",
|
||||
"availableFonts": "Verfügbare Schriftarten",
|
||||
"empty": "Keine Schriftarten gefunden"
|
||||
},
|
||||
"userList": {
|
||||
"empty": "Keine Benutzer gefunden",
|
||||
"hint": {
|
||||
"text": "Klicke auf Benutzer um zu folgen",
|
||||
"followStatus": "Du folgst derzeit diesem Benutzer",
|
||||
"inCall": "Benutzer ist in einem Sprachanruf",
|
||||
"micMuted": "Mikrofon des Benutzers ist stumm geschaltet",
|
||||
"isSpeaking": "Benutzer spricht"
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "Befehlspalette",
|
||||
"shortcuts": {
|
||||
"select": "Auswählen",
|
||||
"confirm": "Bestätigen",
|
||||
"close": "Schließen"
|
||||
},
|
||||
"recents": "Zuletzt verwendet",
|
||||
"search": {
|
||||
"placeholder": "Suche in Menüs und Befehlen, entdecke versteckte Funktionen",
|
||||
"noMatch": "Keine passenden Befehle..."
|
||||
},
|
||||
"itemNotAvailable": "Befehl ist nicht verfügbar...",
|
||||
"shortcutHint": "Benutze {{shortcut}} für Befehlspalette"
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,19 +11,17 @@
|
||||
"copyAsPng": "Αντιγραφή στο πρόχειρο ως PNG",
|
||||
"copyAsSvg": "Αντιγραφή στο πρόχειρο ως SVG",
|
||||
"copyText": "Αντιγραφή στο πρόχειρο ως κείμενο",
|
||||
"copySource": "Αντιγραφή προέλευσης στο πρόχειρο",
|
||||
"convertToCode": "Μετατροπή σε κώδικα",
|
||||
"bringForward": "Μεταφορά μπροστά",
|
||||
"sendToBack": "Στείλ' το στο τέλος",
|
||||
"bringToFront": "Φερ' το μπροστά",
|
||||
"copySource": "",
|
||||
"convertToCode": "",
|
||||
"bringForward": "Στο προσκήνιο",
|
||||
"sendToBack": "Ένα επίπεδο πίσω",
|
||||
"bringToFront": "Ένα επίπεδο μπροστά",
|
||||
"sendBackward": "Στο παρασκήνιο",
|
||||
"delete": "Διαγραφή",
|
||||
"copyStyles": "Αντιγραφή εμφάνισης",
|
||||
"pasteStyles": "Επικόλληση εμφάνισης",
|
||||
"stroke": "Μολυβιά",
|
||||
"changeStroke": "Αλλαγή χρώματος πινελιάς",
|
||||
"background": "Φόντο",
|
||||
"changeBackground": "Αλλαγή χρώματος παρασκηνίου",
|
||||
"fill": "Γέμισμα",
|
||||
"strokeWidth": "Πάχος μολυβιάς",
|
||||
"strokeStyle": "Στυλ περιγράμματος",
|
||||
@@ -40,20 +38,12 @@
|
||||
"arrowhead_none": "Κανένα",
|
||||
"arrowhead_arrow": "Βέλος",
|
||||
"arrowhead_bar": "Μπάρα",
|
||||
"arrowhead_circle": "Κύκλος",
|
||||
"arrowhead_circle_outline": "Κύκλος (περίγραμμα)",
|
||||
"arrowhead_circle": "",
|
||||
"arrowhead_circle_outline": "",
|
||||
"arrowhead_triangle": "Τρίγωνο",
|
||||
"arrowhead_triangle_outline": "Τρίγωνο (περίγραμμα)",
|
||||
"arrowhead_diamond": "Ρόμβος",
|
||||
"arrowhead_diamond_outline": "Ρόμβος (περίγραμμα)",
|
||||
"arrowhead_crowfoot_many": "",
|
||||
"arrowhead_crowfoot_one": "",
|
||||
"arrowhead_crowfoot_one_or_many": "",
|
||||
"more_options": "",
|
||||
"arrowtypes": "Τύπος βέλους",
|
||||
"arrowtype_sharp": "Αιχμηρό βέλος",
|
||||
"arrowtype_round": "Κυρτό βέλος",
|
||||
"arrowtype_elbowed": "Γωνιακό βέλος",
|
||||
"arrowhead_triangle_outline": "",
|
||||
"arrowhead_diamond": "",
|
||||
"arrowhead_diamond_outline": "",
|
||||
"fontSize": "Μέγεθος γραμματοσειράς",
|
||||
"fontFamily": "Γραμματοσειρά",
|
||||
"addWatermark": "Προσθήκη \"Φτιαγμένο με Excalidraw\"",
|
||||
@@ -66,7 +56,7 @@
|
||||
"veryLarge": "Πολύ μεγάλο",
|
||||
"solid": "Συμπαγής",
|
||||
"hachure": "Εκκόλαψη",
|
||||
"zigzag": "Τεθλασμένη γραμμή",
|
||||
"zigzag": "",
|
||||
"crossHatch": "Διασταυρούμενη εκκόλαψη",
|
||||
"thin": "Λεπτή",
|
||||
"bold": "Έντονη",
|
||||
@@ -82,7 +72,6 @@
|
||||
"canvasColors": "Χρησιμοποείται στον καμβά",
|
||||
"canvasBackground": "Φόντο καμβά",
|
||||
"drawingCanvas": "Σχεδίαση καμβά",
|
||||
"clearCanvas": "Καθαρισμός καμβά",
|
||||
"layers": "Στρώματα",
|
||||
"actions": "Ενέργειες",
|
||||
"language": "Γλώσσα",
|
||||
@@ -95,13 +84,12 @@
|
||||
"group": "Δημιουργία ομάδας από επιλογή",
|
||||
"ungroup": "Κατάργηση ομάδας από επιλογή",
|
||||
"collaborators": "Συνεργάτες",
|
||||
"toggleGrid": "Εναλλαγή ορατότητας πλέγματος",
|
||||
"showGrid": "Προβολή πλέγματος",
|
||||
"addToLibrary": "Προσθήκη στη βιβλιοθήκη",
|
||||
"removeFromLibrary": "Αφαίρεση από τη βιβλιοθήκη",
|
||||
"libraryLoadingMessage": "Φόρτωση βιβλιοθήκης…",
|
||||
"libraries": "Άλλες βιβλιοθήκες",
|
||||
"loadingScene": "Φόρτωση σκηνής…",
|
||||
"loadScene": "Φόρτωση σκηνής από αρχείο",
|
||||
"align": "Στοίχιση",
|
||||
"alignTop": "Στοίχιση πάνω",
|
||||
"alignBottom": "Στοίχιση κάτω",
|
||||
@@ -117,33 +105,26 @@
|
||||
"share": "Κοινοποίηση",
|
||||
"showStroke": "Εμφάνιση επιλογέα χρωμάτων πινελιάς",
|
||||
"showBackground": "Εμφάνιση επιλογέα χρώματος φόντου",
|
||||
"showFonts": "Εμφάνιση επιλογέα γραμματοσειράς",
|
||||
"toggleTheme": "Εναλλαγή φωτεινού/σκοτεινού θέματος",
|
||||
"theme": "Θέμα",
|
||||
"toggleTheme": "Εναλλαγή θέματος",
|
||||
"personalLib": "Προσωπική Βιβλιοθήκη",
|
||||
"excalidrawLib": "Βιβλιοθήκη Excalidraw",
|
||||
"decreaseFontSize": "Μείωση μεγέθους γραμματοσειράς",
|
||||
"increaseFontSize": "Αύξηση μεγέθους γραμματοσειράς",
|
||||
"unbindText": "Αποσύνδεση κειμένου",
|
||||
"bindText": "Δέσμευση κειμένου στο δοχείο",
|
||||
"createContainerFromText": "Αναδίπλωση κειμένου σε δοχείο",
|
||||
"createContainerFromText": "",
|
||||
"link": {
|
||||
"edit": "Επεξεργασία συνδέσμου",
|
||||
"editEmbed": "",
|
||||
"create": "",
|
||||
"create": "Δημιουργία συνδέσμου",
|
||||
"createEmbed": "",
|
||||
"label": "Σύνδεσμος",
|
||||
"labelEmbed": "Σύνδεσμος & ενσωμάτωση",
|
||||
"empty": "Δεν έχει οριστεί σύνδεσμος",
|
||||
"hint": "",
|
||||
"goToElement": ""
|
||||
"labelEmbed": "",
|
||||
"empty": ""
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "Επεξεργασία γραμμής",
|
||||
"editArrow": "Επεξεργασία βέλους"
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"exit": "Έξοδος επεξεργαστή κειμένου"
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "Κλείδωμα",
|
||||
@@ -153,50 +134,16 @@
|
||||
},
|
||||
"statusPublished": "Δημοσιευμένο",
|
||||
"sidebarLock": "Κρατήστε την πλαϊνή μπάρα ανοιχτή",
|
||||
"selectAllElementsInFrame": "Επιλογή όλων των στοιχείων στο πλαίσιο",
|
||||
"removeAllElementsFromFrame": "Αφαίρεση όλων των στοιχείων από το πλαίσιο",
|
||||
"eyeDropper": "Διαλέξτε χρώμα απ' τον καμβά",
|
||||
"textToDiagram": "Κείμενο σε διάγραμμα",
|
||||
"prompt": "Εντολή",
|
||||
"followUs": "Ακολουθήστε μας",
|
||||
"discordChat": "Συνομιλία Discord",
|
||||
"zoomToFitViewport": "Εστίαση για να χωρέσει στο παράθυρο προβολής",
|
||||
"zoomToFitSelection": "Εστίαση για να χωρέσει στην επιλογή",
|
||||
"zoomToFit": "Εστίαση για να χωρέσει σε όλα τα στοιχεία",
|
||||
"installPWA": "Τοπική εγκατάσταση Excalidraw (PWA)",
|
||||
"autoResize": "Ενεργοποίηση αυτόματης αλλαγής μεγέθους κειμένου",
|
||||
"imageCropping": "",
|
||||
"unCroppedDimension": "",
|
||||
"copyElementLink": "",
|
||||
"linkToElement": "",
|
||||
"wrapSelectionInFrame": "",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "",
|
||||
"desc": "",
|
||||
"notFound": ""
|
||||
"selectAllElementsInFrame": "",
|
||||
"removeAllElementsFromFrame": "",
|
||||
"eyeDropper": "",
|
||||
"textToDiagram": "",
|
||||
"prompt": ""
|
||||
},
|
||||
"library": {
|
||||
"noItems": "Δεν έχουν προστεθεί αντικείμενα ακόμη...",
|
||||
"hint_emptyLibrary": "Επιλέξτε ένα στοιχείο στον καμβά για να το προσθέσετε εδώ, ή εγκαταστήστε μια βιβλιοθήκη από το δημόσιο αποθετήριο, παρακάτω.",
|
||||
"hint_emptyPrivateLibrary": "Επιλέξτε ένα στοιχείο στον καμβά για να το προσθέσετε εδώ.",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "",
|
||||
"noMatch": "",
|
||||
"singleResult": "",
|
||||
"multipleResults": "",
|
||||
"placeholder": "",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"hint_emptyPrivateLibrary": "Επιλέξτε ένα στοιχείο στον καμβά για να το προσθέσετε εδώ."
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "Επαναφορά του καμβά",
|
||||
@@ -204,7 +151,6 @@
|
||||
"exportImage": "Εξαγωγή εικόνας...",
|
||||
"export": "Αποθήκευση ως...",
|
||||
"copyToClipboard": "Αντιγραφή στο πρόχειρο",
|
||||
"copyLink": "Αντιγραφή συνδέσμου",
|
||||
"save": "Αποθήκευση στο τρέχον αρχείο",
|
||||
"saveAs": "Αποθήκευση ως",
|
||||
"load": "Άνοιγμα",
|
||||
@@ -225,19 +171,17 @@
|
||||
"fullScreen": "Πλήρης οθόνη",
|
||||
"darkMode": "Σκοτεινή λειτουργία",
|
||||
"lightMode": "Φωτεινή λειτουργία",
|
||||
"systemMode": "Λειτουργία συστήματος",
|
||||
"zenMode": "Λειτουργία Zεν",
|
||||
"objectsSnapMode": "Προσκόλληση σε αντικείμενα",
|
||||
"objectsSnapMode": "",
|
||||
"exitZenMode": "Έξοδος από την λειτουργία Zen",
|
||||
"cancel": "Ακύρωση",
|
||||
"saveLibNames": "",
|
||||
"clear": "Καθαρισμός",
|
||||
"remove": "Κατάργηση",
|
||||
"embed": "Εναλλαγή ενσωμάτωσης",
|
||||
"publishLibrary": "",
|
||||
"embed": "",
|
||||
"publishLibrary": "Δημοσίευση",
|
||||
"submit": "Υποβολή",
|
||||
"confirm": "Επιβεβαίωση",
|
||||
"embeddableInteractionButton": "Κάντε κλικ για αλληλεπίδραση"
|
||||
"embeddableInteractionButton": ""
|
||||
},
|
||||
"alerts": {
|
||||
"clearReset": "Αυτό θα σβήσει ολόκληρο τον καμβά. Είσαι σίγουρος;",
|
||||
@@ -260,39 +204,37 @@
|
||||
"resetLibrary": "Αυτό θα καθαρίσει τη βιβλιοθήκη σας. Είστε σίγουροι;",
|
||||
"removeItemsFromsLibrary": "Διαγραφή {{count}} αντικειμένου(ων) από τη βιβλιοθήκη;",
|
||||
"invalidEncryptionKey": "Το κλειδί κρυπτογράφησης πρέπει να είναι 22 χαρακτήρες. Η ζωντανή συνεργασία είναι απενεργοποιημένη.",
|
||||
"collabOfflineWarning": "Δεν υπάρχει διαθέσιμη σύνδεση στο internet.\nΟι αλλαγές σας δεν θα αποθηκευτούν!",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"collabOfflineWarning": "Δεν υπάρχει διαθέσιμη σύνδεση στο internet.\nΟι αλλαγές σας δεν θα αποθηκευτούν!"
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "Μη υποστηριζόμενος τύπος αρχείου.",
|
||||
"imageInsertError": "Αδυναμία εισαγωγής εικόνας. Προσπαθήστε ξανά αργότερα...",
|
||||
"fileTooBig": "Το αρχείο είναι πολύ μεγάλο. Το μέγιστο επιτρεπόμενο μέγεθος είναι {{maxSize}}.",
|
||||
"svgImageInsertError": "Αδυναμία εισαγωγής εικόνας SVG. Η σήμανση της SVG δεν φαίνεται έγκυρη.",
|
||||
"failedToFetchImage": "Αποτυχία ανάκτησης εικόνας.",
|
||||
"failedToFetchImage": "",
|
||||
"invalidSVGString": "Μη έγκυρο SVG.",
|
||||
"cannotResolveCollabServer": "Αδυναμία σύνδεσης με τον διακομιστή συνεργασίας. Παρακαλώ ανανεώστε τη σελίδα και προσπαθήστε ξανά.",
|
||||
"importLibraryError": "Αδυναμία φόρτωσης βιβλιοθήκης",
|
||||
"saveLibraryError": "Αδύνατη η αποθήκευση της βιβλιοθήκης στον δίσκο. Παρακαλώ αποθηκεύστε τη βιβλιοθήκη σας σε ένα αρχείο τοπικά για να βεβαιωθείτε ότι δε θα χάσετε τις αλλαγές.",
|
||||
"collabSaveFailed": "Η αποθήκευση στη βάση δεδομένων δεν ήταν δυνατή. Αν το προβλήματα παραμείνει, θα πρέπει να αποθηκεύσετε το αρχείο σας τοπικά για να βεβαιωθείτε ότι δεν χάνετε την εργασία σας.",
|
||||
"collabSaveFailed_sizeExceeded": "Η αποθήκευση στη βάση δεδομένων δεν ήταν δυνατή, ο καμβάς φαίνεται να είναι πολύ μεγάλος. Θα πρέπει να αποθηκεύσετε το αρχείο τοπικά για να βεβαιωθείτε ότι δεν θα χάσετε την εργασία σας.",
|
||||
"imageToolNotSupported": "Οι εικόνες είναι απενεργοποιημένες.",
|
||||
"imageToolNotSupported": "",
|
||||
"brave_measure_text_error": {
|
||||
"line1": "Φαίνεται ότι χρησιμοποιείτε τον περιηγητή Brave με ενεργοποιημένη τη ρύθμιση <bold>Aggressively Block Fingerprinting</bold>.",
|
||||
"line2": "Αυτό θα μπορεί να οδηγήσει στη διάλυση των <bold>Στοιχείων Κειμένου</bold> στο σχέδιό σας.",
|
||||
"line3": "Σας συνιστούμε να απενεργοποιήσετε αυτή τη ρύθμιση. Μπορείτε να ακολουθήσετε <link>αυτά τα βήματα</link> για το πώς να το κάνετε.",
|
||||
"line4": "Εάν η απενεργοποίηση αυτής της ρύθμισης δε διορθώσει την εμφάνιση των στοιχείων κειμένου, παρακαλώ ανοίξτε ένα <issueLink>θέμα</issueLink> στο GitHub, ή γράψτε μας στο <discordLink>Discord</discordLink>"
|
||||
"line1": "",
|
||||
"line2": "",
|
||||
"line3": "",
|
||||
"line4": ""
|
||||
},
|
||||
"libraryElementTypeError": {
|
||||
"embeddable": "Τα ενσωματώσιμα στοιχεία δεν μπορούν να προστεθούν στη βιβλιοθήκη.",
|
||||
"iframe": "Τα στοιχεία IFrame δεν μπορούν να προστεθούν στη βιβλιοθήκη.",
|
||||
"image": "Η υποστήριξη για προσθήκη εικόνων στη βιβλιοθήκη έρχεται σύντομα!"
|
||||
"embeddable": "",
|
||||
"iframe": "",
|
||||
"image": ""
|
||||
},
|
||||
"asyncPasteFailedOnRead": "Δεν ήταν δυνατή η επικόλληση (δεν ήταν δυνατή η ανάγνωση από το πρόχειρο του συστήματος).",
|
||||
"asyncPasteFailedOnParse": "Αδυναμία επικόλλησης.",
|
||||
"copyToSystemClipboardFailed": "Αδυναμία αντιγραφής στο πρόχειρο."
|
||||
"asyncPasteFailedOnRead": "",
|
||||
"asyncPasteFailedOnParse": "",
|
||||
"copyToSystemClipboardFailed": ""
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "Επιλογή",
|
||||
"lasso": "",
|
||||
"image": "Εισαγωγή εικόνας",
|
||||
"rectangle": "Ορθογώνιο",
|
||||
"diamond": "Ρόμβος",
|
||||
@@ -304,32 +246,16 @@
|
||||
"library": "Βιβλιοθήκη",
|
||||
"lock": "Κράτησε επιλεγμένο το εργαλείο μετά το σχέδιο",
|
||||
"penMode": "Λειτουργία μολυβιού - αποτροπή αφής",
|
||||
"link": "Προσθήκη / Ενημέρωση συνδέσμου για επιλεγμένο σχήμα",
|
||||
"link": "Προσθήκη/ Ενημέρωση συνδέσμου για ένα επιλεγμένο σχήμα",
|
||||
"eraser": "Γόμα",
|
||||
"frame": "Εργαλείο πλαισίου",
|
||||
"magicframe": "Wireframe σε κώδικα",
|
||||
"embeddable": "Web Embed",
|
||||
"laser": "Δείκτης λέιζερ",
|
||||
"hand": "Χέρι (εργαλείο μετακίνησης)",
|
||||
"extraTools": "Περισσότερα εργαλεία",
|
||||
"mermaidToExcalidraw": "Mermaid σε Excalidraw",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "Ορθογώνιο",
|
||||
"diamond": "Ρόμβος",
|
||||
"ellipse": "Έλλειψη",
|
||||
"arrow": "Βέλος",
|
||||
"line": "Γραμμή",
|
||||
"freedraw": "Ελεύθερη σχεδίαση",
|
||||
"text": "Κείμενο",
|
||||
"image": "Εικόνα",
|
||||
"group": "Ομάδα",
|
||||
"frame": "Πλαίσιο",
|
||||
"magicframe": "Wireframe σε κώδικα",
|
||||
"embeddable": "Web Embed",
|
||||
"selection": "Επιλογή",
|
||||
"iframe": "IFrame"
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"laser": "",
|
||||
"hand": "",
|
||||
"extraTools": "",
|
||||
"mermaidToExcalidraw": "",
|
||||
"magicSettings": ""
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "Ενέργειες καμβά",
|
||||
@@ -337,33 +263,28 @@
|
||||
"shapes": "Σχήματα"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"linearElement": "Κάνε κλικ για να ξεκινήσεις πολλαπλά σημεία, σύρε για μια γραμμή",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "Κάντε κλικ και σύρτε, απελευθερώσατε όταν έχετε τελειώσει",
|
||||
"text": "Tip: μπορείτε επίσης να προσθέστε κείμενο με διπλό-κλικ οπουδήποτε με το εργαλείο επιλογών",
|
||||
"embeddable": "Κάντε κλικ και σύρετε για να δημιουργήσετε μια ενσωματωμένη ιστοσελίδα",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"embeddable": "",
|
||||
"text_selected": "Κάντε διπλό κλικ ή πατήστε ENTER για να επεξεργαστείτε το κείμενο",
|
||||
"text_editing": "Πατήστε Escape ή CtrlOrCmd+ENTER για να ολοκληρώσετε την επεξεργασία",
|
||||
"linearElementMulti": "Κάνε κλικ στο τελευταίο σημείο ή πάτησε Escape ή Enter για να τελειώσεις",
|
||||
"lockAngle": "Μπορείτε να περιορίσετε τη γωνία κρατώντας πατημένο το SHIFT",
|
||||
"resize": "Μπορείς να περιορίσεις τις αναλογίες κρατώντας το SHIFT ενώ αλλάζεις μέγεθος,\nκράτησε πατημένο το ALT για αλλαγή μεγέθους από το κέντρο",
|
||||
"resizeImage": "Μπορείτε να αλλάξετε το μέγεθος ελεύθερα κρατώντας πατημένο το SHIFT,\nκρατήστε πατημένο το ALT για να αλλάξετε το μέγεθος από το κέντρο",
|
||||
"rotate": "Μπορείς να περιορίσεις τις γωνίες κρατώντας πατημένο το πλήκτρο SHIFT κατά την περιστροφή",
|
||||
"lineEditor_info": "Κρατήστε πατημένο Ctrl ή Cmd και πατήστε το πλήκτρο Ctrl ή Cmd + Enter για επεξεργασία σημείων",
|
||||
"lineEditor_pointSelected": "Πατήστε Διαγραφή για αφαίρεση σημείου(ων),\nCtrlOrCmd+D για αντιγραφή, ή σύρετε για μετακίνηση",
|
||||
"lineEditor_nothingSelected": "Επιλέξτε ένα σημείο για να επεξεργαστείτε (κρατήστε πατημένο το SHIFT για να επιλέξετε πολλαπλά),\nή κρατήστε πατημένο το Alt και κάντε κλικ για να προσθέσετε νέα σημεία",
|
||||
"placeImage": "Κάντε κλικ για να τοποθετήσετε την εικόνα ή κάντε κλικ και σύρετε για να ορίσετε το μέγεθός της χειροκίνητα",
|
||||
"publishLibrary": "Δημοσιεύστε τη δική σας βιβλιοθήκη",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"bindTextToElement": "Πατήστε Enter για προσθήκη κειμένου",
|
||||
"deepBoxSelect": "Κρατήστε πατημένο το CtrlOrCmd για να επιλέξετε βαθιά, και να αποτρέψετε τη μεταφορά",
|
||||
"eraserRevert": "Κρατήστε πατημένο το Alt για να επαναφέρετε τα στοιχεία που σημειώθηκαν για διαγραφή",
|
||||
"firefox_clipboard_write": "Αυτή η επιλογή μπορεί πιθανώς να ενεργοποιηθεί αλλάζοντας την ρύθμιση \"dom.events.asyncClipboard.clipboardItem\" σε \"true\". Για να αλλάξετε τις ρυθμίσεις του προγράμματος περιήγησης στο Firefox, επισκεφθείτε τη σελίδα \"about:config\".",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": ""
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "Αδυναμία εμφάνισης προεπισκόπησης",
|
||||
@@ -378,12 +299,9 @@
|
||||
"openIssueMessage": "Ήμασταν πολύ προσεκτικοί για να μην συμπεριλάβουμε τις πληροφορίες της σκηνής σου στο σφάλμα. Αν η σκηνή σου δεν είναι ιδιωτική, παρακαλώ σκέψου να ακολουθήσεις το δικό μας <button>ανιχνευτής σφαλμάτων.</button> Παρακαλώ να συμπεριλάβετε τις παρακάτω πληροφορίες, αντιγράφοντας και επικολλώντας το ζήτημα στο GitHub.",
|
||||
"sceneContent": "Περιεχόμενο σκηνής:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": "Ή"
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "Προσκαλέστε άτομα για να συνεργαστείτε στο σχέδιό σας.",
|
||||
"desc_privacy": "Μην ανησυχείτε, η συνεδρία είναι κρυπτογραφημένη από άκρο σε άκρο, και πλήρως ιδιωτική. Ούτε ο διακομιστής μας μπορεί να δει τι σχεδιάζετε.",
|
||||
"desc_intro": "Μπορείς να προσκαλέσεις άλλους να δουλέψουν μαζί σου.",
|
||||
"desc_privacy": "Μην ανησυχείς, η συνεδρία χρησιμοποιεί κρυπτογράφηση από σημείο σε σημείο, άρα οτιδήποτε κάνεις θα παραμείνει ανοιχτό μόνο σε εσένα. Ούτε οι μηχανές μας μπορούν να δουν τι κάνεις.",
|
||||
"button_startSession": "Έναρξη Συνεδρίας",
|
||||
"button_stopSession": "Τερματισμός Συνεδρίας",
|
||||
"desc_inProgressIntro": "Η ζωντανή συνεργασία με άλλους είναι σε ενεργή.",
|
||||
@@ -410,16 +328,14 @@
|
||||
"click": "κλικ",
|
||||
"deepSelect": "Βαθιά επιλογή",
|
||||
"deepBoxSelect": "Βαθιά επιλογή μέσα στο πλαίσιο και αποτροπή συρσίματος",
|
||||
"createFlowchart": "Δημιουργία διαγράμματος ροής από ένα γενικό στοιχείο",
|
||||
"navigateFlowchart": "Πλοήγηση σε ένα διάγραμμα ροής",
|
||||
"curvedArrow": "Κυρτό βέλος",
|
||||
"curvedLine": "Κυρτή γραμμή",
|
||||
"documentation": "Εγχειρίδιο",
|
||||
"doubleClick": "διπλό κλικ",
|
||||
"drag": "σύρε",
|
||||
"editor": "Επεξεργαστής",
|
||||
"editLineArrowPoints": "Επεξεργασία σημείων γραμμής/βέλους",
|
||||
"editText": "Επεξεργασία κειμένου / προσθήκη ετικέτας",
|
||||
"editLineArrowPoints": "",
|
||||
"editText": "",
|
||||
"github": "Βρήκατε πρόβλημα; Υποβάλετε το",
|
||||
"howto": "Ακολουθήστε τους οδηγούς μας",
|
||||
"or": "ή",
|
||||
@@ -434,9 +350,7 @@
|
||||
"zoomToSelection": "Ζουμ στην επιλογή",
|
||||
"toggleElementLock": "Κλείδωμα/Ξεκλείδωμα επιλογής",
|
||||
"movePageUpDown": "Μετακίνηση σελίδας πάνω/κάτω",
|
||||
"movePageLeftRight": "Μετακίνηση σελίδας αριστερά/δεξιά",
|
||||
"cropStart": "",
|
||||
"cropFinish": ""
|
||||
"movePageLeftRight": "Μετακίνηση σελίδας αριστερά/δεξιά"
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": "Καθαρισμός καμβά"
|
||||
@@ -445,8 +359,8 @@
|
||||
"title": "Δημοσίευση βιβλιοθήκης",
|
||||
"itemName": "Όνομα αντικειμένου",
|
||||
"authorName": "Όνομα δημιουργού",
|
||||
"githubUsername": "Όνομα χρήστη GitHub",
|
||||
"twitterUsername": "Όνομα χρήστη Twitter",
|
||||
"githubUsername": "GitHub username",
|
||||
"twitterUsername": "Twitter username",
|
||||
"libraryName": "Όνομα βιβλιοθήκης",
|
||||
"libraryDesc": "Περιγραφή βιβλιοθήκης",
|
||||
"website": "Ιστοσελίδα",
|
||||
@@ -478,27 +392,27 @@
|
||||
"removeItemsFromLib": "Αφαίρεση επιλεγμένων αντικειμένων από τη βιβλιοθήκη"
|
||||
},
|
||||
"imageExportDialog": {
|
||||
"header": "Εξαγωγή εικόνας",
|
||||
"header": "",
|
||||
"label": {
|
||||
"withBackground": "Παρασκήνιο",
|
||||
"onlySelected": "Μόνο τα επιλεγμένα",
|
||||
"darkMode": "Σκοτεινό θέμα",
|
||||
"embedScene": "Ενσωμάτωση σκηνής",
|
||||
"scale": "Κλιμάκωση",
|
||||
"padding": "Περιθώριο"
|
||||
"withBackground": "",
|
||||
"onlySelected": "",
|
||||
"darkMode": "",
|
||||
"embedScene": "",
|
||||
"scale": "",
|
||||
"padding": ""
|
||||
},
|
||||
"tooltip": {
|
||||
"embedScene": "Τα δεδομένα σκηνής θα αποθηκευτούν στο αρχείο PNG/SVG προς εξαγωγή ώστε η σκηνή να είναι δυνατό να αποκατασταθεί από αυτό.\nΘα αυξήσει το μέγεθος του αρχείου προς εξαγωγή."
|
||||
"embedScene": ""
|
||||
},
|
||||
"title": {
|
||||
"exportToPng": "Εξαγωγή σε PNG",
|
||||
"exportToSvg": "Εξαγωγή σε SVG",
|
||||
"copyPngToClipboard": "Αντιγραφή PNG στο πρόχειρο"
|
||||
"exportToPng": "",
|
||||
"exportToSvg": "",
|
||||
"copyPngToClipboard": ""
|
||||
},
|
||||
"button": {
|
||||
"exportToPng": "PNG",
|
||||
"exportToSvg": "SVG",
|
||||
"copyPngToClipboard": "Αντιγραφή στο πρόχειρο"
|
||||
"exportToPng": "",
|
||||
"exportToSvg": "",
|
||||
"copyPngToClipboard": ""
|
||||
}
|
||||
},
|
||||
"encrypted": {
|
||||
@@ -507,15 +421,13 @@
|
||||
},
|
||||
"stats": {
|
||||
"angle": "Γωνία",
|
||||
"shapes": "Σχήματα",
|
||||
"element": "Στοιχείο",
|
||||
"elements": "Στοιχεία",
|
||||
"height": "Ύψος",
|
||||
"scene": "Σκηνή",
|
||||
"selected": "Επιλεγμένα",
|
||||
"storage": "Χώρος",
|
||||
"fullTitle": "Ιδιότητες Καμβά & Σχήματος",
|
||||
"title": "Ιδιότητες",
|
||||
"generalStats": "Γενικά",
|
||||
"elementProperties": "Ιδιότητες σχήματος",
|
||||
"title": "Στατιστικά για σπασίκλες",
|
||||
"total": "Σύνολο ",
|
||||
"version": "Έκδοση",
|
||||
"versionCopy": "Κάνε κλικ για αντιγραφή",
|
||||
@@ -527,15 +439,13 @@
|
||||
"copyStyles": "Αντιγράφηκαν στυλ.",
|
||||
"copyToClipboard": "Αντιγράφηκε στο πρόχειρο.",
|
||||
"copyToClipboardAsPng": "Αντιγράφηκε {{exportSelection}} στο πρόχειρο ως PNG\n({{exportColorScheme}})",
|
||||
"copyToClipboardAsSvg": "",
|
||||
"fileSaved": "Το αρχείο αποθηκεύτηκε.",
|
||||
"fileSavedToFilename": "Αποθηκεύτηκε στο {filename}",
|
||||
"canvas": "καμβάς",
|
||||
"selection": "επιλογή",
|
||||
"pasteAsSingleElement": "Χρησιμοποίησε το {{shortcut}} για να επικολλήσεις ως ένα μόνο στοιχείο,\nή να επικολλήσεις σε έναν υπάρχοντα επεξεργαστή κειμένου",
|
||||
"unableToEmbed": "Η ενσωμάτωση αυτού του url δεν επιτρέπεται αυτήν τη στιγμή. Θέστε ένα πρόβλημα στο GitHub για να ζητήσετε το url να είναι στη λίστα των επιτρεπόμενων.",
|
||||
"unrecognizedLinkFormat": "Ο σύνδεσμος που ενσωματώσατε δεν ταιριάζει με την αναμενόμενη μορφή. Παρακαλώ προσπαθήστε να επικολλήσετε τη συμβολοσειρά 'embed' που παρέχεται από τον ιστότοπο προορισμού",
|
||||
"elementLinkCopied": ""
|
||||
"unableToEmbed": "",
|
||||
"unrecognizedLinkFormat": ""
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "Διαφανές",
|
||||
@@ -568,7 +478,6 @@
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "Πιο χρησιμοποιούμενα χρώματα",
|
||||
"colors": "Χρώματα",
|
||||
"shades": "Αποχρώσεις",
|
||||
@@ -578,87 +487,39 @@
|
||||
"overwriteConfirm": {
|
||||
"action": {
|
||||
"exportToImage": {
|
||||
"title": "Εξαγωγή ως εικόνα",
|
||||
"button": "Εξαγωγή ως εικόνα",
|
||||
"description": "Εξαγωγή δεδομένων σκηνής σε ένα αρχείο από το οποίο μπορείτε να εισάγετε αργότερα."
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
},
|
||||
"saveToDisk": {
|
||||
"title": "Αποθήκευση στο δίσκο",
|
||||
"button": "Αποθήκευση στο δίσκο",
|
||||
"description": "Εξαγωγή δεδομένων σκηνής σε ένα αρχείο από το οποίο μπορείτε να εισάγετε αργότερα."
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
},
|
||||
"excalidrawPlus": {
|
||||
"title": "Excalidraw+",
|
||||
"button": "Εξαγωγή σε Excalidraw+",
|
||||
"description": "Αποθηκεύστε τη σκηνή στο χώρο εργασίας σας Excalidraw+."
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"modal": {
|
||||
"loadFromFile": {
|
||||
"title": "Φόρτωση από αρχείο",
|
||||
"button": "Φόρτωση από αρχείο",
|
||||
"description": "Η φόρτωση από αρχείο θα <bold>αντικαταστήσει το υπάρχον περιεχόμενό σας</bold>.<br></br>Μπορείτε πρώτα να δημιουργήσετε αντίγραφα ασφαλείας του σχεδίου σας χρησιμοποιώντας μία από τις παρακάτω επιλογές."
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
},
|
||||
"shareableLink": {
|
||||
"title": "Φόρτωση από σύνδεσμο",
|
||||
"button": "Αντικατάσταση του περιεχομένου μου",
|
||||
"description": "Η φόρτωση εξωτερικού σχεδίου θα <bold>αντικαταστήσει το υπάρχον περιεχόμενο</bold>.<br></br>Μπορείτε να δημιουργήσετε αντίγραφα ασφαλείας του σχεδίου σας πρώτα χρησιμοποιώντας μία από τις παρακάτω επιλογές."
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"mermaid": {
|
||||
"title": "Mermaid σε Excalidraw",
|
||||
"button": "Εισαγωγή",
|
||||
"description": "Επί του παρόντος υποστηρίζονται μόνο Διαγράμματα <flowchartLink>Ροής</flowchartLink>,<sequenceLink> Ακολουθίας, </sequenceLink> και <classLink>Κλάσεων</classLink>. Οι άλλοι τύποι θα αποδοθούν ως εικόνα στο Excalidraw.",
|
||||
"syntax": "Σύνταξη Mermaid",
|
||||
"preview": "Προεπισκόπηση"
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": "Γρήγορη αναζήτηση"
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": "παλιό"
|
||||
},
|
||||
"sceneFonts": "Σε αυτή τη σκηνή",
|
||||
"availableFonts": "Διαθέσιμες γραμματοσειρές",
|
||||
"empty": "Δεν βρέθηκαν γραμματοσειρές"
|
||||
},
|
||||
"userList": {
|
||||
"empty": "Δεν βρέθηκαν χρήστες",
|
||||
"hint": {
|
||||
"text": "Κάντε κλικ στο χρήστη για να τον ακολουθήσετε",
|
||||
"followStatus": "Ακολουθείτε αυτόν τον χρήστη",
|
||||
"inCall": "Ο χρήστης βρίσκεται σε κλήση",
|
||||
"micMuted": "Το μικρόφωνο του χρήστη είναι σε σίγαση",
|
||||
"isSpeaking": "Ο χρήστης μιλάει"
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "Παλέτα Εντολών",
|
||||
"shortcuts": {
|
||||
"select": "Επιλογή",
|
||||
"confirm": "Επιβεβαίωση",
|
||||
"close": "Κλείσιμο"
|
||||
},
|
||||
"recents": "Πρόσφατα χρησιμοποιημένα",
|
||||
"search": {
|
||||
"placeholder": "Αναζητήστε μενού, εντολές και ανακαλύψτε κρυμμένα διαμάντια",
|
||||
"noMatch": "Δεν υπάρχουν εντολές που ταιριάζουν..."
|
||||
},
|
||||
"itemNotAvailable": "Η εντολή δεν είναι διαθέσιμη...",
|
||||
"shortcutHint": "Για την παλέτα εντολών, χρησιμοποιήστε το {{shortcut}}"
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": "",
|
||||
"syntax": "",
|
||||
"preview": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
"strokeStyle_dotted": "Dotted",
|
||||
"sloppiness": "Sloppiness",
|
||||
"opacity": "Opacity",
|
||||
"strokeType": "Stroke Type",
|
||||
"strokeWidthFixed": "Fixed width",
|
||||
"strokeWidthVariable": "Variable width",
|
||||
"textAlign": "Text align",
|
||||
"edges": "Edges",
|
||||
"sharp": "Sharp",
|
||||
|
||||
@@ -21,9 +21,7 @@
|
||||
"copyStyles": "Copiar estilos",
|
||||
"pasteStyles": "Pegar estilos",
|
||||
"stroke": "Trazo",
|
||||
"changeStroke": "Cambiar el color del trazo",
|
||||
"background": "Fondo",
|
||||
"changeBackground": "Cambiar el color de fondo",
|
||||
"fill": "Rellenar",
|
||||
"strokeWidth": "Grosor del trazo",
|
||||
"strokeStyle": "Estilo del trazo",
|
||||
@@ -46,14 +44,6 @@
|
||||
"arrowhead_triangle_outline": "Triángulo (contorno)",
|
||||
"arrowhead_diamond": "Diamante",
|
||||
"arrowhead_diamond_outline": "Diamante (contorno)",
|
||||
"arrowhead_crowfoot_many": "Pie de la corona (varios)",
|
||||
"arrowhead_crowfoot_one": "Pie de la corona (uno)",
|
||||
"arrowhead_crowfoot_one_or_many": "Pie de la corona (uno o varios)",
|
||||
"more_options": "Más opciones",
|
||||
"arrowtypes": "Tipo de flecha",
|
||||
"arrowtype_sharp": "Flecha Afilada",
|
||||
"arrowtype_round": "Flecha Curva",
|
||||
"arrowtype_elbowed": "Flecha de codo",
|
||||
"fontSize": "Tamaño de la fuente",
|
||||
"fontFamily": "Tipo de fuente",
|
||||
"addWatermark": "Agregar \"Hecho con Excalidraw\"",
|
||||
@@ -82,7 +72,6 @@
|
||||
"canvasColors": "Usado en lienzo",
|
||||
"canvasBackground": "Fondo del lienzo",
|
||||
"drawingCanvas": "Lienzo de dibujo",
|
||||
"clearCanvas": "Lona transparente",
|
||||
"layers": "Capas",
|
||||
"actions": "Acciones",
|
||||
"language": "Idioma",
|
||||
@@ -95,13 +84,12 @@
|
||||
"group": "Agrupar selección",
|
||||
"ungroup": "Desagrupar selección",
|
||||
"collaborators": "Colaboradores",
|
||||
"toggleGrid": "Alternar rejilla",
|
||||
"showGrid": "Mostrar cuadrícula",
|
||||
"addToLibrary": "Añadir a la biblioteca",
|
||||
"removeFromLibrary": "Eliminar de la biblioteca",
|
||||
"libraryLoadingMessage": "Cargando biblioteca…",
|
||||
"libraries": "Explorar bibliotecas",
|
||||
"loadingScene": "Cargando escena…",
|
||||
"loadScene": "Cargar escena desde archivo",
|
||||
"align": "Alinear",
|
||||
"alignTop": "Alineación superior",
|
||||
"alignBottom": "Alineación inferior",
|
||||
@@ -117,9 +105,7 @@
|
||||
"share": "Compartir",
|
||||
"showStroke": "Mostrar selector de color de trazo",
|
||||
"showBackground": "Mostrar el selector de color de fondo",
|
||||
"showFonts": "Mostrar selector de fuentes",
|
||||
"toggleTheme": "Cambiar tema claro/oscuro",
|
||||
"theme": "Tema",
|
||||
"toggleTheme": "Cambiar tema",
|
||||
"personalLib": "Biblioteca personal",
|
||||
"excalidrawLib": "Biblioteca Excalidraw",
|
||||
"decreaseFontSize": "Disminuir tamaño de letra",
|
||||
@@ -129,21 +115,16 @@
|
||||
"createContainerFromText": "Envolver el texto en un contenedor",
|
||||
"link": {
|
||||
"edit": "Editar enlace",
|
||||
"editEmbed": "Editar enlace incrustable",
|
||||
"create": "Añadir enlace",
|
||||
"editEmbed": "Editar enlace e incrustar",
|
||||
"create": "Crear enlace",
|
||||
"createEmbed": "Crear enlace e incrustar",
|
||||
"label": "Enlace",
|
||||
"labelEmbed": "Enlazar e incrustar",
|
||||
"empty": "No se ha establecido un enlace",
|
||||
"hint": "Escribe o pega tu enlace aquí",
|
||||
"goToElement": "Ir al elemento objetivo"
|
||||
"empty": "No se ha establecido un enlace"
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "Editar línea",
|
||||
"editArrow": "Editar flecha"
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"exit": "Salir del editor en línea"
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "Bloquear",
|
||||
@@ -157,46 +138,12 @@
|
||||
"removeAllElementsFromFrame": "Eliminar todos los elementos del marco",
|
||||
"eyeDropper": "Seleccionar un color del lienzo",
|
||||
"textToDiagram": "Texto a diagrama",
|
||||
"prompt": "Prompt",
|
||||
"followUs": "Síguenos",
|
||||
"discordChat": "Chat de Discord",
|
||||
"zoomToFitViewport": "Zoom para encajar en la ventana",
|
||||
"zoomToFitSelection": "Zoom para ajustar la selección",
|
||||
"zoomToFit": "Zoom para mostrar todos los elementos",
|
||||
"installPWA": "Instalar Excalidraw localmente (PWA)",
|
||||
"autoResize": "Activar redimensionado automático de texto",
|
||||
"imageCropping": "Recortar imagen",
|
||||
"unCroppedDimension": "Dimensión no recortada",
|
||||
"copyElementLink": "Copiar enlace al objeto",
|
||||
"linkToElement": "Enlace al objeto",
|
||||
"wrapSelectionInFrame": "Ajustar la selección en el marco",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "Enlace al objeto",
|
||||
"desc": "Haga clic en una forma en lienzo o pegue un enlace.",
|
||||
"notFound": "El objeto vinculado no se encontró en el lienzo."
|
||||
"prompt": "Sugerencia"
|
||||
},
|
||||
"library": {
|
||||
"noItems": "No hay elementos añadidos todavía...",
|
||||
"hint_emptyLibrary": "Seleccione un elemento en el lienzo para añadirlo aquí, o instale una biblioteca del repositorio público, a continuación.",
|
||||
"hint_emptyPrivateLibrary": "Seleccione un elemento del lienzo para añadirlo aquí.",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "Encontrar en lienzo",
|
||||
"noMatch": "No hay coincidencias...",
|
||||
"singleResult": "resultado",
|
||||
"multipleResults": "resultados",
|
||||
"placeholder": "Encontrar texto en lienzo...",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"hint_emptyPrivateLibrary": "Seleccione un elemento del lienzo para añadirlo aquí."
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "Limpiar lienzo y reiniciar el color de fondo",
|
||||
@@ -204,7 +151,6 @@
|
||||
"exportImage": "Exportar imagen...",
|
||||
"export": "Guardar en...",
|
||||
"copyToClipboard": "Copiar al portapapeles",
|
||||
"copyLink": "Copiar enlace",
|
||||
"save": "Guardar en archivo actual",
|
||||
"saveAs": "Guardar como",
|
||||
"load": "Abrir",
|
||||
@@ -225,16 +171,14 @@
|
||||
"fullScreen": "Pantalla completa",
|
||||
"darkMode": "Modo oscuro",
|
||||
"lightMode": "Modo claro",
|
||||
"systemMode": "Modo del sistema",
|
||||
"zenMode": "Modo Zen",
|
||||
"objectsSnapMode": "Ajustar a los objetos",
|
||||
"exitZenMode": "Salir del modo Zen",
|
||||
"cancel": "Cancelar",
|
||||
"saveLibNames": "",
|
||||
"clear": "Borrar",
|
||||
"remove": "Eliminar",
|
||||
"embed": "Alternar incrustación",
|
||||
"publishLibrary": "",
|
||||
"embed": "",
|
||||
"publishLibrary": "Publicar",
|
||||
"submit": "Enviar",
|
||||
"confirm": "Confirmar",
|
||||
"embeddableInteractionButton": "Pulsa para interactuar"
|
||||
@@ -260,8 +204,7 @@
|
||||
"resetLibrary": "Esto borrará tu biblioteca. ¿Estás seguro?",
|
||||
"removeItemsFromsLibrary": "¿Eliminar {{count}} elemento(s) de la biblioteca?",
|
||||
"invalidEncryptionKey": "La clave de cifrado debe tener 22 caracteres. La colaboración en vivo está deshabilitada.",
|
||||
"collabOfflineWarning": "No hay conexión a internet disponible.\n¡No se guardarán los cambios!",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"collabOfflineWarning": "No hay conexión a internet disponible.\n¡No se guardarán los cambios!"
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "Tipo de archivo no admitido.",
|
||||
@@ -269,22 +212,22 @@
|
||||
"fileTooBig": "Archivo demasiado grande. El tamaño máximo permitido es {{maxSize}}.",
|
||||
"svgImageInsertError": "No se pudo insertar la imagen SVG. El código SVG parece inválido.",
|
||||
"failedToFetchImage": "Error al obtener la imagen.",
|
||||
"invalidSVGString": "SVG no válido.",
|
||||
"cannotResolveCollabServer": "No se pudo conectar al servidor colaborador. Por favor, vuelva a cargar la página y vuelva a intentarlo.",
|
||||
"importLibraryError": "No se pudo cargar la librería",
|
||||
"saveLibraryError": "No se pudo guardar la biblioteca en el almacenamiento. Por favor, guarde su biblioteca en un archivo localmente para asegurarse de que no pierde los cambios.",
|
||||
"collabSaveFailed": "No se pudo guardar en la base de datos del backend. Si los problemas persisten, debería guardar su archivo localmente para asegurarse de que no pierde su trabajo.",
|
||||
"collabSaveFailed_sizeExceeded": "No se pudo guardar en la base de datos del backend, el lienzo parece ser demasiado grande. Debería guardar el archivo localmente para asegurarse de que no pierde su trabajo.",
|
||||
"imageToolNotSupported": "Las imágenes están desactivadas.",
|
||||
"imageToolNotSupported": "",
|
||||
"brave_measure_text_error": {
|
||||
"line1": "Parece que estás usando el navegador Brave con el ajuste <bold>Forzar el bloqueo de huellas digitales</bold> habilitado.",
|
||||
"line2": "Esto podría resultar en errores en los <bold>Elementos de Texto</bold> en tus dibujos.",
|
||||
"line3": "Recomendamos fuertemente deshabilitar esta configuración. Puedes seguir <link>estos pasos</link> sobre cómo hacerlo.",
|
||||
"line4": "Si deshabilitar esta opción no arregla la visualización de elementos conformados por texto, por favor abre un <issueLink>problema</issueLink> en nuestro GitHub o escríbanos en <discordLink>Discord</discordLink>"
|
||||
"line4": ""
|
||||
},
|
||||
"libraryElementTypeError": {
|
||||
"embeddable": "Los elementos incrustables no pueden ser añadidos a la biblioteca.",
|
||||
"embeddable": "",
|
||||
"iframe": "Los elementos IFrame no se pueden agregar a la biblioteca.",
|
||||
"image": "¡Soporte para añadir imágenes a la biblioteca muy pronto!"
|
||||
"image": ""
|
||||
},
|
||||
"asyncPasteFailedOnRead": "No se pudo pegar (no se pudo leer desde el portapapeles del sistema).",
|
||||
"asyncPasteFailedOnParse": "No se pudo pegar.",
|
||||
@@ -292,7 +235,6 @@
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "Selección",
|
||||
"lasso": "",
|
||||
"image": "Insertar imagen",
|
||||
"rectangle": "Rectángulo",
|
||||
"diamond": "Diamante",
|
||||
@@ -306,30 +248,14 @@
|
||||
"penMode": "Modo Lápiz - previene toque",
|
||||
"link": "Añadir/Actualizar enlace para una forma seleccionada",
|
||||
"eraser": "Borrar",
|
||||
"frame": "Herramienta Estructura",
|
||||
"frame": "",
|
||||
"magicframe": "Esquema a código",
|
||||
"embeddable": "Incrustar Web",
|
||||
"laser": "Puntero láser",
|
||||
"hand": "Mano (herramienta de panoramización)",
|
||||
"extraTools": "Más herramientas",
|
||||
"mermaidToExcalidraw": "Mermaid a Excalidraw",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "Rectángulo",
|
||||
"diamond": "Rombo",
|
||||
"ellipse": "Elipse",
|
||||
"arrow": "Flecha",
|
||||
"line": "Línea",
|
||||
"freedraw": "Dibujar a mano",
|
||||
"text": "Texto",
|
||||
"image": "Imagen",
|
||||
"group": "Grupo",
|
||||
"frame": "Marco",
|
||||
"magicframe": "Esquema a código",
|
||||
"embeddable": "Incrustar Web",
|
||||
"selection": "Selección",
|
||||
"iframe": "IFrame"
|
||||
"magicSettings": "Ajustes AI"
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "Acciones del lienzo",
|
||||
@@ -337,33 +263,28 @@
|
||||
"shapes": "Formas"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"canvasPanning": "Para mover el lienzo, mantenga la rueda del ratón o la barra espaciadora mientras arrastra o utilice la herramienta de mano",
|
||||
"linearElement": "Haz clic para dibujar múltiples puntos, arrastrar para solo una línea",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "Haz clic y arrastra, suelta al terminar",
|
||||
"text": "Consejo: también puedes añadir texto haciendo doble clic en cualquier lugar con la herramienta de selección",
|
||||
"embeddable": "Haga clic y arrastre para crear un sitio web incrustado",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"text_selected": "Doble clic o pulse ENTER para editar el texto",
|
||||
"text_editing": "Pulse Escape o Ctrl/Cmd + ENTER para terminar de editar",
|
||||
"linearElementMulti": "Haz clic en el último punto o presiona Escape o Enter para finalizar",
|
||||
"lockAngle": "Puedes restringir el ángulo manteniendo presionado el botón SHIFT",
|
||||
"resize": "Para mantener las proporciones mantén SHIFT presionado mientras modificas el tamaño, \nmantén presionado ALT para modificar el tamaño desde el centro",
|
||||
"resizeImage": "Puede redimensionar libremente pulsando SHIFT,\npulse ALT para redimensionar desde el centro",
|
||||
"rotate": "Puedes restringir los ángulos manteniendo presionado SHIFT mientras giras",
|
||||
"lineEditor_info": "Mantenga pulsado CtrlOrCmd y haga doble click o presione CtrlOrCmd + Enter para editar puntos",
|
||||
"lineEditor_pointSelected": "Presione Suprimir para eliminar el/los punto(s), CtrlOrCmd+D para duplicarlo, o arrástrelo para moverlo",
|
||||
"lineEditor_nothingSelected": "Seleccione un punto a editar (mantenga MAYÚSCULAS para seleccionar múltiples),\no mantenga pulsado Alt y haga click para añadir nuevos puntos",
|
||||
"placeImage": "Haga clic para colocar la imagen o haga click y arrastre para establecer su tamaño manualmente",
|
||||
"publishLibrary": "Publica tu propia biblioteca",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"bindTextToElement": "Presione Entrar para agregar",
|
||||
"deepBoxSelect": "Mantén CtrlOrCmd para seleccionar en profundidad, y para evitar arrastrar",
|
||||
"eraserRevert": "Mantenga pulsado Alt para revertir los elementos marcados para su eliminación",
|
||||
"firefox_clipboard_write": "Esta característica puede ser habilitada estableciendo la bandera \"dom.events.asyncClipboard.clipboardItem\" a \"true\". Para cambiar las banderas del navegador en Firefox, visite la página \"about:config\".",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": "Mantén pulsado CtrlOrCmd para desactivar el ajuste"
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "No se puede mostrar la vista previa",
|
||||
@@ -378,12 +299,9 @@
|
||||
"openIssueMessage": "Fuimos muy cautelosos de no incluir la información de tu escena en el error. Si tu escena no es privada, por favor considera seguir nuestro <button>rastreador de errores.</button> Por favor, incluya la siguiente información copiándola y pegándola en el issue de GitHub.",
|
||||
"sceneContent": "Contenido de la escena:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": "O"
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "Invita a gente a colaborar en tu dibujo.",
|
||||
"desc_privacy": "No te preocupes, la sesión está encriptada de extremo a extremo y es totalmente privada. Ni siquiera nuestro servidor puede ver lo que dibujas.",
|
||||
"desc_intro": "Puede invitar a otras personas a tu actual escena para que colaboren contigo.",
|
||||
"desc_privacy": "No te preocupes, la sesión usa encriptación de punta a punta, por lo que todo lo que se dibuje se mantendrá privadamente. Ni siquiera nuestro servidor podrá ver lo que haces.",
|
||||
"button_startSession": "Iniciar sesión",
|
||||
"button_stopSession": "Detener sesión",
|
||||
"desc_inProgressIntro": "La sesión de colaboración en vivo está ahora en progreso.",
|
||||
@@ -407,11 +325,9 @@
|
||||
},
|
||||
"helpDialog": {
|
||||
"blog": "Lea nuestro blog",
|
||||
"click": "clic",
|
||||
"click": "click",
|
||||
"deepSelect": "Selección profunda",
|
||||
"deepBoxSelect": "Seleccione en profundidad dentro de la caja, y evite arrastrar",
|
||||
"createFlowchart": "Crear un diagrama de flujo a partir de un elemento genérico",
|
||||
"navigateFlowchart": "Navegar un diagrama de flujo",
|
||||
"curvedArrow": "Flecha curva",
|
||||
"curvedLine": "Línea curva",
|
||||
"documentation": "Documentación",
|
||||
@@ -434,9 +350,7 @@
|
||||
"zoomToSelection": "Ampliar selección",
|
||||
"toggleElementLock": "Bloquear/desbloquear selección",
|
||||
"movePageUpDown": "Mover página hacia arriba/abajo",
|
||||
"movePageLeftRight": "Mover página hacia la izquierda/derecha",
|
||||
"cropStart": "Recortar imagen",
|
||||
"cropFinish": "Terminar recorte de imagen"
|
||||
"movePageLeftRight": "Mover página hacia la izquierda/derecha"
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": "Borrar lienzo"
|
||||
@@ -488,7 +402,7 @@
|
||||
"padding": "Espaciado"
|
||||
},
|
||||
"tooltip": {
|
||||
"embedScene": "Los datos de la escena se guardarán en el archivo PNG/SVG exportado, así la escena puede ser restaurada desde la misma. Esto acción aumentará el tamaño del archivo exportado."
|
||||
"embedScene": ""
|
||||
},
|
||||
"title": {
|
||||
"exportToPng": "Exportar a PNG",
|
||||
@@ -507,15 +421,13 @@
|
||||
},
|
||||
"stats": {
|
||||
"angle": "Ángulo",
|
||||
"shapes": "Formas",
|
||||
"element": "Elemento",
|
||||
"elements": "Elementos",
|
||||
"height": "Alto",
|
||||
"scene": "Escena",
|
||||
"selected": "Seleccionado",
|
||||
"storage": "Almacenamiento",
|
||||
"fullTitle": "Propiedades del Lienzo y Forma",
|
||||
"title": "Propiedades",
|
||||
"generalStats": "General",
|
||||
"elementProperties": "Propiedades de forma",
|
||||
"title": "Estadísticas para nerds",
|
||||
"total": "Total",
|
||||
"version": "Versión",
|
||||
"versionCopy": "Click para copiar",
|
||||
@@ -527,15 +439,13 @@
|
||||
"copyStyles": "Estilos copiados.",
|
||||
"copyToClipboard": "Copiado en el portapapeles.",
|
||||
"copyToClipboardAsPng": "Copiado {{exportSelection}} al portapapeles como PNG\n({{exportColorScheme}})",
|
||||
"copyToClipboardAsSvg": "Copiado {{exportSelection}} al portapapeles como PNG\n({{exportColorScheme}})",
|
||||
"fileSaved": "Archivo guardado.",
|
||||
"fileSavedToFilename": "Guardado en {filename}",
|
||||
"canvas": "lienzo",
|
||||
"selection": "selección",
|
||||
"pasteAsSingleElement": "Usa {{shortcut}} para pegar como un solo elemento,\no pegar en un editor de texto existente",
|
||||
"unableToEmbed": "Incorporar esta url no está permitido actualmente. Señale esta incidencia en nuestro GitHub para solicitar que esta url esté entre las permitidas",
|
||||
"unrecognizedLinkFormat": "El enlace que incrustó no coincide con el formato esperado. Por favor intente pegar la cadena 'embed' proporcionada por el sitio de origen",
|
||||
"elementLinkCopied": "Enlace copiado al portapapeles"
|
||||
"unableToEmbed": "",
|
||||
"unrecognizedLinkFormat": ""
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "Transparente",
|
||||
@@ -568,19 +478,18 @@
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "Colores personalizados más utilizados",
|
||||
"colors": "Colores",
|
||||
"shades": "Sombras",
|
||||
"shades": "",
|
||||
"hexCode": "Código Hexadecimal",
|
||||
"noShades": "No hay sombras disponibles para este color"
|
||||
"noShades": ""
|
||||
},
|
||||
"overwriteConfirm": {
|
||||
"action": {
|
||||
"exportToImage": {
|
||||
"title": "Exportar como imagen",
|
||||
"button": "Exportar como imagen",
|
||||
"description": "Exporta los datos de la escena como una imagen desde el cual podrás importarlo más tarde."
|
||||
"description": ""
|
||||
},
|
||||
"saveToDisk": {
|
||||
"title": "Guardar en el disco",
|
||||
@@ -588,16 +497,16 @@
|
||||
"description": "Exporta los datos de la escena a un archivo desde el cual podrás importar más tarde."
|
||||
},
|
||||
"excalidrawPlus": {
|
||||
"title": "Excalidraw+",
|
||||
"title": "",
|
||||
"button": "Exportar a Excalidraw+",
|
||||
"description": "Guarda la escena en su espacio de trabajo de Excalidraw+."
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"modal": {
|
||||
"loadFromFile": {
|
||||
"title": "Cargar desde un archivo",
|
||||
"button": "Cargar desde un archivo",
|
||||
"description": "Cargando desde un archivo <bold>reemplazará tu contenido actual</bold> <br></br>Puedes primero hacer una copia de seguridad usando una de las siguientes opciones."
|
||||
"description": ""
|
||||
},
|
||||
"shareableLink": {
|
||||
"title": "Cargar desde un enlace",
|
||||
@@ -609,56 +518,8 @@
|
||||
"mermaid": {
|
||||
"title": "Mermaid a Excalidraw",
|
||||
"button": "Insertar",
|
||||
"description": "Actualmente sólo estos tipos de <flowchartLink>diagrama de flujo</flowchartLink>,<sequenceLink> Secuencia, </sequenceLink> y <classLink>Clase </classLink> son soportados. Los otros tipos de diagramas se renderizarán como imagen en Excalidraw.",
|
||||
"description": "Actualmente sólo <flowchartLink>Flowchart</flowchartLink>,<sequenceLink> Secuencia, </sequenceLink> y <classLink>Class </classLink>Diagramas son soportados. Los otros tipos se renderizarán como imagen en Excalidraw.",
|
||||
"syntax": "Sintaxis Mermaid",
|
||||
"preview": "Vista previa"
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": "Búsqueda rápida"
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": "viejo"
|
||||
},
|
||||
"sceneFonts": "En esta escena",
|
||||
"availableFonts": "Fuentes disponibles",
|
||||
"empty": "No se han encontrado fuentes"
|
||||
},
|
||||
"userList": {
|
||||
"empty": "No se han encontrado usuarios",
|
||||
"hint": {
|
||||
"text": "Haga clic en el usuario para seguir",
|
||||
"followStatus": "Ya estás siguiendo a este usuario",
|
||||
"inCall": "El usuario está en una llamada de voz",
|
||||
"micMuted": "El micrófono del usuario está silenciado",
|
||||
"isSpeaking": "El usuario está hablando"
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "Paleta de comandos",
|
||||
"shortcuts": {
|
||||
"select": "Seleccionar",
|
||||
"confirm": "Confirmar",
|
||||
"close": "Cerrar"
|
||||
},
|
||||
"recents": "Usado recientemente",
|
||||
"search": {
|
||||
"placeholder": "Busca menús, comandos y descubre gemas ocultas",
|
||||
"noMatch": "No hay comandos coincidentes..."
|
||||
},
|
||||
"itemNotAvailable": "Comando no disponible...",
|
||||
"shortcutHint": "Para la paleta de comandos, utilice {{shortcut}}"
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"copyAsPng": "Kopiatu arbelera PNG gisa",
|
||||
"copyAsSvg": "Kopiatu arbelera SVG gisa",
|
||||
"copyText": "Kopiatu arbelera testu gisa",
|
||||
"copySource": "Kopiatu jatorria arbelean",
|
||||
"convertToCode": "Kodera bihurtu",
|
||||
"copySource": "Kopiatu iturria arbelean",
|
||||
"convertToCode": "Bihurtu kodea",
|
||||
"bringForward": "Ekarri aurrerago",
|
||||
"sendToBack": "Eraman atzera",
|
||||
"bringToFront": "Ekarri aurrera",
|
||||
@@ -21,9 +21,7 @@
|
||||
"copyStyles": "Kopiatu estiloak",
|
||||
"pasteStyles": "Itsatsi estiloak",
|
||||
"stroke": "Marra",
|
||||
"changeStroke": "Marraren kolorea aldatu",
|
||||
"background": "Atzeko planoa",
|
||||
"changeBackground": "Atzealdeko kolorea aldatu",
|
||||
"fill": "Bete",
|
||||
"strokeWidth": "Marraren zabalera",
|
||||
"strokeStyle": "Marraren estiloa",
|
||||
@@ -40,20 +38,12 @@
|
||||
"arrowhead_none": "Bat ere ez",
|
||||
"arrowhead_arrow": "Gezia",
|
||||
"arrowhead_bar": "Barra",
|
||||
"arrowhead_circle": "Zirkulua",
|
||||
"arrowhead_circle_outline": "Zirkulua (eskema)",
|
||||
"arrowhead_circle": "",
|
||||
"arrowhead_circle_outline": "",
|
||||
"arrowhead_triangle": "Hirukia",
|
||||
"arrowhead_triangle_outline": "Triangelua (eskema)",
|
||||
"arrowhead_diamond": "Erromboa",
|
||||
"arrowhead_diamond_outline": "Erromboa (eskema)",
|
||||
"arrowhead_crowfoot_many": "",
|
||||
"arrowhead_crowfoot_one": "",
|
||||
"arrowhead_crowfoot_one_or_many": "",
|
||||
"more_options": "",
|
||||
"arrowtypes": "",
|
||||
"arrowtype_sharp": "",
|
||||
"arrowtype_round": "",
|
||||
"arrowtype_elbowed": "",
|
||||
"arrowhead_triangle_outline": "",
|
||||
"arrowhead_diamond": "",
|
||||
"arrowhead_diamond_outline": "",
|
||||
"fontSize": "Letra-tamaina",
|
||||
"fontFamily": "Letra-tipoa",
|
||||
"addWatermark": "Gehitu \"Excalidraw bidez egina\"",
|
||||
@@ -82,7 +72,6 @@
|
||||
"canvasColors": "Oihalean erabilita",
|
||||
"canvasBackground": "Oihalaren atzeko planoa",
|
||||
"drawingCanvas": "Marrazteko oihala",
|
||||
"clearCanvas": "Garbitu",
|
||||
"layers": "Geruzak",
|
||||
"actions": "Ekintzak",
|
||||
"language": "Hizkuntza",
|
||||
@@ -95,13 +84,12 @@
|
||||
"group": "Hautapena taldea bihurtu",
|
||||
"ungroup": "Desegin hautapenaren taldea",
|
||||
"collaborators": "Kolaboratzaileak",
|
||||
"toggleGrid": "Txandakatu sareta",
|
||||
"showGrid": "Erakutsi sareta",
|
||||
"addToLibrary": "Gehitu liburutegira",
|
||||
"removeFromLibrary": "Kendu liburutegitik",
|
||||
"libraryLoadingMessage": "Liburutegia kargatzen…",
|
||||
"libraries": "Arakatu liburutegiak",
|
||||
"loadingScene": "Eszena kargatzen…",
|
||||
"loadScene": "Fitxategitik kargatu",
|
||||
"align": "Lerrokatu",
|
||||
"alignTop": "Lerrokatu goian",
|
||||
"alignBottom": "Lerrokatu behean",
|
||||
@@ -117,9 +105,7 @@
|
||||
"share": "Partekatu",
|
||||
"showStroke": "Erakutsi marraren kolore-hautatzailea",
|
||||
"showBackground": "Erakutsi atzeko planoaren kolore-hautatzailea",
|
||||
"showFonts": "",
|
||||
"toggleTheme": "Gaia argia/iluna aktibatu",
|
||||
"theme": "Itxura",
|
||||
"toggleTheme": "Aldatu gaia",
|
||||
"personalLib": "Liburutegi pertsonala",
|
||||
"excalidrawLib": "Excalidraw liburutegia",
|
||||
"decreaseFontSize": "Txikitu letra tamaina",
|
||||
@@ -129,21 +115,16 @@
|
||||
"createContainerFromText": "Bilatu testua edukiontzi batean",
|
||||
"link": {
|
||||
"edit": "Editatu esteka",
|
||||
"editEmbed": "",
|
||||
"create": "",
|
||||
"editEmbed": "Editatu esteka eta kapsulatu",
|
||||
"create": "Sortu esteka",
|
||||
"createEmbed": "Sortu esteka eta kapsulatu",
|
||||
"label": "Esteka",
|
||||
"labelEmbed": "Esteka eta kapsula",
|
||||
"empty": "Ez da estekarik ezarri",
|
||||
"hint": "",
|
||||
"goToElement": ""
|
||||
"empty": "Ez da estekarik ezarri"
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "Editatu lerroa",
|
||||
"editArrow": "Gezia aldatu"
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"exit": "Irten lerro-editoretik"
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "Blokeatu",
|
||||
@@ -157,46 +138,12 @@
|
||||
"removeAllElementsFromFrame": "Kendu markoko elementu guztiak",
|
||||
"eyeDropper": "Aukeratu kolorea oihaletik",
|
||||
"textToDiagram": "Testutik diagramara",
|
||||
"prompt": "Galdetu",
|
||||
"followUs": "Jarraitu gaitzazu",
|
||||
"discordChat": "Discord txata",
|
||||
"zoomToFitViewport": "Zoom ikuspegira",
|
||||
"zoomToFitSelection": "Zoom hautapenera",
|
||||
"zoomToFit": "Egin zoom elementu guztiak ikusteko",
|
||||
"installPWA": "Instalatu Excalidraw lokalean (PWA)",
|
||||
"autoResize": "Textu zabalera automatikoa aktibatu",
|
||||
"imageCropping": "",
|
||||
"unCroppedDimension": "",
|
||||
"copyElementLink": "",
|
||||
"linkToElement": "",
|
||||
"wrapSelectionInFrame": "",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "",
|
||||
"desc": "",
|
||||
"notFound": ""
|
||||
"prompt": ""
|
||||
},
|
||||
"library": {
|
||||
"noItems": "Oraindik ez da elementurik gehitu...",
|
||||
"hint_emptyLibrary": "Hautatu oihaleko elementu bat hemen gehitzeko, edo instalatu liburutegi bat beheko biltegi publikotik.",
|
||||
"hint_emptyPrivateLibrary": "Hautatu oihaleko elementu bat hemen gehitzeko.",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "",
|
||||
"noMatch": "",
|
||||
"singleResult": "",
|
||||
"multipleResults": "",
|
||||
"placeholder": "",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"hint_emptyPrivateLibrary": "Hautatu oihaleko elementu bat hemen gehitzeko."
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "Garbitu oihala",
|
||||
@@ -204,7 +151,6 @@
|
||||
"exportImage": "Esportatu irudia...",
|
||||
"export": "Gorde hemen...",
|
||||
"copyToClipboard": "Kopiatu arbelera",
|
||||
"copyLink": "",
|
||||
"save": "Gorde uneko fitxategian",
|
||||
"saveAs": "Gorde honela",
|
||||
"load": "Ireki",
|
||||
@@ -225,16 +171,14 @@
|
||||
"fullScreen": "Pantaila osoa",
|
||||
"darkMode": "Modu iluna",
|
||||
"lightMode": "Modu argia",
|
||||
"systemMode": "",
|
||||
"zenMode": "Zen modua",
|
||||
"objectsSnapMode": "Atxiki objektuei",
|
||||
"exitZenMode": "Irten Zen modutik",
|
||||
"cancel": "Utzi",
|
||||
"saveLibNames": "",
|
||||
"clear": "Garbitu",
|
||||
"remove": "Kendu",
|
||||
"embed": "Aldatu kapsulatzea",
|
||||
"publishLibrary": "",
|
||||
"publishLibrary": "Argitaratu",
|
||||
"submit": "Bidali",
|
||||
"confirm": "Bai",
|
||||
"embeddableInteractionButton": "Egin klik elkar eragiteko"
|
||||
@@ -260,8 +204,7 @@
|
||||
"resetLibrary": "Honek zure liburutegia garbituko du. Ziur zaude?",
|
||||
"removeItemsFromsLibrary": "Liburutegitik {{count}} elementu ezabatu?",
|
||||
"invalidEncryptionKey": "Enkriptazio-gakoak 22 karaktere izan behar ditu. Zuzeneko lankidetza desgaituta dago.",
|
||||
"collabOfflineWarning": "Ez dago Interneteko konexiorik.\nZure aldaketak ez dira gordeko!",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"collabOfflineWarning": "Ez dago Interneteko konexiorik.\nZure aldaketak ez dira gordeko!"
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "Onartu gabeko fitxategi mota.",
|
||||
@@ -269,12 +212,12 @@
|
||||
"fileTooBig": "Fitxategia handiegia da. Onartutako gehienezko tamaina {{maxSize}} da.",
|
||||
"svgImageInsertError": "Ezin izan da SVG irudia txertatu. SVG markak baliogabea dirudi.",
|
||||
"failedToFetchImage": "Ezin izan da irudia eskuratu.",
|
||||
"invalidSVGString": "SVG baliogabea.",
|
||||
"cannotResolveCollabServer": "Ezin izan da elkarlaneko zerbitzarira konektatu. Mesedez, berriro kargatu orria eta saiatu berriro.",
|
||||
"importLibraryError": "Ezin izan da liburutegia kargatu",
|
||||
"saveLibraryError": "Ezin izan da liburutegian gorde. Mesedez, gorde fitxategi lokal batetara aldaketarik ez galtzeko.",
|
||||
"collabSaveFailed": "Ezin izan da backend datu-basean gorde. Arazoak jarraitzen badu, zure fitxategia lokalean gorde beharko zenuke zure lana ez duzula galtzen ziurtatzeko.",
|
||||
"collabSaveFailed_sizeExceeded": "Ezin izan da backend datu-basean gorde, ohiala handiegia dela dirudi. Fitxategia lokalean gorde beharko zenuke zure lana galtzen ez duzula ziurtatzeko.",
|
||||
"imageToolNotSupported": "Irudiak desgaituak daude.",
|
||||
"imageToolNotSupported": "Irudiak desgaituta daude.",
|
||||
"brave_measure_text_error": {
|
||||
"line1": "Brave arakatzailea erabiltzen ari zarela dirudi <bold>Blokeatu hatz-markak erasokorki</bold> ezarpena gaituta.",
|
||||
"line2": "Honek zure marrazkietako <bold>Testu-elementuak</bold> hautsi ditzake.",
|
||||
@@ -283,7 +226,7 @@
|
||||
},
|
||||
"libraryElementTypeError": {
|
||||
"embeddable": "Kapsulatutako elementuak ezin dira liburutegira gehitu.",
|
||||
"iframe": "Kapsulatutako elementuak ezin dira liburutegira gehitu.",
|
||||
"iframe": "IFrame elementuak ezin dira liburutegira gehitu.",
|
||||
"image": "Laster egongo da irudiak liburutegian gehitzeko laguntza!"
|
||||
},
|
||||
"asyncPasteFailedOnRead": "Ezin izan da itsatsi (ezin izan da sistemaren arbeletik irakurri).",
|
||||
@@ -292,7 +235,6 @@
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "Hautapena",
|
||||
"lasso": "",
|
||||
"image": "Txertatu irudia",
|
||||
"rectangle": "Laukizuzena",
|
||||
"diamond": "Diamantea",
|
||||
@@ -307,29 +249,13 @@
|
||||
"link": "Gehitu / Eguneratu esteka hautatutako forma baterako",
|
||||
"eraser": "Borragoma",
|
||||
"frame": "Marko tresna",
|
||||
"magicframe": "Wireframetik kodera",
|
||||
"magicframe": "Wireframe kodetzeko",
|
||||
"embeddable": "Web kapsulatzea",
|
||||
"laser": "Laser punteroa",
|
||||
"hand": "Eskua (panoratze tresna)",
|
||||
"extraTools": "Tresna gehiago",
|
||||
"mermaidToExcalidraw": "Mermaid-etik Excalidraw-ra",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "",
|
||||
"diamond": "",
|
||||
"ellipse": "",
|
||||
"arrow": "",
|
||||
"line": "",
|
||||
"freedraw": "",
|
||||
"text": "",
|
||||
"image": "",
|
||||
"group": "",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"selection": "",
|
||||
"iframe": ""
|
||||
"mermaidToExcalidraw": "",
|
||||
"magicSettings": "AI ezarpenak"
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "Canvas ekintzak",
|
||||
@@ -337,33 +263,28 @@
|
||||
"shapes": "Formak"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"canvasPanning": "Oihala mugitzeko, eutsi saguaren gurpila edo zuriune-barra arrastatzean, edo erabili esku tresna",
|
||||
"linearElement": "Egin klik hainbat puntu hasteko, arrastatu lerro bakarrerako",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "Egin klik eta arrastatu, askatu amaitutakoan",
|
||||
"text": "Aholkua: testua gehitu dezakezu edozein lekutan klik bikoitza eginez hautapen tresnarekin",
|
||||
"embeddable": "Egin klik eta arrastatu webgunea kapsulatzeko",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"text_selected": "Egin klik bikoitza edo sakatu SARTU testua editatzeko",
|
||||
"text_editing": "Sakatu Esc edo Ctrl+SARTU editatzen amaitzeko",
|
||||
"linearElementMulti": "Egin klik azken puntuan edo sakatu Esc edo Sartu amaitzeko",
|
||||
"lockAngle": "SHIFT sakatuta angelua mantendu dezakezu",
|
||||
"resize": "Proportzioak mantendu ditzakezu SHIFT sakatuta tamaina aldatzen duzun bitartean.\nsakatu ALT erditik tamaina aldatzeko",
|
||||
"resizeImage": "Tamaina libreki alda dezakezu SHIFT sakatuta,\nsakatu ALT erditik tamaina aldatzeko",
|
||||
"rotate": "Angeluak mantendu ditzakezu SHIFT sakatuta biratzen duzun bitartean",
|
||||
"lineEditor_info": "Eutsi sakatuta Ctrl edo Cmd eta egin klik bikoitza edo sakatu Ctrl edo Cmd + Sartu puntuak editatzeko",
|
||||
"lineEditor_pointSelected": "Sakatu Ezabatu puntuak kentzeko,\nKtrl+D bikoizteko, edo arrastatu mugitzeko",
|
||||
"lineEditor_nothingSelected": "Hautatu editatzeko puntu bat (SHIFT sakatuta anitz hautatzeko),\nedo eduki Alt sakatuta eta egin klik puntu berriak gehitzeko",
|
||||
"placeImage": "Egin klik irudia kokatzeko, edo egin klik eta arrastatu bere tamaina eskuz ezartzeko",
|
||||
"publishLibrary": "Argitaratu zure liburutegia",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"bindTextToElement": "Sakatu Sartu testua gehitzeko",
|
||||
"deepBoxSelect": "Eutsi Ctrl edo Cmd sakatuta aukeraketa sakona egiteko eta arrastatzea saihesteko",
|
||||
"eraserRevert": "Eduki Alt sakatuta ezabatzeko markatutako elementuak leheneratzeko",
|
||||
"firefox_clipboard_write": "Ezaugarri hau \"dom.events.asyncClipboard.clipboardItem\" marka \"true\" gisa ezarrita gaitu daiteke. Firefox-en arakatzailearen banderak aldatzeko, bisitatu \"about:config\" orrialdera.",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": "Eduki sakatuta Ctrl edo Cmd tekla atxikipena desgaitzeko"
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "Ezin da oihala aurreikusi",
|
||||
@@ -378,12 +299,9 @@
|
||||
"openIssueMessage": "Oso kontuz ibili gara zure eszenaren informazioa errorean ez sartzeko. Zure eszena pribatua ez bada, kontuan hartu gure <button>erroreen jarraipena egitea.</button> Sartu beheko informazioa kopiatu eta itsatsi bidez GitHub issue-n.",
|
||||
"sceneContent": "Eszenaren edukia:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": "Edo"
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "Gonbidatu jendea zure marrazkira.",
|
||||
"desc_privacy": "Lasai, sesioa encriptatua dago eta erabat pribatua da. Gure zerbitzarian ere ezin da ikusi zure marrazkia.",
|
||||
"desc_intro": "Jendea zure uneko eszenara gonbida dezakezu zurekin elkarlanean aritzeko.",
|
||||
"desc_privacy": "Ez kezkatu, saioak muturretik muturrerako enkriptatzea erabiltzen du, beraz, marrazten duzuna pribatua izango da. Gure zerbitzariak ere ezingo du ikusi zer egiten duzun.",
|
||||
"button_startSession": "Hasi saioa",
|
||||
"button_stopSession": "Itxi saioa",
|
||||
"desc_inProgressIntro": "Zuzeneko lankidetza saioa abian da.",
|
||||
@@ -410,8 +328,6 @@
|
||||
"click": "sakatu",
|
||||
"deepSelect": "Hautapen sakona",
|
||||
"deepBoxSelect": "Hautapen sakona egin laukizuzen bidez, eta saihestu arrastatzea",
|
||||
"createFlowchart": "",
|
||||
"navigateFlowchart": "",
|
||||
"curvedArrow": "Gezi kurbatua",
|
||||
"curvedLine": "Lerro kurbatua",
|
||||
"documentation": "Dokumentazioa",
|
||||
@@ -434,9 +350,7 @@
|
||||
"zoomToSelection": "Zooma hautapenera",
|
||||
"toggleElementLock": "Blokeatu/desbloketatu hautapena",
|
||||
"movePageUpDown": "Mugitu orria gora/behera",
|
||||
"movePageLeftRight": "Mugitu orria ezker/eskuin",
|
||||
"cropStart": "",
|
||||
"cropFinish": ""
|
||||
"movePageLeftRight": "Mugitu orria ezker/eskuin"
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": "Garbitu oihala"
|
||||
@@ -507,15 +421,13 @@
|
||||
},
|
||||
"stats": {
|
||||
"angle": "Angelua",
|
||||
"shapes": "",
|
||||
"element": "Elementua",
|
||||
"elements": "Elementuak",
|
||||
"height": "Altuera",
|
||||
"scene": "Eszena",
|
||||
"selected": "Hautatua",
|
||||
"storage": "Biltegia",
|
||||
"fullTitle": "",
|
||||
"title": "",
|
||||
"generalStats": "",
|
||||
"elementProperties": "",
|
||||
"title": "Datuak",
|
||||
"total": "Guztira",
|
||||
"version": "Bertsioa",
|
||||
"versionCopy": "Klikatu kopiatzeko",
|
||||
@@ -527,15 +439,13 @@
|
||||
"copyStyles": "Estiloak kopiatu dira.",
|
||||
"copyToClipboard": "Arbelean kopiatu da.",
|
||||
"copyToClipboardAsPng": "{{exportSelection}} kopiatu da arbelean PNG gisa\n({{exportColorScheme}})",
|
||||
"copyToClipboardAsSvg": "",
|
||||
"fileSaved": "Fitxategia gorde da.",
|
||||
"fileSavedToFilename": "{filename}-n gorde da",
|
||||
"canvas": "oihala",
|
||||
"selection": "hautapena",
|
||||
"pasteAsSingleElement": "Erabili {{shortcut}} elementu bakar gisa itsasteko,\nedo itsatsi lehendik dagoen testu-editore batean",
|
||||
"unableToEmbed": "Url hau txertatzea ez da une honetan onartzen. Sortu issue bat GitHub-en Urla zerrenda zurian sartzea eskatzeko",
|
||||
"unrecognizedLinkFormat": "Kapsulatu duzun esteka ez dator bat espero den formatuarekin. Mesedez, saiatu iturburu-guneak emandako 'kapsulatu' katea itsasten",
|
||||
"elementLinkCopied": ""
|
||||
"unrecognizedLinkFormat": "Kapsulatu duzun esteka ez dator bat espero den formatuarekin. Mesedez, saiatu iturburu-guneak emandako 'kapsulatu' katea itsasten"
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "Gardena",
|
||||
@@ -568,7 +478,6 @@
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "Gehien erabilitako kolore pertsonalizatuak",
|
||||
"colors": "Koloreak",
|
||||
"shades": "Ñabardurak",
|
||||
@@ -607,58 +516,10 @@
|
||||
}
|
||||
},
|
||||
"mermaid": {
|
||||
"title": "Mermaid-etik Excalidraw-ra",
|
||||
"button": "Txertatu",
|
||||
"description": "Momentu honetan <flowchartLink>Flowchart</flowchartLink>, <sequenceLink> Sequence, </sequenceLink> eta <classLink>Class </classLink>Diagramak onartzen dira. Beste motak irudi gisa errendatuko dira Excalidrawn.",
|
||||
"syntax": "Mermaid sintaxia",
|
||||
"preview": "Aurrebista"
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": ""
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": ""
|
||||
},
|
||||
"sceneFonts": "",
|
||||
"availableFonts": "",
|
||||
"empty": ""
|
||||
},
|
||||
"userList": {
|
||||
"empty": "",
|
||||
"hint": {
|
||||
"text": "Klik erabiltzailean jarraitzeko",
|
||||
"followStatus": "Dagoeneko erabiltzaile hau jarraitzen ari zara",
|
||||
"inCall": "Erabiltzailea dei batean dago",
|
||||
"micMuted": "Erabiltzailearen mikronofoa isildua dago",
|
||||
"isSpeaking": ""
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "",
|
||||
"shortcuts": {
|
||||
"select": "",
|
||||
"confirm": "",
|
||||
"close": ""
|
||||
},
|
||||
"recents": "",
|
||||
"search": {
|
||||
"placeholder": "",
|
||||
"noMatch": ""
|
||||
},
|
||||
"itemNotAvailable": "",
|
||||
"shortcutHint": ""
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
"button": "Txertatu",
|
||||
"description": "",
|
||||
"syntax": "",
|
||||
"preview": "Aurrebista"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,29 +1,27 @@
|
||||
{
|
||||
"labels": {
|
||||
"paste": "جایگذاری",
|
||||
"pasteAsPlaintext": "جایگذاری به عنوان متن ساده",
|
||||
"pasteCharts": "جایگذاری نمودارها",
|
||||
"paste": "جای گذاری",
|
||||
"pasteAsPlaintext": "جایگذاری به عنوان متن ساده",
|
||||
"pasteCharts": "قراردادن نمودارها",
|
||||
"selectAll": "انتخاب همه",
|
||||
"multiSelect": "یک ایتم به انتخاب شده ها اضافه کنید",
|
||||
"multiSelect": "یک ایتم به انتخاب شده ها اضافه کنید.",
|
||||
"moveCanvas": "جابجایی بوم",
|
||||
"cut": "بریدن",
|
||||
"copy": "کپی",
|
||||
"copyAsPng": "کپی در حافطه موقت به صورت PNG",
|
||||
"copyAsSvg": "کپی در حافطه موقت به صورت SVG",
|
||||
"copyText": "کپی در حافطه موقت به صورت متن",
|
||||
"copySource": "کپی منبع در حافظه موقت",
|
||||
"convertToCode": "تبدیل به کد",
|
||||
"copySource": "",
|
||||
"convertToCode": "",
|
||||
"bringForward": "جلو آوردن",
|
||||
"sendToBack": "ارسال به عقب",
|
||||
"sendToBack": "پس فرستادن",
|
||||
"bringToFront": "جلو آوردن",
|
||||
"sendBackward": "پس فرستادن",
|
||||
"delete": "حذف",
|
||||
"copyStyles": "کپی سبک",
|
||||
"pasteStyles": "جایگذاری سبک",
|
||||
"pasteStyles": "جای گذاری سبک",
|
||||
"stroke": "حاشیه",
|
||||
"changeStroke": "تغییر رنگ حاشیه",
|
||||
"background": "پس زمینه",
|
||||
"changeBackground": "تغییر رنگ پس زمینه",
|
||||
"fill": "رنگ آمیزی",
|
||||
"strokeWidth": "ضخامت حاشیه",
|
||||
"strokeStyle": "استایل حاشیه",
|
||||
@@ -32,32 +30,24 @@
|
||||
"strokeStyle_dotted": "نقطه چین",
|
||||
"sloppiness": "دقت",
|
||||
"opacity": "شفافیت",
|
||||
"textAlign": "تراز متن",
|
||||
"textAlign": "چیدمان متن",
|
||||
"edges": "لبه ها",
|
||||
"sharp": "تیز",
|
||||
"round": "گرد",
|
||||
"round": "دور",
|
||||
"arrowheads": "سر پیکان",
|
||||
"arrowhead_none": "هیچ کدام",
|
||||
"arrowhead_arrow": "پیکان",
|
||||
"arrowhead_bar": "میله ای",
|
||||
"arrowhead_circle": "دایره",
|
||||
"arrowhead_circle_outline": "دایره (پیرامون)",
|
||||
"arrowhead_circle": "",
|
||||
"arrowhead_circle_outline": "",
|
||||
"arrowhead_triangle": "مثلث",
|
||||
"arrowhead_triangle_outline": "مثلث (پیرامون)",
|
||||
"arrowhead_diamond": "الماس",
|
||||
"arrowhead_diamond_outline": "الماس (پیرامون)",
|
||||
"arrowhead_crowfoot_many": "پای کلاغی (بسیار)",
|
||||
"arrowhead_crowfoot_one": "پای کلاغی (یک)",
|
||||
"arrowhead_crowfoot_one_or_many": "پای کلاغی (یک یا بسیار)",
|
||||
"more_options": "امکانات بیشتر",
|
||||
"arrowtypes": "نوع پیکان",
|
||||
"arrowtype_sharp": "پیکان تیز",
|
||||
"arrowtype_round": "پیکان منحنی",
|
||||
"arrowtype_elbowed": "پیکان گوشهدار",
|
||||
"arrowhead_triangle_outline": "",
|
||||
"arrowhead_diamond": "",
|
||||
"arrowhead_diamond_outline": "",
|
||||
"fontSize": "اندازه قلم",
|
||||
"fontFamily": "نوع قلم",
|
||||
"addWatermark": "\"ساخته شده با Excalidraw\" را اضافه کن",
|
||||
"handDrawn": "دستنویس",
|
||||
"handDrawn": "دست نویس",
|
||||
"normal": "عادی",
|
||||
"code": "کد",
|
||||
"small": "کوچک",
|
||||
@@ -79,15 +69,14 @@
|
||||
"cartoonist": "کارتونیست",
|
||||
"fileTitle": "نام فایل",
|
||||
"colorPicker": "انتخابگر رنگ",
|
||||
"canvasColors": "اسنفاده شده در بوم",
|
||||
"canvasBackground": "پسزمینه بوم",
|
||||
"canvasColors": "رنگ های بوم",
|
||||
"canvasBackground": "بوم",
|
||||
"drawingCanvas": "بوم نقاشی",
|
||||
"clearCanvas": "پاکسازی بوم",
|
||||
"layers": "لایه ها",
|
||||
"actions": "عملیات",
|
||||
"language": "زبان",
|
||||
"liveCollaboration": "همکاری آنلاین...",
|
||||
"duplicateSelection": "تکراری",
|
||||
"duplicateSelection": "تکرار",
|
||||
"untitled": "بدون عنوان",
|
||||
"name": "نام",
|
||||
"yourName": "نام شما",
|
||||
@@ -95,13 +84,12 @@
|
||||
"group": "گروهبندی انتخابها",
|
||||
"ungroup": "حذف گروهبندی انتخابها",
|
||||
"collaborators": "همکاران",
|
||||
"toggleGrid": "تغییر وضعیت خطوط شطرنجی",
|
||||
"showGrid": "نمایش گرید",
|
||||
"addToLibrary": "افزودن به کتابخانه",
|
||||
"removeFromLibrary": "حذف از کتابخانه",
|
||||
"libraryLoadingMessage": "بارگذاری کتابخانه…",
|
||||
"libraries": "مرور کردن کتابخانه ها",
|
||||
"loadingScene": "باگذاری صحنه…",
|
||||
"loadScene": "بارگذاری صحنه از فایل",
|
||||
"align": "تراز",
|
||||
"alignTop": "تراز به بالا",
|
||||
"alignBottom": "تراز به پایین",
|
||||
@@ -117,11 +105,9 @@
|
||||
"share": "اشتراکگذاری",
|
||||
"showStroke": "نمایش انتخاب کننده رنگ حاشیه",
|
||||
"showBackground": "نمایش انتخاب کننده رنگ پس زمینه",
|
||||
"showFonts": "نمایش انتخاب فونت",
|
||||
"toggleTheme": "تغییر وضعیت پوسته روشن/تیره",
|
||||
"theme": "پوسته",
|
||||
"toggleTheme": "تغییر تم",
|
||||
"personalLib": "کتابخانه شخصی",
|
||||
"excalidrawLib": "کتابخانه Excalidraw",
|
||||
"excalidrawLib": "کتابخانه",
|
||||
"decreaseFontSize": "کاهش اندازه فونت",
|
||||
"increaseFontSize": "افزایش دادن اندازه فونت",
|
||||
"unbindText": "بازکردن نوشته",
|
||||
@@ -129,21 +115,16 @@
|
||||
"createContainerFromText": "متن را در یک جایگاه بپیچید",
|
||||
"link": {
|
||||
"edit": "ویرایش لینک",
|
||||
"editEmbed": "تغیر لینک",
|
||||
"create": "افزودن لینک",
|
||||
"editEmbed": "",
|
||||
"create": "ایجاد پیوند",
|
||||
"createEmbed": "",
|
||||
"label": "لینک",
|
||||
"labelEmbed": "لینک و افزونه",
|
||||
"empty": "هیچ لینکی ست نشده",
|
||||
"hint": "لینک خود را بنویسید یا جایگذاری کنید",
|
||||
"goToElement": "رفتن به المان مد نظر"
|
||||
"labelEmbed": "",
|
||||
"empty": ""
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "ویرایش لینک",
|
||||
"editArrow": "ویرایش پیکان"
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"exit": "خروج از ویرایشگر"
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "قفل",
|
||||
@@ -153,50 +134,16 @@
|
||||
},
|
||||
"statusPublished": "منتشر شده",
|
||||
"sidebarLock": "باز نگه داشتن سایدبار",
|
||||
"selectAllElementsInFrame": "همه آیتم های در فریم را انتخاب کنید",
|
||||
"removeAllElementsFromFrame": "حذف همه آیتم های داخل فریم",
|
||||
"eyeDropper": "انتخاب رنگ از بوم",
|
||||
"textToDiagram": "متن به دیاگرام",
|
||||
"prompt": "فوری",
|
||||
"followUs": "ما را دنبال کنید",
|
||||
"discordChat": "چت دیسکورد",
|
||||
"zoomToFitViewport": "بزرگنمایی به اندازه نمایشگر",
|
||||
"zoomToFitSelection": "بزرگنمایی به اندازه قسمت انتخاب شده",
|
||||
"zoomToFit": "بزرگنمایی برای دیدن تمام آیتم ها",
|
||||
"installPWA": "نصب Excalidraw روی دستگاه (PWA)",
|
||||
"autoResize": "فعالسازی تنظیم خودکار سایز",
|
||||
"imageCropping": "برش عکس",
|
||||
"unCroppedDimension": "اندازه غیر برشی",
|
||||
"copyElementLink": "کپی لینک به آیتم",
|
||||
"linkToElement": "لینک به آیتم",
|
||||
"wrapSelectionInFrame": "انتخاب را در قاب قرار دهید",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "لینک به آیتم",
|
||||
"desc": "روی شکل یا بوم کلیک کنید، یا لینک را جایگذاری کنید.",
|
||||
"notFound": "آیتم لینک شده در بوم پیدا نشد."
|
||||
"selectAllElementsInFrame": "",
|
||||
"removeAllElementsFromFrame": "",
|
||||
"eyeDropper": "انتخاب رنگ از کرباس",
|
||||
"textToDiagram": "",
|
||||
"prompt": ""
|
||||
},
|
||||
"library": {
|
||||
"noItems": "آیتمی به اینجا اضافه نشده...",
|
||||
"hint_emptyLibrary": "یک آیتم روی بوم را برای اضافه شده به اینجا انتخاب کنید، یا یک کتابخانه از مخزن عمومی در بخش پایین را نصب کنید.",
|
||||
"hint_emptyPrivateLibrary": "یک آیتم روی بوم را برای اضافه شدن به اینجا انتخاب کنید.",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "جستجو در بوم",
|
||||
"noMatch": "هیچ موردی یافت نشد...",
|
||||
"singleResult": "نتیجه",
|
||||
"multipleResults": "نتایج",
|
||||
"placeholder": "جستجوی متن در بوم...",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"hint_emptyPrivateLibrary": "یک آیتم روی بوم را برای اضافه شدن به اینجا انتخاب کنید."
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "پاکسازی بوم نقاشی",
|
||||
@@ -204,7 +151,6 @@
|
||||
"exportImage": "خروجی گرفتن از تصویر...",
|
||||
"export": "ذخیره در...",
|
||||
"copyToClipboard": "کپی در حافظه موقت",
|
||||
"copyLink": "کپی لینک",
|
||||
"save": "ذخیره در همین فایل",
|
||||
"saveAs": "ذخیره با نام",
|
||||
"load": "باز کردن",
|
||||
@@ -225,19 +171,17 @@
|
||||
"fullScreen": "تمامصفحه",
|
||||
"darkMode": "حالت تیره",
|
||||
"lightMode": "حالت روشن",
|
||||
"systemMode": "حالت سیستم",
|
||||
"zenMode": "حالت ذن",
|
||||
"objectsSnapMode": "به اشیاء بچسبد",
|
||||
"objectsSnapMode": "",
|
||||
"exitZenMode": "خروج از حالت تمرکز",
|
||||
"cancel": "لغو",
|
||||
"saveLibNames": "",
|
||||
"clear": "پاکسازی",
|
||||
"clear": "پاک کردن",
|
||||
"remove": "پاک کردن",
|
||||
"embed": "تغییر افزونه",
|
||||
"publishLibrary": "",
|
||||
"embed": "",
|
||||
"publishLibrary": "انتشار",
|
||||
"submit": "ارسال",
|
||||
"confirm": "تایید",
|
||||
"embeddableInteractionButton": "کلیک برای تعامل"
|
||||
"embeddableInteractionButton": ""
|
||||
},
|
||||
"alerts": {
|
||||
"clearReset": "این کار کل صفحه را پاک میکند. آیا مطمئنید؟",
|
||||
@@ -246,8 +190,8 @@
|
||||
"couldNotLoadInvalidFile": "عدم توانایی در بازگذاری فایل نامعتبر",
|
||||
"importBackendFailed": "بارگیری از پشت صحنه با شکست مواجه شد.",
|
||||
"cannotExportEmptyCanvas": "بوم خالی قابل تبدیل نیست.",
|
||||
"couldNotCopyToClipboard": "در بریدهدان رونویسی نشد.",
|
||||
"decryptFailed": "رمزگشایی داده ها امکانپذیر نیست.",
|
||||
"couldNotCopyToClipboard": "به کلیپ بورد کپی نشد.",
|
||||
"decryptFailed": "رمزگشایی داده ها امکان پذیر نیست.",
|
||||
"uploadedSecurly": "آپلود با رمزگذاری دو طرفه انجام میشود، به این معنی که سرور Excalidraw و اشخاص ثالث نمی توانند مطالب شما را بخوانند.",
|
||||
"loadSceneOverridePrompt": "بارگزاری یک طرح خارجی محتوای فعلی رو از بین میبرد. آیا میخواهید ادامه دهید؟",
|
||||
"collabStopOverridePrompt": "با توقف بوم نقاشی، نقشه قبلی و ذخیره شده محلی شما را بازنویسی می کند. مطمئنی؟\n\n(اگر می خواهید نقاشی محلی خود را حفظ کنید، به سادگی برگه مرورگر را ببندید.)",
|
||||
@@ -260,39 +204,37 @@
|
||||
"resetLibrary": "ین کار کل صفحه را پاک میکند. آیا مطمئنید?",
|
||||
"removeItemsFromsLibrary": "حذف {{count}} آیتم(ها) از کتابخانه?",
|
||||
"invalidEncryptionKey": "کلید رمزگذاری باید 22 کاراکتر باشد. همکاری زنده غیرفعال است.",
|
||||
"collabOfflineWarning": "اتصال به اینترنت در دسترس نیست.\nتغییرات شما ذخیره نمی شود!",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"collabOfflineWarning": "اتصال به اینترنت در دسترس نیست.\nتغییرات شما ذخیره نمی شود!"
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "نوع فایل پشتیبانی نشده.",
|
||||
"imageInsertError": "عکس ارسال نشد. بعداً دوباره تلاش کنید...",
|
||||
"fileTooBig": "فایل خیلی بزرگ است حداکثر اندازه مجاز {{maxSize}}.",
|
||||
"svgImageInsertError": "تصویر SVG وارد نشد. نشانه گذاری SVG نامعتبر به نظر می رسد.",
|
||||
"failedToFetchImage": "گرفتن تصویر ناموفق بود.",
|
||||
"failedToFetchImage": "",
|
||||
"invalidSVGString": "SVG نادرست.",
|
||||
"cannotResolveCollabServer": "به سرور collab متصل نشد. لطفا صفحه را مجددا بارگذاری کنید و دوباره تلاش کنید.",
|
||||
"importLibraryError": "دادهها بارگذاری نشدند",
|
||||
"saveLibraryError": "ذخیرهسازی در سرور با مشکل مواجه شد. لطفا فایل خود را در دستگاه خود به صورت محلی ذخیره کنید تا مطمئن شوید تغییرات اعمال شده را از دست نخواهید داد.",
|
||||
"collabSaveFailed": "در پایگاه داده باطن ذخیره نشد. اگر مشکلات همچنان ادامه داشت، باید فایل خود را به صورت محلی ذخیره کنید تا مطمئن شوید کار خود را از دست نمی دهید.",
|
||||
"collabSaveFailed_sizeExceeded": "در پایگاه داده بکند ذخیره نشد. اگر مشکلات همچنان ادامه داشت، باید فایل خود را به صورت محلی ذخیره کنید تا مطمئن شوید کار خود را از دست نمی دهید.",
|
||||
"imageToolNotSupported": "تصاویر غیر فعال شدند.",
|
||||
"imageToolNotSupported": "",
|
||||
"brave_measure_text_error": {
|
||||
"line1": "به نظر میرسد از مرورگر Brave با تنظیم <bold> مسدود کردن شدید اثرانگشت</bold> استفاده میکنید.",
|
||||
"line2": "این می تواند منجر به شکستن <bold>عناصر متن</bold> در نقاشی های شما شود.",
|
||||
"line3": "اکیداً توصیه می کنیم این تنظیم را غیرفعال کنید. برای نحوه انجام این کار میتوانید <link>این مراحل</link> را دنبال کنید.",
|
||||
"line4": "اگر غیرفعال کردن این تنظیم نمایش عناصر متنی را برطرف نکرد، لطفاً یک <issueLink>مشکل</issueLink> را در GitHub ما باز کنید یا برای ما در <discordLink>Discord</discordLink> بنویسید"
|
||||
"line4": "اگر غیرفعال کردن این تنظیم نمایش عناصر متنی را برطرف نکرد، لطفاً یک <issueLink>مشکل</issueLink> را در GitHub ما باز کنید یا برای ما در <discordLink>Discord</discordLink> بنویسید."
|
||||
},
|
||||
"libraryElementTypeError": {
|
||||
"embeddable": "عناصر افزوده شده نمی توانند به کتابخانه افزوده شوند.",
|
||||
"iframe": "عناصر IFrame نمی توانند به کتابخانه افزوده شوند.",
|
||||
"image": "پشتیبانی از افزودن تصاویر به کتابخانه به زودی اضافه خواهد شد!"
|
||||
"embeddable": "",
|
||||
"iframe": "",
|
||||
"image": ""
|
||||
},
|
||||
"asyncPasteFailedOnRead": "نمی تواند جاگذاری شود (نمی تواند از کلیپبورد بخواند).",
|
||||
"asyncPasteFailedOnParse": "نمیتواند جایگذاری شود.",
|
||||
"copyToSystemClipboardFailed": "نمی تواند در کلیپبورد کپی شود."
|
||||
"asyncPasteFailedOnRead": "",
|
||||
"asyncPasteFailedOnParse": "",
|
||||
"copyToSystemClipboardFailed": ""
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "گزینش",
|
||||
"lasso": "",
|
||||
"image": "وارد کردن تصویر",
|
||||
"rectangle": "مستطیل",
|
||||
"diamond": "لوزی",
|
||||
@@ -304,66 +246,45 @@
|
||||
"library": "کتابخانه",
|
||||
"lock": "ابزار انتخاب شده را بعد از کشیدن نگه دار",
|
||||
"penMode": "حالت قلم - جلوگیری از تماس",
|
||||
"link": "افزودن/بهروزرسانی لینک برای شکل انتخابی",
|
||||
"link": "افزودن/بهروزرسانی پیوند برای شکل انتخابی",
|
||||
"eraser": "پاک کن",
|
||||
"frame": "ابزار فریم",
|
||||
"magicframe": "وایرفریم به کد",
|
||||
"embeddable": "افزونه وب",
|
||||
"laser": "اشاره گر لیزری",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"laser": "",
|
||||
"hand": "دست (ابزار پانینگ)",
|
||||
"extraTools": "ابزارهای بیشتر",
|
||||
"mermaidToExcalidraw": "مرمید به excalidraw",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "مستطیل",
|
||||
"diamond": "لوزی",
|
||||
"ellipse": "بیضی",
|
||||
"arrow": "پیکان",
|
||||
"line": "خط",
|
||||
"freedraw": "کشیدن",
|
||||
"text": "متن",
|
||||
"image": "تصویر",
|
||||
"group": "گروه",
|
||||
"frame": "قاب",
|
||||
"magicframe": "وایرفریم به کد",
|
||||
"embeddable": "افزونه وب",
|
||||
"selection": "انتخاب",
|
||||
"iframe": "آی فریم"
|
||||
"mermaidToExcalidraw": "",
|
||||
"magicSettings": ""
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "عملیات روی بوم",
|
||||
"selectedShapeActions": "عملیات روی شکل انتخاب شده",
|
||||
"shapes": "اشکال"
|
||||
"shapes": "شکلها"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"canvasPanning": "برای حرکت دادن بوم، چرخ ماوس یا فاصله را در حین کشیدن نگه دارید یا از ابزار دستی استفاده کنید",
|
||||
"linearElement": "برای چند نقطه کلیک و برای یک خط بکشید",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "کلیک کنید و بکشید و وقتی کار تمام شد رها کنید",
|
||||
"text": "نکته: با برنامه انتخاب شده شما میتوانید با دوبار کلیک کردن هرکجا میخواید متن اظاف کنید",
|
||||
"embeddable": "کلیک-درگ برای ساخت افزونه وب",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"embeddable": "",
|
||||
"text_selected": "دوبار کلیک کنید یا Enter را فشار دهید تا نقاط را ویرایش کنید",
|
||||
"text_editing": "Escape یا CtrlOrCmd+ENTER را فشار دهید تا ویرایش تمام شود",
|
||||
"linearElementMulti": "روی آخرین نقطه کلیک کنید یا کلید ESC را بزنید یا کلید Enter را بزنید برای اتمام کار",
|
||||
"lockAngle": "با نگه داشتن SHIFT هنگام چرخش می توانید زاویه ها را محدود کنید",
|
||||
"resize": "می توانید با نگه داشتن SHIFT در هنگام تغییر اندازه، نسبت ها را محدود کنید،ALT را برای تغییر اندازه از مرکز نگه دارید",
|
||||
"resizeImage": "با نگه داشتن SHIFT می توانید آزادانه اندازه را تغییر دهید،\nبرای تغییر اندازه از مرکز، ALT را نگه دارید",
|
||||
"rotate": "با نگه داشتن SHIFT هنگام چرخش می توانید زاویه ها را محدود کنید",
|
||||
"lineEditor_info": "CtrlOrCmd را نگه دارید و دوبار کلیک کنید یا CtrlOrCmd + Enter را فشار دهید تا نقاط را ویرایش کنید.",
|
||||
"lineEditor_pointSelected": "برای حذف نقطه Delete برای کپی زدن Ctrl یا Cmd+D را بزنید و یا برای جابجایی بکشید",
|
||||
"lineEditor_nothingSelected": "یک نقطه را برای ویرایش انتخاب کنید (SHIFT را برای انتخاب چندگانه نگه دارید)،\nیا Alt را نگه دارید و برای افزودن نقاط جدید کلیک کنید",
|
||||
"placeImage": "برای قرار دادن تصویر کلیک کنید، یا کلیک کنید و بکشید تا اندازه آن به صورت دستی تنظیم شود",
|
||||
"publishLibrary": "کتابخانه خود را منتشر کنید",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"bindTextToElement": "برای افزودن اینتر را بزنید",
|
||||
"deepBoxSelect": "CtrlOrCmd را برای انتخاب عمیق و جلوگیری از کشیدن نگه دارید",
|
||||
"eraserRevert": "Alt را نگه دارید تا عناصر علامت گذاری شده برای حذف برگردند",
|
||||
"firefox_clipboard_write": "احتمالاً میتوان این ویژگی را با تنظیم پرچم «dom.events.asyncClipboard.clipboardItem» روی «true» فعال کرد. برای تغییر پرچم های مرورگر در فایرفاکس، از صفحه \"about:config\" دیدن کنید.",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": ""
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "پیش نمایش نشان داده نمی شود",
|
||||
@@ -371,19 +292,16 @@
|
||||
"canvasTooBigTip": "نکته: سعی کنید دورترین عناصر را کمی به همدیگر نزدیک کنید."
|
||||
},
|
||||
"errorSplash": {
|
||||
"headingMain": "مشکلی رخ داده. امتحان کنید <button> بارگذاری مجدد صفحه </button>.",
|
||||
"clearCanvasMessage": "اگر بازنشانی صفحه مشکل را حل نکرد <button>پاک کردن بوم</button> را امتحان کنید.",
|
||||
"headingMain": "",
|
||||
"clearCanvasMessage": "اگر بازنشانی صفحه مشکل را حل نکرد این را امتحان کنید ",
|
||||
"clearCanvasCaveat": " این باعث میشود کارهای شما ذخیره نشود ",
|
||||
"trackedToSentry": "خطا با شناسه {{eventId}} در سیستم ما رهگیری شد.",
|
||||
"openIssueMessage": "ما بسیار محتاط بودیم که اطلاعات صحنه شما را در خطا لحاظ نکنیم. اگر صحنه شما خصوصی نیست، لطفاً ما را دنبال کنید\n<button> رد یابی خطا </button>. لطفاً اطلاعات زیر را با کپی و جایگذاری در مشکل GitHub وارد کنید.",
|
||||
"trackedToSentry": "",
|
||||
"openIssueMessage": "",
|
||||
"sceneContent": "محتوای صحنه:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": "یا"
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "از دیگران برای همکاری در کار خود دعوت کنید.",
|
||||
"desc_privacy": "نگران نباشید، این نشست به صورت پایانه-به-پایانه رمزنگاری شده است و کاملا امن است. حتی سرورهای ما نیز قادر به دیدن ترسیمات شما نیستند.",
|
||||
"desc_intro": "می توانید افرادی را به صحنه فعلی خود دعوت کنید تا با شما همکاری کنند.",
|
||||
"desc_privacy": "نگران نباشید، این جلسه از رمزگذاری دوطرفه استفاده می کند، پس هر چیزی بکشید خصوصی خواهد ماند. حتی سرور ما نمیتواند ببیند چیزی که شما طراحی میکنید.",
|
||||
"button_startSession": "شروع جلسه",
|
||||
"button_stopSession": "پایان جلسه",
|
||||
"desc_inProgressIntro": "جلسه همکاری آنلاین در حال انجام است.",
|
||||
@@ -410,8 +328,6 @@
|
||||
"click": "کلیک",
|
||||
"deepSelect": "انتخاب عمیق",
|
||||
"deepBoxSelect": "انتخاب عمیق در کادر، و جلوگیری از کشیدن",
|
||||
"createFlowchart": "از هر آیتمی یک فلوچارت ایجاد کنید",
|
||||
"navigateFlowchart": "پیمایش یک فلوچارت",
|
||||
"curvedArrow": "فلش خمیده",
|
||||
"curvedLine": "منحنی",
|
||||
"documentation": "مستندات",
|
||||
@@ -434,9 +350,7 @@
|
||||
"zoomToSelection": "بزرگنمایی قسمت انتخاب شده",
|
||||
"toggleElementLock": "قفل/بازکردن انتخاب شده ها",
|
||||
"movePageUpDown": "حرکت صفحه به بالا/پایین",
|
||||
"movePageLeftRight": "حرکت صفحه به چپ/راست",
|
||||
"cropStart": "برش تصویر",
|
||||
"cropFinish": "پایان برش تصویر"
|
||||
"movePageLeftRight": "حرکت صفحه به چپ/راست"
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": "پاک کردن بوم"
|
||||
@@ -449,22 +363,22 @@
|
||||
"twitterUsername": "نام کاربری توییتر",
|
||||
"libraryName": "نام کتابخانه",
|
||||
"libraryDesc": "توضیحات کتابخانه",
|
||||
"website": "وبسایت",
|
||||
"website": "تارنما",
|
||||
"placeholder": {
|
||||
"authorName": "نام یا نام کاربری شما",
|
||||
"libraryName": "اسم کتابخانه",
|
||||
"libraryDesc": "شرحی از کتابخانه شما برای کمک به مردم برای درک استفاده از آن",
|
||||
"githubHandle": "دسته GitHub (اختیاری)، بنابراین می توانید پس از ارسال برای بررسی، کتابخانه را ویرایش کنید",
|
||||
"twitterHandle": "نام کاربری توییتر (اختیاری)، بنابراین میدانیم هنگام تبلیغ در توییتر به چه کسی اعتبار دهیم",
|
||||
"twitterHandle": "نام کاربری توییتر (اختیاری)، بنابراین می دانیم هنگام تبلیغ در توییتر به چه کسی اعتبار دهیم",
|
||||
"website": "پیوند به وب سایت شخصی شما یا هر جای دیگر (اختیاری)"
|
||||
},
|
||||
"errors": {
|
||||
"required": "لازم",
|
||||
"website": "وارد کردن آدرس درست"
|
||||
},
|
||||
"noteDescription": "کتابخانه خود را ارسال کنید تا در <link/> مخرن کتابخانه عمومی <link> برای بقیه مردم گنجانده شود تا در طرح هایشان استفاده کنند.",
|
||||
"noteGuidelines": "کتابخانه باید ابتدا به صورت دستی تأیید شود. لطفا قبل انتشار <link>راهنما</link> را مطالعه کنید. برای برقراری ارتباط و ایجاد تغییرات در صورت درخواست، به یک حساب GitHub نیاز دارید، اما خیلی الزامی نیست.",
|
||||
"noteLicense": "با ارسال، موافقت می کنید که کتابخانه تحت عنوان <link>MIT License</link> منتشر شود،که به طور خلاصه به این معنی است که هر کسی می تواند بدون محدودیت از آنها استفاده کند.",
|
||||
"noteDescription": "",
|
||||
"noteGuidelines": "",
|
||||
"noteLicense": "",
|
||||
"noteItems": "هر مورد کتابخانه باید نام خاص خود را داشته باشد تا قابل فیلتر باشد. اقلام کتابخانه زیر شامل خواهد شد:",
|
||||
"atleastOneLibItem": "لطفاً حداقل یک مورد از کتابخانه را برای شروع انتخاب کنید",
|
||||
"republishWarning": "توجه: برخی از موارد انتخاب شده به عنوان قبلاً منتشر شده/ارسال شده علامت گذاری شده اند. شما فقط باید هنگام بهروزرسانی یک کتابخانه موجود یا ارسال، موارد را دوباره ارسال کنید."
|
||||
@@ -475,30 +389,30 @@
|
||||
},
|
||||
"confirmDialog": {
|
||||
"resetLibrary": "تنظیم مجدد کتابخانه",
|
||||
"removeItemsFromLib": "موارد انتخاب شده از کتابخوانه حذف شوند"
|
||||
"removeItemsFromLib": "موارد انتخاب شده از موارد پسندیده حذف شوند"
|
||||
},
|
||||
"imageExportDialog": {
|
||||
"header": "خروجی گرفتن از تصویر",
|
||||
"header": "",
|
||||
"label": {
|
||||
"withBackground": "پس زمینه",
|
||||
"onlySelected": "فقط انتخاب شده ها",
|
||||
"darkMode": "حالت تاریک",
|
||||
"embedScene": "صحنه افزونه",
|
||||
"scale": "نسبت",
|
||||
"padding": "فاصله"
|
||||
"onlySelected": "",
|
||||
"darkMode": "حالت تیره",
|
||||
"embedScene": "",
|
||||
"scale": "",
|
||||
"padding": ""
|
||||
},
|
||||
"tooltip": {
|
||||
"embedScene": "داده های صحنه در فایل PNG/SVG صادر شده ذخیره می شود تا صحنه را بتوان از آن بازیابی کرد.\nاندازه فایل خروجی را افزایش می دهد."
|
||||
"embedScene": ""
|
||||
},
|
||||
"title": {
|
||||
"exportToPng": "تبدیل به PNG",
|
||||
"exportToSvg": "تبدیل به SVG",
|
||||
"copyPngToClipboard": "کپی PNG در حافظه موقت"
|
||||
"exportToPng": "",
|
||||
"exportToSvg": "",
|
||||
"copyPngToClipboard": ""
|
||||
},
|
||||
"button": {
|
||||
"exportToPng": "PNG",
|
||||
"exportToSvg": "SVG",
|
||||
"copyPngToClipboard": "کپی در حافظه موقت"
|
||||
"copyPngToClipboard": "کپی در کلیپبورد"
|
||||
}
|
||||
},
|
||||
"encrypted": {
|
||||
@@ -507,15 +421,13 @@
|
||||
},
|
||||
"stats": {
|
||||
"angle": "زاویه",
|
||||
"shapes": "اشکال",
|
||||
"element": "اِلمان",
|
||||
"elements": "اِلمان ها",
|
||||
"height": "ارتفاع",
|
||||
"scene": "صحنه",
|
||||
"selected": "انتخاب شده",
|
||||
"storage": "حافظه",
|
||||
"fullTitle": "ویژگیهای بوم و شکل",
|
||||
"title": "ویژگیها",
|
||||
"generalStats": "عمومی",
|
||||
"elementProperties": "ویژگیهای شکل",
|
||||
"title": "آمار برای نردها",
|
||||
"total": "مجموع",
|
||||
"version": "نسخه",
|
||||
"versionCopy": "برای کپی کردن کلیک کنید",
|
||||
@@ -524,18 +436,16 @@
|
||||
},
|
||||
"toast": {
|
||||
"addedToLibrary": "به مجموعه اضافه شد",
|
||||
"copyStyles": "سبک کپی شد.",
|
||||
"copyStyles": "کپی سبک.",
|
||||
"copyToClipboard": "در کلیپبورد کپی شد.",
|
||||
"copyToClipboardAsPng": "کپی {{exportSelection}} در حافظه موقت به عنوان PNG\n({{exportColorScheme}})",
|
||||
"copyToClipboardAsSvg": "{{exportSelection}} در حافظه موقت به عنوان\n({{exportColorScheme}}) رونویسی شد",
|
||||
"copyToClipboardAsPng": "کپی {{exportSelection}} در کلیپبورد به عنوان PNG\n({{exportColorScheme}})",
|
||||
"fileSaved": "فایل ذخیره شد.",
|
||||
"fileSavedToFilename": "ذخیره در {filename}",
|
||||
"canvas": "بوم",
|
||||
"selection": "انتخاب",
|
||||
"pasteAsSingleElement": "از {{shortcut}} برای چسباندن به عنوان یک عنصر استفاده کنید،\nیا در یک ویرایشگر متن موجود جایگذاری کنید",
|
||||
"unableToEmbed": "قرار دادن این Url در حال حاضر مجاز نیست. درGitHub برای درخواست Url Whitelisted مشکلی ایجاد کنید",
|
||||
"unrecognizedLinkFormat": "پیوندی که افزودید با قالب مورد انتظار مطابقت ندارد. لطفاً سعی کنید رشته \"افزونه\" ارائه شده توسط سایت منبع را بچسبانید",
|
||||
"elementLinkCopied": "لینک در کلیپبورد کپی شد"
|
||||
"unableToEmbed": "",
|
||||
"unrecognizedLinkFormat": ""
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "شفاف",
|
||||
@@ -568,97 +478,48 @@
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "رنگ های بهتازگی بهکار گرفته شده",
|
||||
"mostUsedCustomColors": "",
|
||||
"colors": "رنگها",
|
||||
"shades": "جلوهها",
|
||||
"hexCode": "کدِ هگز",
|
||||
"noShades": "هیچ سایه ای برای این رنگ در دسترس نیست"
|
||||
"noShades": ""
|
||||
},
|
||||
"overwriteConfirm": {
|
||||
"action": {
|
||||
"exportToImage": {
|
||||
"title": "صادر کردن به عنوان تصاویر",
|
||||
"button": "صادر کردن به عنوان تصاویر",
|
||||
"description": "خروجی از داده های صحنه به عنوان تصویر که میتوانید بعدا بیافزایید."
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
},
|
||||
"saveToDisk": {
|
||||
"title": "ذخیره در دیسک",
|
||||
"button": "ذخیره در دیسک",
|
||||
"description": "خروجی از داده های صحنه را به عنوان فایل که بعدا می توانید بیافزایید."
|
||||
"description": ""
|
||||
},
|
||||
"excalidrawPlus": {
|
||||
"title": "Excalidraw+",
|
||||
"button": "خروجی به Excalidraw+",
|
||||
"description": "ذخیره صفحه در میز کار Excalidraw+."
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"modal": {
|
||||
"loadFromFile": {
|
||||
"title": "بارگذاری از فایل",
|
||||
"button": "بارگذاری از فایل",
|
||||
"description": "بارگذاری از فایل <bold>جایگزین بشه با محتوای موجود</bold>.<br></br> می توانید ابتدا با استفاده از یکی از گزینه های زیر از نقاشی خود نسخه پشتیبان تهیه کنید."
|
||||
"description": ""
|
||||
},
|
||||
"shareableLink": {
|
||||
"title": "بارگذاری از پیوند",
|
||||
"button": "جایگزینی محتوای من",
|
||||
"description": "بارگذاری از فایل <bold>جایگزین بشه با محتوای موجود</bold>.<br></br> می توانید ابتدا با استفاده از یکی از گزینه های زیر از نقاشی خود نسخه پشتیبان تهیه کنید."
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"mermaid": {
|
||||
"title": "مرمید به excalidraw",
|
||||
"button": "درج",
|
||||
"description": "فعلا فقط <flowchartLink> فلوچارت </flowchartLink> ، <sequenceLink> توالی </sequenceLink> و <classLink> کلاس </classLink> نمودارها پشتیبانی می شوند. انواع دیگر به صورت تصویر در Excalidraw ارائه خواهند شد.",
|
||||
"syntax": "مرمید syntax",
|
||||
"preview": "پیشنمایش"
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": "جستجو فوری"
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": "قدیمی"
|
||||
},
|
||||
"sceneFonts": "در این صحنه",
|
||||
"availableFonts": "قلم های در دسترس",
|
||||
"empty": "قلمی یافت نشد"
|
||||
},
|
||||
"userList": {
|
||||
"empty": "کاربری یافت نشد",
|
||||
"hint": {
|
||||
"text": "روی کاربر بزنید تا دنبالش کنید",
|
||||
"followStatus": "هماینک این کاربر را دنبال میکنید",
|
||||
"inCall": "کاربر در تماسی صوتی است",
|
||||
"micMuted": "میکروفون کاربر بیصدا است",
|
||||
"isSpeaking": "کاربر در حال صحبت است"
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "تخته فرمانها",
|
||||
"shortcuts": {
|
||||
"select": "انتخاب",
|
||||
"confirm": "تایید",
|
||||
"close": "بستن"
|
||||
},
|
||||
"recents": "اخیراً استفاده شده",
|
||||
"search": {
|
||||
"placeholder": "در فهرستها و دستورها را جستجو کنید هم سنگهای پنهان را کشف کنید",
|
||||
"noMatch": "دستوری یافت نشد..."
|
||||
},
|
||||
"itemNotAvailable": "دستور در دسترس نیست...",
|
||||
"shortcutHint": "برای تخته دستور ها {{shortcut}} را بکار بگیرید"
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": "",
|
||||
"syntax": "",
|
||||
"preview": "پیشنمایش"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"copyAsPng": "Kopioi leikepöydälle PNG-tiedostona",
|
||||
"copyAsSvg": "Kopioi leikepöydälle SVG-tiedostona",
|
||||
"copyText": "Kopioi tekstinä",
|
||||
"copySource": "Kopioi lähde leikepöydälle",
|
||||
"convertToCode": "Muunna koodiksi",
|
||||
"copySource": "",
|
||||
"convertToCode": "",
|
||||
"bringForward": "Tuo eteenpäin",
|
||||
"sendToBack": "Vie taakse",
|
||||
"bringToFront": "Tuo eteen",
|
||||
@@ -21,9 +21,7 @@
|
||||
"copyStyles": "Kopioi tyyli",
|
||||
"pasteStyles": "Liitä tyyli",
|
||||
"stroke": "Piirto",
|
||||
"changeStroke": "",
|
||||
"background": "Tausta",
|
||||
"changeBackground": "",
|
||||
"fill": "Täyttö",
|
||||
"strokeWidth": "Viivan leveys",
|
||||
"strokeStyle": "Viivan tyyli",
|
||||
@@ -40,20 +38,12 @@
|
||||
"arrowhead_none": "Ei mitään",
|
||||
"arrowhead_arrow": "Nuoli",
|
||||
"arrowhead_bar": "Tasapää",
|
||||
"arrowhead_circle": "Ympyrä",
|
||||
"arrowhead_circle_outline": "Ympyrä (ääriviiva)",
|
||||
"arrowhead_circle": "",
|
||||
"arrowhead_circle_outline": "",
|
||||
"arrowhead_triangle": "Kolmio",
|
||||
"arrowhead_triangle_outline": "Kolmio (ääriviiva)",
|
||||
"arrowhead_triangle_outline": "",
|
||||
"arrowhead_diamond": "",
|
||||
"arrowhead_diamond_outline": "",
|
||||
"arrowhead_crowfoot_many": "",
|
||||
"arrowhead_crowfoot_one": "",
|
||||
"arrowhead_crowfoot_one_or_many": "",
|
||||
"more_options": "",
|
||||
"arrowtypes": "",
|
||||
"arrowtype_sharp": "",
|
||||
"arrowtype_round": "",
|
||||
"arrowtype_elbowed": "",
|
||||
"fontSize": "Kirjasinkoko",
|
||||
"fontFamily": "Kirjasintyyppi",
|
||||
"addWatermark": "Lisää \"Tehty Excalidrawilla\"",
|
||||
@@ -82,7 +72,6 @@
|
||||
"canvasColors": "Käytössä piirtoalueella",
|
||||
"canvasBackground": "Piirtoalueen tausta",
|
||||
"drawingCanvas": "Piirtoalue",
|
||||
"clearCanvas": "Tyhjennä piirtoalue",
|
||||
"layers": "Tasot",
|
||||
"actions": "Toiminnot",
|
||||
"language": "Kieli",
|
||||
@@ -95,13 +84,12 @@
|
||||
"group": "Ryhmitä valinta",
|
||||
"ungroup": "Pura valittu ryhmä",
|
||||
"collaborators": "Yhteistyökumppanit",
|
||||
"toggleGrid": "Näytä tai piilota ruudukko",
|
||||
"showGrid": "Näytä ruudukko",
|
||||
"addToLibrary": "Lisää kirjastoon",
|
||||
"removeFromLibrary": "Poista kirjastosta",
|
||||
"libraryLoadingMessage": "Ladataan kirjastoa…",
|
||||
"libraries": "Selaa kirjastoja",
|
||||
"loadingScene": "Ladataan työtä…",
|
||||
"loadScene": "",
|
||||
"align": "Tasaa",
|
||||
"alignTop": "Tasaa ylös",
|
||||
"alignBottom": "Tasaa alas",
|
||||
@@ -117,9 +105,7 @@
|
||||
"share": "Jaa",
|
||||
"showStroke": "Näytä viivan värin valitsin",
|
||||
"showBackground": "Näytä taustavärin valitsin",
|
||||
"showFonts": "",
|
||||
"toggleTheme": "",
|
||||
"theme": "Teema",
|
||||
"toggleTheme": "Vaihda teema",
|
||||
"personalLib": "Oma kirjasto",
|
||||
"excalidrawLib": "Excalidraw kirjasto",
|
||||
"decreaseFontSize": "Pienennä kirjasinkokoa",
|
||||
@@ -130,20 +116,15 @@
|
||||
"link": {
|
||||
"edit": "Muokkaa linkkiä",
|
||||
"editEmbed": "",
|
||||
"create": "",
|
||||
"create": "Luo linkki",
|
||||
"createEmbed": "",
|
||||
"label": "Linkki",
|
||||
"labelEmbed": "",
|
||||
"empty": "Linkkiä ei ole asetettu",
|
||||
"hint": "",
|
||||
"goToElement": ""
|
||||
"empty": ""
|
||||
},
|
||||
"lineEditor": {
|
||||
"edit": "Muokkaa riviä",
|
||||
"editArrow": ""
|
||||
},
|
||||
"polygon": {
|
||||
"breakPolygon": "",
|
||||
"convertToPolygon": ""
|
||||
"exit": "Poistu rivieditorista"
|
||||
},
|
||||
"elementLock": {
|
||||
"lock": "Lukitse",
|
||||
@@ -156,47 +137,13 @@
|
||||
"selectAllElementsInFrame": "",
|
||||
"removeAllElementsFromFrame": "",
|
||||
"eyeDropper": "",
|
||||
"textToDiagram": "Teksti kaavioksi",
|
||||
"prompt": "",
|
||||
"followUs": "Seuraa meitä",
|
||||
"discordChat": "Discord-keskustelu",
|
||||
"zoomToFitViewport": "",
|
||||
"zoomToFitSelection": "",
|
||||
"zoomToFit": "",
|
||||
"installPWA": "",
|
||||
"autoResize": "",
|
||||
"imageCropping": "",
|
||||
"unCroppedDimension": "",
|
||||
"copyElementLink": "",
|
||||
"linkToElement": "",
|
||||
"wrapSelectionInFrame": "",
|
||||
"tab": "",
|
||||
"shapeSwitch": ""
|
||||
},
|
||||
"elementLink": {
|
||||
"title": "",
|
||||
"desc": "",
|
||||
"notFound": ""
|
||||
"textToDiagram": "",
|
||||
"prompt": ""
|
||||
},
|
||||
"library": {
|
||||
"noItems": "Kirjastossa ei ole vielä yhtään kohdetta...",
|
||||
"hint_emptyLibrary": "Valitse lisättävä kohde piirtoalueelta, tai asenna alta julkinen kirjasto.",
|
||||
"hint_emptyPrivateLibrary": "Valitse lisättävä kohde piirtoalueelta.",
|
||||
"search": {
|
||||
"inputPlaceholder": "",
|
||||
"heading": "",
|
||||
"noResults": "",
|
||||
"clearSearch": ""
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "",
|
||||
"noMatch": "",
|
||||
"singleResult": "",
|
||||
"multipleResults": "",
|
||||
"placeholder": "",
|
||||
"frames": "",
|
||||
"texts": ""
|
||||
"hint_emptyPrivateLibrary": "Valitse lisättävä kohde piirtoalueelta."
|
||||
},
|
||||
"buttons": {
|
||||
"clearReset": "Tyhjennä piirtoalue",
|
||||
@@ -204,7 +151,6 @@
|
||||
"exportImage": "Vie kuva...",
|
||||
"export": "Tallenna nimellä...",
|
||||
"copyToClipboard": "Kopioi leikepöydälle",
|
||||
"copyLink": "",
|
||||
"save": "Tallenna nykyiseen tiedostoon",
|
||||
"saveAs": "Tallenna nimellä",
|
||||
"load": "Avaa",
|
||||
@@ -225,16 +171,14 @@
|
||||
"fullScreen": "Koko näyttö",
|
||||
"darkMode": "Tumma tila",
|
||||
"lightMode": "Vaalea tila",
|
||||
"systemMode": "Järjestelmätila",
|
||||
"zenMode": "Zen-tila",
|
||||
"objectsSnapMode": "",
|
||||
"exitZenMode": "Poistu zen-tilasta",
|
||||
"cancel": "Peruuta",
|
||||
"saveLibNames": "",
|
||||
"clear": "Pyyhi",
|
||||
"remove": "Poista",
|
||||
"embed": "",
|
||||
"publishLibrary": "",
|
||||
"publishLibrary": "Julkaise",
|
||||
"submit": "Lähetä",
|
||||
"confirm": "Vahvista",
|
||||
"embeddableInteractionButton": ""
|
||||
@@ -260,8 +204,7 @@
|
||||
"resetLibrary": "Tämä tyhjentää kirjastosi. Jatketaanko?",
|
||||
"removeItemsFromsLibrary": "Poista {{count}} kohdetta kirjastosta?",
|
||||
"invalidEncryptionKey": "Salausavaimen on oltava 22 merkkiä pitkä. Live-yhteistyö ei ole käytössä.",
|
||||
"collabOfflineWarning": "Internet-yhteyttä ei ole saatavilla.\nMuutoksiasi ei tallenneta!",
|
||||
"localStorageQuotaExceeded": ""
|
||||
"collabOfflineWarning": "Internet-yhteyttä ei ole saatavilla.\nMuutoksiasi ei tallenneta!"
|
||||
},
|
||||
"errors": {
|
||||
"unsupportedFileType": "Tiedostotyyppiä ei tueta.",
|
||||
@@ -269,9 +212,9 @@
|
||||
"fileTooBig": "Tiedosto on liian suuri. Suurin sallittu koko on {{maxSize}}.",
|
||||
"svgImageInsertError": "SVG- kuvaa ei voitu lisätä. Tiedoston SVG-sisältö näyttää virheelliseltä.",
|
||||
"failedToFetchImage": "",
|
||||
"invalidSVGString": "Virheellinen SVG.",
|
||||
"cannotResolveCollabServer": "Yhteyden muodostaminen collab-palvelimeen epäonnistui. Virkistä sivu ja yritä uudelleen.",
|
||||
"importLibraryError": "Kokoelman lataaminen epäonnistui",
|
||||
"saveLibraryError": "",
|
||||
"collabSaveFailed": "Ei voitu tallentaan palvelimen tietokantaan. Jos ongelmia esiintyy, sinun kannatta tallentaa tallentaa tiedosto paikallisesti varmistaaksesi, että et menetä työtäsi.",
|
||||
"collabSaveFailed_sizeExceeded": "Ei voitu tallentaan palvelimen tietokantaan. Jos ongelmia esiintyy, sinun kannatta tallentaa tallentaa tiedosto paikallisesti varmistaaksesi, että et menetä työtäsi.",
|
||||
"imageToolNotSupported": "",
|
||||
@@ -287,12 +230,11 @@
|
||||
"image": ""
|
||||
},
|
||||
"asyncPasteFailedOnRead": "",
|
||||
"asyncPasteFailedOnParse": "Ei voitu liittää.",
|
||||
"copyToSystemClipboardFailed": "Kopiointi leikepöydälle epäonnistui."
|
||||
"asyncPasteFailedOnParse": "",
|
||||
"copyToSystemClipboardFailed": ""
|
||||
},
|
||||
"toolBar": {
|
||||
"selection": "Valinta",
|
||||
"lasso": "",
|
||||
"image": "Lisää kuva",
|
||||
"rectangle": "Suorakulmio",
|
||||
"diamond": "Vinoneliö",
|
||||
@@ -304,32 +246,16 @@
|
||||
"library": "Kirjasto",
|
||||
"lock": "Pidä valittu työkalu aktiivisena piirron jälkeen",
|
||||
"penMode": "Kynätila - estä kosketus",
|
||||
"link": "",
|
||||
"link": "Lisää/päivitä linkki valitulle muodolle",
|
||||
"eraser": "Poistotyökalu",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "Verkkoupote",
|
||||
"laser": "Laserosoitin",
|
||||
"hand": "Käsi (panning-työkalu)",
|
||||
"extraTools": "Lisää työkaluja",
|
||||
"mermaidToExcalidraw": "Mermaid Excalidrawiksi",
|
||||
"convertElementType": ""
|
||||
},
|
||||
"element": {
|
||||
"rectangle": "",
|
||||
"diamond": "",
|
||||
"ellipse": "",
|
||||
"arrow": "",
|
||||
"line": "",
|
||||
"freedraw": "",
|
||||
"text": "",
|
||||
"image": "",
|
||||
"group": "",
|
||||
"frame": "",
|
||||
"magicframe": "",
|
||||
"embeddable": "",
|
||||
"selection": "",
|
||||
"iframe": ""
|
||||
"laser": "",
|
||||
"hand": "Käsi (panning-työkalu)",
|
||||
"extraTools": "",
|
||||
"mermaidToExcalidraw": "",
|
||||
"magicSettings": ""
|
||||
},
|
||||
"headings": {
|
||||
"canvasActions": "Piirtoalueen toiminnot",
|
||||
@@ -337,33 +263,28 @@
|
||||
"shapes": "Muodot"
|
||||
},
|
||||
"hints": {
|
||||
"dismissSearch": "",
|
||||
"canvasPanning": "",
|
||||
"canvasPanning": "Piirtoalueen liikuttamiseksi pidä hiiren pyörää tai välilyöntiä pohjassa tai käytä käsityökalua",
|
||||
"linearElement": "Klikkaa piirtääksesi useampi piste, raahaa piirtääksesi yksittäinen viiva",
|
||||
"arrowTool": "",
|
||||
"freeDraw": "Paina ja raahaa, päästä irti kun olet valmis",
|
||||
"text": "Vinkki: voit myös lisätä tekstiä kaksoisnapsauttamalla mihin tahansa valintatyökalulla",
|
||||
"embeddable": "",
|
||||
"text_selected": "",
|
||||
"text_editing": "",
|
||||
"linearElementMulti": "",
|
||||
"lockAngle": "",
|
||||
"resize": "",
|
||||
"resizeImage": "",
|
||||
"rotate": "",
|
||||
"lineEditor_info": "",
|
||||
"lineEditor_line_info": "",
|
||||
"lineEditor_pointSelected": "",
|
||||
"lineEditor_nothingSelected": "",
|
||||
"text_selected": "Kaksoisnapsauta tai paina ENTER muokataksesi tekstiä",
|
||||
"text_editing": "Paina Escape tai CtrlOrCmd+ENTER lopettaaksesi muokkaamisen",
|
||||
"linearElementMulti": "Lopeta klikkaamalla viimeistä pistettä, painamalla Escape- tai Enter-näppäintä",
|
||||
"lockAngle": "Voit rajoittaa kulmaa pitämällä SHIFT-näppäintä alaspainettuna",
|
||||
"resize": "Voit rajoittaa mittasuhteet pitämällä SHIFT-näppäintä alaspainettuna kun muutat kokoa, pidä ALT-näppäintä alaspainettuna muuttaaksesi kokoa keskipisteen suhteen",
|
||||
"resizeImage": "Voit muuttaa kokoa vapaasti pitämällä SHIFTiä pohjassa, pidä ALT pohjassa muuttaaksesi kokoa keskipisteen ympäri",
|
||||
"rotate": "Voit rajoittaa kulman pitämällä SHIFT pohjassa pyörittäessäsi",
|
||||
"lineEditor_info": "Pidä CtrlOrCmd pohjassa ja kaksoisnapsauta tai paina CtrlOrCmd + Enter muokataksesi pisteitä",
|
||||
"lineEditor_pointSelected": "Poista piste(et) painamalla delete, monista painamalla CtrlOrCmd+D, tai liikuta raahaamalla",
|
||||
"lineEditor_nothingSelected": "Valitse muokattava piste (monivalinta pitämällä SHIFT pohjassa), tai paina Alt ja klikkaa lisätäksesi uusia pisteitä",
|
||||
"placeImage": "Klikkaa asettaaksesi kuvan, tai klikkaa ja raahaa asettaaksesi sen koon manuaalisesti",
|
||||
"publishLibrary": "Julkaise oma kirjasto",
|
||||
"bindTextToElement": "",
|
||||
"createFlowchart": "",
|
||||
"deepBoxSelect": "",
|
||||
"eraserRevert": "",
|
||||
"bindTextToElement": "Lisää tekstiä painamalla enter",
|
||||
"deepBoxSelect": "Käytä syvävalintaa ja estä raahaus painamalla CtrlOrCmd",
|
||||
"eraserRevert": "Pidä Alt alaspainettuna, kumotaksesi merkittyjen elementtien poistamisen",
|
||||
"firefox_clipboard_write": "Tämä ominaisuus voidaan todennäköisesti ottaa käyttöön asettamalla \"dom.events.asyncClipboard.clipboardItem\" kohta \"true\":ksi. Vaihtaaksesi selaimen kohdan Firefoxissa, käy \"about:config\" sivulla.",
|
||||
"disableSnapping": "",
|
||||
"enterCropEditor": "",
|
||||
"leaveCropEditor": ""
|
||||
"disableSnapping": ""
|
||||
},
|
||||
"canvasError": {
|
||||
"cannotShowPreview": "Esikatselua ei voitu näyttää",
|
||||
@@ -378,12 +299,9 @@
|
||||
"openIssueMessage": "Olimme varovaisia emmekä sisällyttäneet tietoa piirroksestasi virheeseen. Mikäli piirroksesi ei ole yksityinen, harkitsethan kertovasi meille <button>virheenseurantajärjestelmässämme.</button> Sisällytä alla olevat tiedot kopioimalla ne GitHub-ongelmaan.",
|
||||
"sceneContent": "Piirroksen tiedot:"
|
||||
},
|
||||
"shareDialog": {
|
||||
"or": "Tai"
|
||||
},
|
||||
"roomDialog": {
|
||||
"desc_intro": "",
|
||||
"desc_privacy": "",
|
||||
"desc_intro": "Voit kutsua ihmisiä piirrokseesi tekemään yhteistyötä kanssasi.",
|
||||
"desc_privacy": "Älä huoli, istunto käyttää päästä-päähän-salausta, joten mitä tahansa piirrätkin, se pysyy salassa. Edes palvelimemme eivät näe mitä keksit.",
|
||||
"button_startSession": "Aloita istunto",
|
||||
"button_stopSession": "Lopeta istunto",
|
||||
"desc_inProgressIntro": "Jaettu istunto on nyt käynnissä.",
|
||||
@@ -410,8 +328,6 @@
|
||||
"click": "klikkaa",
|
||||
"deepSelect": "Syvävalinta",
|
||||
"deepBoxSelect": "Käytä syvävalintaa ja estä raahaus",
|
||||
"createFlowchart": "",
|
||||
"navigateFlowchart": "",
|
||||
"curvedArrow": "Kaareva nuoli",
|
||||
"curvedLine": "Kaareva viiva",
|
||||
"documentation": "Käyttöohjeet",
|
||||
@@ -434,9 +350,7 @@
|
||||
"zoomToSelection": "Näytä valinta",
|
||||
"toggleElementLock": "Lukitse / poista lukitus valinta",
|
||||
"movePageUpDown": "Siirrä sivua ylös/alas",
|
||||
"movePageLeftRight": "Siirrä sivua vasemmalle/oikealle",
|
||||
"cropStart": "",
|
||||
"cropFinish": ""
|
||||
"movePageLeftRight": "Siirrä sivua vasemmalle/oikealle"
|
||||
},
|
||||
"clearCanvasDialog": {
|
||||
"title": "Pyyhi piirtoalue"
|
||||
@@ -482,7 +396,7 @@
|
||||
"label": {
|
||||
"withBackground": "",
|
||||
"onlySelected": "",
|
||||
"darkMode": "Tumma tila",
|
||||
"darkMode": "",
|
||||
"embedScene": "",
|
||||
"scale": "",
|
||||
"padding": ""
|
||||
@@ -493,12 +407,12 @@
|
||||
"title": {
|
||||
"exportToPng": "",
|
||||
"exportToSvg": "",
|
||||
"copyPngToClipboard": "Kopioi PNG leikepöydälle"
|
||||
"copyPngToClipboard": ""
|
||||
},
|
||||
"button": {
|
||||
"exportToPng": "PNG",
|
||||
"exportToSvg": "SVG",
|
||||
"copyPngToClipboard": "Kopioi leikepöydälle"
|
||||
"exportToPng": "",
|
||||
"exportToSvg": "",
|
||||
"copyPngToClipboard": ""
|
||||
}
|
||||
},
|
||||
"encrypted": {
|
||||
@@ -507,15 +421,13 @@
|
||||
},
|
||||
"stats": {
|
||||
"angle": "Kulma",
|
||||
"shapes": "",
|
||||
"element": "Elementti",
|
||||
"elements": "Elementit",
|
||||
"height": "Korkeus",
|
||||
"scene": "Teos",
|
||||
"selected": "Valitut",
|
||||
"storage": "Tallennustila",
|
||||
"fullTitle": "",
|
||||
"title": "",
|
||||
"generalStats": "",
|
||||
"elementProperties": "",
|
||||
"title": "Tilastoja nörteille",
|
||||
"total": "Yhteensä",
|
||||
"version": "Versio",
|
||||
"versionCopy": "Klikkaa kopioidaksesi",
|
||||
@@ -527,32 +439,30 @@
|
||||
"copyStyles": "Tyylit kopioitiin.",
|
||||
"copyToClipboard": "Kopioitiin leikepöydälle.",
|
||||
"copyToClipboardAsPng": "Kopioitiin {{exportSelection}} leikepöydälle PNG:nä\n({{exportColorScheme}})",
|
||||
"copyToClipboardAsSvg": "",
|
||||
"fileSaved": "Tiedosto tallennettu.",
|
||||
"fileSavedToFilename": "Tallennettiin kohteeseen {filename}",
|
||||
"canvas": "piirtoalue",
|
||||
"selection": "valinta",
|
||||
"pasteAsSingleElement": "Käytä {{shortcut}} liittääksesi yhtenä elementtinä,\ntai liittääksesi olemassa olevaan tekstieditoriin",
|
||||
"unableToEmbed": "",
|
||||
"unrecognizedLinkFormat": "",
|
||||
"elementLinkCopied": ""
|
||||
"unrecognizedLinkFormat": ""
|
||||
},
|
||||
"colors": {
|
||||
"transparent": "Läpinäkyvä",
|
||||
"black": "Musta",
|
||||
"white": "Valkoinen",
|
||||
"red": "Punainen",
|
||||
"pink": "Pinkki",
|
||||
"grape": "Rypäle",
|
||||
"violet": "Violetti",
|
||||
"gray": "Harmaa",
|
||||
"blue": "Sininen",
|
||||
"cyan": "Syaani",
|
||||
"teal": "Sinivihreä",
|
||||
"green": "Vihreä",
|
||||
"yellow": "Keltainen",
|
||||
"orange": "Oranssi",
|
||||
"bronze": "Pronssi"
|
||||
"black": "",
|
||||
"white": "",
|
||||
"red": "",
|
||||
"pink": "",
|
||||
"grape": "",
|
||||
"violet": "",
|
||||
"gray": "",
|
||||
"blue": "",
|
||||
"cyan": "",
|
||||
"teal": "",
|
||||
"green": "",
|
||||
"yellow": "",
|
||||
"orange": "",
|
||||
"bronze": ""
|
||||
},
|
||||
"welcomeScreen": {
|
||||
"app": {
|
||||
@@ -568,35 +478,34 @@
|
||||
}
|
||||
},
|
||||
"colorPicker": {
|
||||
"color": "",
|
||||
"mostUsedCustomColors": "Eniten käytetyt omat värit",
|
||||
"colors": "Värit",
|
||||
"shades": "Varjot",
|
||||
"hexCode": "Hex koodi",
|
||||
"mostUsedCustomColors": "",
|
||||
"colors": "",
|
||||
"shades": "",
|
||||
"hexCode": "",
|
||||
"noShades": ""
|
||||
},
|
||||
"overwriteConfirm": {
|
||||
"action": {
|
||||
"exportToImage": {
|
||||
"title": "Vie kuva",
|
||||
"button": "Vie kuva",
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
},
|
||||
"saveToDisk": {
|
||||
"title": "Tallenna levylle",
|
||||
"button": "Tallenna levylle",
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
},
|
||||
"excalidrawPlus": {
|
||||
"title": "Excalidraw+",
|
||||
"button": "Vie Excalidraw+:aan",
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
}
|
||||
},
|
||||
"modal": {
|
||||
"loadFromFile": {
|
||||
"title": "Lataa tiedostosta",
|
||||
"button": "Lataa tiedostosta",
|
||||
"title": "",
|
||||
"button": "",
|
||||
"description": ""
|
||||
},
|
||||
"shareableLink": {
|
||||
@@ -611,54 +520,6 @@
|
||||
"button": "",
|
||||
"description": "",
|
||||
"syntax": "",
|
||||
"preview": "Esikatsele"
|
||||
},
|
||||
"quickSearch": {
|
||||
"placeholder": ""
|
||||
},
|
||||
"fontList": {
|
||||
"badge": {
|
||||
"old": ""
|
||||
},
|
||||
"sceneFonts": "",
|
||||
"availableFonts": "",
|
||||
"empty": ""
|
||||
},
|
||||
"userList": {
|
||||
"empty": "",
|
||||
"hint": {
|
||||
"text": "",
|
||||
"followStatus": "",
|
||||
"inCall": "",
|
||||
"micMuted": "",
|
||||
"isSpeaking": ""
|
||||
}
|
||||
},
|
||||
"commandPalette": {
|
||||
"title": "",
|
||||
"shortcuts": {
|
||||
"select": "Valitse",
|
||||
"confirm": "Vahvista",
|
||||
"close": "Sulje"
|
||||
},
|
||||
"recents": "Viimeksi käytetty",
|
||||
"search": {
|
||||
"placeholder": "Hae valikoita, komentoja ja löydä piilotettuja helmiä",
|
||||
"noMatch": "Ei vastaavia komentoja..."
|
||||
},
|
||||
"itemNotAvailable": "Komento ei ole käytettävissä...",
|
||||
"shortcutHint": ""
|
||||
},
|
||||
"keys": {
|
||||
"ctrl": "",
|
||||
"option": "",
|
||||
"cmd": "",
|
||||
"alt": "",
|
||||
"escape": "",
|
||||
"enter": "",
|
||||
"shift": "",
|
||||
"spacebar": "",
|
||||
"delete": "",
|
||||
"mmb": ""
|
||||
"preview": ""
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user