Compare commits

..

1 Commits

Author SHA1 Message Date
Panayiotis Lipiridis c12dab7a60 refactor: Remove the grid size and have a boolean instead 2020-12-24 20:15:12 +02:00
97 changed files with 2115 additions and 2906 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
REACT_APP_BACKEND_V1_GET_URL=https://json.excalidraw.com/api/v1/ REACT_APP_BACKEND_V1_GET_URL=https://json.excalidraw.com/api/v1/
REACT_APP_BACKEND_V2_GET_URL=https://json.excalidraw.com/api/v2/ REACT_APP_BACKEND_V2_GET_URL=https://json.excalidraw.com/api/v2/
REACT_APP_BACKEND_V2_POST_URL=https://json.excalidraw.com/api/v2/post/ REACT_APP_BACKEND_V2_POST_URL=https://json.excalidraw.com/api/v2/post/
REACT_APP_SOCKET_SERVER_URL=https://portal.excalidraw.com REACT_APP_SOCKET_SERVER_URL=https://excalidraw-socket.herokuapp.com
REACT_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyAd15pYlMci_xIp9ko6wkEsDzAAA0Dn0RU","authDomain":"excalidraw-room-persistence.firebaseapp.com","databaseURL":"https://excalidraw-room-persistence.firebaseio.com","projectId":"excalidraw-room-persistence","storageBucket":"excalidraw-room-persistence.appspot.com","messagingSenderId":"654800341332","appId":"1:654800341332:web:4a692de832b55bd57ce0c1"}' REACT_APP_FIREBASE_CONFIG='{"apiKey":"AIzaSyAd15pYlMci_xIp9ko6wkEsDzAAA0Dn0RU","authDomain":"excalidraw-room-persistence.firebaseapp.com","databaseURL":"https://excalidraw-room-persistence.firebaseio.com","projectId":"excalidraw-room-persistence","storageBucket":"excalidraw-room-persistence.appspot.com","messagingSenderId":"654800341332","appId":"1:654800341332:web:4a692de832b55bd57ce0c1"}'
+44 -44
View File
@@ -2663,70 +2663,70 @@
} }
}, },
"@sentry/browser": { "@sentry/browser": {
"version": "5.29.2", "version": "5.29.0",
"resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.29.2.tgz", "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-5.29.0.tgz",
"integrity": "sha512-uxZ7y7rp85tJll+RZtXRhXPbnFnOaxZqJEv05vJlXBtBNLQtlczV5iCtU9mZRLVHDtmZ5VVKUV8IKXntEqqDpQ==", "integrity": "sha512-kRlt1mE2wrYjspnIupNnPxqsUrRuy02SuXhbpP7J6uu8QasoEmJ78hk0hHz4jOZRmuWwfs2zIXD4tLGgWOKq8A==",
"requires": { "requires": {
"@sentry/core": "5.29.2", "@sentry/core": "5.29.0",
"@sentry/types": "5.29.2", "@sentry/types": "5.29.0",
"@sentry/utils": "5.29.2", "@sentry/utils": "5.29.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
} }
}, },
"@sentry/core": { "@sentry/core": {
"version": "5.29.2", "version": "5.29.0",
"resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.29.2.tgz", "resolved": "https://registry.npmjs.org/@sentry/core/-/core-5.29.0.tgz",
"integrity": "sha512-7WYkoxB5IdlNEbwOwqSU64erUKH4laavPsM0/yQ+jojM76ErxlgEF0u//p5WaLPRzh3iDSt6BH+9TL45oNZeZw==", "integrity": "sha512-a1sZBJ2u3NG0YDlGvOTwUCWiNjhfmDtAQiKK1o6RIIbcrWy9TlSps7CYDkBP239Y3A4pnvohjEEKEP3v3L3LZQ==",
"requires": { "requires": {
"@sentry/hub": "5.29.2", "@sentry/hub": "5.29.0",
"@sentry/minimal": "5.29.2", "@sentry/minimal": "5.29.0",
"@sentry/types": "5.29.2", "@sentry/types": "5.29.0",
"@sentry/utils": "5.29.2", "@sentry/utils": "5.29.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
} }
}, },
"@sentry/hub": { "@sentry/hub": {
"version": "5.29.2", "version": "5.29.0",
"resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.29.2.tgz", "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-5.29.0.tgz",
"integrity": "sha512-LaAIo2hwUk9ykeh9RF0cwLy6IRw+DjEee8l1HfEaDFUM6TPGlNNGObMJNXb9/95jzWp7jWwOpQjoIE3jepdQJQ==", "integrity": "sha512-kcDPQsRG4cFdmqDh+TzjeO7lWYxU8s1dZYAbbl1J4uGKmhNB0J7I4ak4SGwTsXLY6fhbierxr6PRaoNojCxjPw==",
"requires": { "requires": {
"@sentry/types": "5.29.2", "@sentry/types": "5.29.0",
"@sentry/utils": "5.29.2", "@sentry/utils": "5.29.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
} }
}, },
"@sentry/integrations": { "@sentry/integrations": {
"version": "5.29.2", "version": "5.29.0",
"resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-5.29.2.tgz", "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-5.29.0.tgz",
"integrity": "sha512-bH50B0xubbHrJFq8xZRxOc5BgXe1PXKfC0OqQkhhSd+Bu2WDLCHcn0CEzV+8thZTYkipAoFAFJNdEWcsM2Wcew==", "integrity": "sha512-SGqpi1Qd1a7gGL6aYrJnKqU/DNJcHvnhD3qOgow23ivEpaJv1BtQSKxv17IbO/CIFn3A0o1a18wY6xef9isKEQ==",
"requires": { "requires": {
"@sentry/types": "5.29.2", "@sentry/types": "5.29.0",
"@sentry/utils": "5.29.2", "@sentry/utils": "5.29.0",
"localforage": "1.8.1", "localforage": "1.8.1",
"tslib": "^1.9.3" "tslib": "^1.9.3"
} }
}, },
"@sentry/minimal": { "@sentry/minimal": {
"version": "5.29.2", "version": "5.29.0",
"resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.29.2.tgz", "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-5.29.0.tgz",
"integrity": "sha512-0aINSm8fGA1KyM7PavOBe1GDZDxrvnKt+oFnU0L+bTcw8Lr+of+v6Kwd97rkLRNOLw621xP076dL/7LSIzMuhw==", "integrity": "sha512-nhXofdjtO41/caiF1wk1oT3p/QuhOZDYdF/b29DoD2MiAMK9IjhhOXI/gqaRpDKkXlDvd95fDTcx4t/MqqcKXA==",
"requires": { "requires": {
"@sentry/hub": "5.29.2", "@sentry/hub": "5.29.0",
"@sentry/types": "5.29.2", "@sentry/types": "5.29.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
} }
}, },
"@sentry/types": { "@sentry/types": {
"version": "5.29.2", "version": "5.29.0",
"resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.29.2.tgz", "resolved": "https://registry.npmjs.org/@sentry/types/-/types-5.29.0.tgz",
"integrity": "sha512-dM9wgt8wy4WRty75QkqQgrw9FV9F+BOMfmc0iaX13Qos7i6Qs2Q0dxtJ83SoR4YGtW8URaHzlDtWlGs5egBiMA==" "integrity": "sha512-iDkxT/9sT3UF+Xb+JyLjZ5caMXsgLfRyV9VXQEiR2J6mgpMielj184d9jeF3bm/VMuAf/VFFqrHlcVsVgmrrMw=="
}, },
"@sentry/utils": { "@sentry/utils": {
"version": "5.29.2", "version": "5.29.0",
"resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.29.2.tgz", "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-5.29.0.tgz",
"integrity": "sha512-nEwQIDjtFkeE4k6yIk4Ka5XjGRklNLThWLs2xfXlL7uwrYOH2B9UBBOOIRUraBm/g/Xrra3xsam/kRxuiwtXZQ==", "integrity": "sha512-b2B1gshw2u3EHlAi84PuI5sfmLKXW1z9enMMhNuuNT/CoRp+g5kMAcUv/qYTws7UNnYSvTuVGuZG30v1e0hP9A==",
"requires": { "requires": {
"@sentry/types": "5.29.2", "@sentry/types": "5.29.0",
"tslib": "^1.9.3" "tslib": "^1.9.3"
} }
}, },
@@ -3030,9 +3030,9 @@
} }
}, },
"@testing-library/jest-dom": { "@testing-library/jest-dom": {
"version": "5.11.8", "version": "5.11.6",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.11.8.tgz", "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.11.6.tgz",
"integrity": "sha512-ScyKrWQM5xNcr79PkSewnA79CLaoxVskE+f7knTOhDD9ftZSA1Jw8mj+pneqhEu3x37ncNfW84NUr7lqK+mXjA==", "integrity": "sha512-cVZyUNRWwUKI0++yepYpYX7uhrP398I+tGz4zOlLVlUYnZS+Svuxv4fwLeCIy7TnBYKXUaOlQr3vopxL8ZfEnA==",
"requires": { "requires": {
"@babel/runtime": "^7.9.2", "@babel/runtime": "^7.9.2",
"@types/testing-library__jest-dom": "^5.9.1", "@types/testing-library__jest-dom": "^5.9.1",
@@ -9039,9 +9039,9 @@
} }
}, },
"firebase-tools": { "firebase-tools": {
"version": "9.1.0", "version": "9.0.1",
"resolved": "https://registry.npmjs.org/firebase-tools/-/firebase-tools-9.1.0.tgz", "resolved": "https://registry.npmjs.org/firebase-tools/-/firebase-tools-9.0.1.tgz",
"integrity": "sha512-hTfxL2meJSl5WuwAS6bEJ5nay7tu3MNYb4ZL2KmPL7yLM3IeT+Qd2z1evHhW1VvbDXKR6RTwlBxzdWPs4l75kA==", "integrity": "sha512-OktyHgjIBJR/JPNU4Xv4NsRLWu5gDnTmYd88VUsMwzUMCkbao2NNpeBi6+0rn6U1zNhwP2WW9PngccJWg/wvSA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@google-cloud/pubsub": "^2.7.0", "@google-cloud/pubsub": "^2.7.0",
@@ -10085,9 +10085,9 @@
} }
}, },
"@types/node": { "@types/node": {
"version": "12.19.11", "version": "12.19.9",
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.11.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.19.9.tgz",
"integrity": "sha512-bwVfNTFZOrGXyiQ6t4B9sZerMSShWNsGRw8tC5DY1qImUNczS9SjT4G6PnzjCnxsu5Ubj6xjL2lgwddkxtQl5w==", "integrity": "sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==",
"dev": true "dev": true
}, },
"ansi-styles": { "ansi-styles": {
+4 -4
View File
@@ -19,9 +19,9 @@
] ]
}, },
"dependencies": { "dependencies": {
"@sentry/browser": "5.29.2", "@sentry/browser": "5.29.0",
"@sentry/integrations": "5.29.2", "@sentry/integrations": "5.29.0",
"@testing-library/jest-dom": "5.11.8", "@testing-library/jest-dom": "5.11.6",
"@testing-library/react": "11.2.2", "@testing-library/react": "11.2.2",
"@types/jest": "26.0.19", "@types/jest": "26.0.19",
"@types/nanoid": "2.1.0", "@types/nanoid": "2.1.0",
@@ -54,7 +54,7 @@
"@types/pako": "1.0.1", "@types/pako": "1.0.1",
"eslint-config-prettier": "7.1.0", "eslint-config-prettier": "7.1.0",
"eslint-plugin-prettier": "3.3.0", "eslint-plugin-prettier": "3.3.0",
"firebase-tools": "9.1.0", "firebase-tools": "9.0.1",
"husky": "4.3.6", "husky": "4.3.6",
"jest-canvas-mock": "2.3.0", "jest-canvas-mock": "2.3.0",
"lint-staged": "10.5.3", "lint-staged": "10.5.3",
+9 -8
View File
@@ -24,7 +24,6 @@ const crowdinMap = {
"nl-NL": "en-nl", "nl-NL": "en-nl",
"nn-NO": "en-nnno", "nn-NO": "en-nnno",
"pl-PL": "en-pl", "pl-PL": "en-pl",
"pt-BR": "en-ptbr",
"pt-PT": "en-pt", "pt-PT": "en-pt",
"ro-RO": "en-ro", "ro-RO": "en-ro",
"ru-RU": "en-ru", "ru-RU": "en-ru",
@@ -58,7 +57,6 @@ const flags = {
"nl-NL": "🇳🇱", "nl-NL": "🇳🇱",
"nn-NO": "🇳🇴", "nn-NO": "🇳🇴",
"pl-PL": "🇵🇱", "pl-PL": "🇵🇱",
"pt-BR": "🇧🇷",
"pt-PT": "🇵🇹", "pt-PT": "🇵🇹",
"ro-RO": "🇷🇴", "ro-RO": "🇷🇴",
"ru-RU": "🇷🇺", "ru-RU": "🇷🇺",
@@ -92,7 +90,6 @@ const languages = {
"nl-NL": "Nederlands", "nl-NL": "Nederlands",
"nn-NO": "Norsk nynorsk", "nn-NO": "Norsk nynorsk",
"pl-PL": "Polski", "pl-PL": "Polski",
"pt-BR": "Português Brasileiro",
"pt-PT": "Português", "pt-PT": "Português",
"ro-RO": "Română", "ro-RO": "Română",
"ru-RU": "Русский", "ru-RU": "Русский",
@@ -117,14 +114,16 @@ const boldIf = (text, condition) => (condition ? `**${text}**` : text);
const printHeader = () => { const printHeader = () => {
let result = "| | Flag | Locale | % |\n"; let result = "| | Flag | Locale | % |\n";
result += "| :--: | :--: | -- | :--: |"; result += "| --: | :--: | -- | --: |";
return result; return result;
}; };
const printRow = (id, locale, coverage) => { const printRow = (id, locale, coverage) => {
const isOver = coverage >= THRESSHOLD; const isOver = coverage > THRESSHOLD;
let result = `| ${isOver ? id : "..."} | `; let result = `| ${boldIf(id, isOver)} | `;
result += `${locale in flags ? flags[locale] : ""} | `; result += `${locale in flags ? flags[locale] : ""} | `;
const language = locale in languages ? languages[locale] : locale; const language = locale in languages ? languages[locale] : locale;
if (locale in crowdinMap && crowdinMap[locale]) { if (locale in crowdinMap && crowdinMap[locale]) {
result += `[${boldIf( result += `[${boldIf(
@@ -134,12 +133,14 @@ const printRow = (id, locale, coverage) => {
} else { } else {
result += `${boldIf(language, isOver)} | `; result += `${boldIf(language, isOver)} | `;
} }
result += `${coverage === 100 ? "✅" : boldIf(coverage, isOver)} |`; result += `${boldIf(coverage, isOver)} |`;
return result; return result;
}; };
console.info("## Languages check");
console.info("\n\r");
console.info( console.info(
`Each language must be at least **${THRESSHOLD}%** translated in order to appear on Excalidraw. Join us on [Crowdin](https://crowdin.com/project/excalidraw) and help us translate your own language. **Can't find yours yet?** Open an [issue](https://github.com/excalidraw/excalidraw/issues/new) and we'll add it to the list.`, `Our translations for every languages should be at least **${THRESSHOLD}%** to appear on Excalidraw. Join our project in [Crowdin](https://crowdin.com/project/excalidraw) and help us translate it in your language. **Can't find your own?** Open an [issue](https://github.com/excalidraw/excalidraw/issues/new) and we'll add it to the list.`,
); );
console.info("\n\r"); console.info("\n\r");
console.info(printHeader()); console.info(printHeader());
+15 -16
View File
@@ -1,22 +1,23 @@
import React from "react"; import React from "react";
import { EVENT_ACTION, EVENT_CHANGE, trackEvent } from "../analytics";
import { getDefaultAppState } from "../appState";
import colors from "../colors";
import { ColorPicker } from "../components/ColorPicker"; import { ColorPicker } from "../components/ColorPicker";
import { resetZoom, trash, zoomIn, zoomOut } from "../components/icons"; import { getDefaultAppState } from "../appState";
import { trash, zoomIn, zoomOut, resetZoom } from "../components/icons";
import { ToolButton } from "../components/ToolButton"; import { ToolButton } from "../components/ToolButton";
import { getCommonBounds, getNonDeletedElements } from "../element"; import { t } from "../i18n";
import { getNormalizedZoom, getSelectedElements } from "../scene";
import { getNonDeletedElements } from "../element";
import { CODES, KEYS } from "../keys";
import { getShortcutKey } from "../utils";
import useIsMobile from "../is-mobile";
import { register } from "./register";
import { newElementWith } from "../element/mutateElement"; import { newElementWith } from "../element/mutateElement";
import { ExcalidrawElement } from "../element/types"; import { ExcalidrawElement } from "../element/types";
import { t } from "../i18n";
import useIsMobile from "../is-mobile";
import { CODES, KEYS } from "../keys";
import { getNormalizedZoom, getSelectedElements } from "../scene";
import { centerScrollOn } from "../scene/scroll";
import { getNewZoom } from "../scene/zoom";
import { AppState, NormalizedZoomValue } from "../types"; import { AppState, NormalizedZoomValue } from "../types";
import { getNewSceneName, getShortcutKey } from "../utils"; import { getCommonBounds } from "../element";
import { register } from "./register"; import { getNewZoom } from "../scene/zoom";
import { centerScrollOn } from "../scene/scroll";
import { EVENT_ACTION, EVENT_CHANGE, trackEvent } from "../analytics";
import colors from "../colors";
export const actionChangeViewBackgroundColor = register({ export const actionChangeViewBackgroundColor = register({
name: "changeViewBackgroundColor", name: "changeViewBackgroundColor",
@@ -59,15 +60,13 @@ export const actionClearCanvas = register({
), ),
appState: { appState: {
...getDefaultAppState(), ...getDefaultAppState(),
name: getNewSceneName(),
appearance: appState.appearance, appearance: appState.appearance,
elementLocked: appState.elementLocked, elementLocked: appState.elementLocked,
exportBackground: appState.exportBackground, exportBackground: appState.exportBackground,
exportEmbedScene: appState.exportEmbedScene, exportEmbedScene: appState.exportEmbedScene,
gridSize: appState.gridSize, showGrid: appState.showGrid,
shouldAddWatermark: appState.shouldAddWatermark, shouldAddWatermark: appState.shouldAddWatermark,
showStats: appState.showStats, showStats: appState.showStats,
pasteDialog: appState.pasteDialog,
}, },
commitToHistory: true, commitToHistory: true,
}; };
+1 -2
View File
@@ -12,7 +12,6 @@ import { KEYS } from "../keys";
import { muteFSAbortError } from "../utils"; import { muteFSAbortError } from "../utils";
import { register } from "./register"; import { register } from "./register";
import "../components/ToolIcon.scss"; import "../components/ToolIcon.scss";
import { SCENE_NAME_FALLBACK } from "../constants";
export const actionChangeProjectName = register({ export const actionChangeProjectName = register({
name: "changeProjectName", name: "changeProjectName",
@@ -23,7 +22,7 @@ export const actionChangeProjectName = register({
PanelComponent: ({ appState, updateData }) => ( PanelComponent: ({ appState, updateData }) => (
<ProjectName <ProjectName
label={t("labels.fileTitle")} label={t("labels.fileTitle")}
value={appState.name || SCENE_NAME_FALLBACK} value={appState.name || "Unnamed"}
onChange={(name: string) => updateData(name)} onChange={(name: string) => updateData(name)}
/> />
), ),
+71 -76
View File
@@ -1,84 +1,79 @@
import oc from "open-color"; import oc from "open-color";
import { AppState, FlooredNumber, NormalizedZoomValue } from "./types";
import { getDateTime } from "./utils";
import { t } from "./i18n";
import { import {
DEFAULT_FONT_FAMILY,
DEFAULT_FONT_SIZE, DEFAULT_FONT_SIZE,
SCENE_NAME_FALLBACK, DEFAULT_FONT_FAMILY,
DEFAULT_TEXT_ALIGN, DEFAULT_TEXT_ALIGN,
} from "./constants"; } from "./constants";
import { AppState, FlooredNumber, NormalizedZoomValue } from "./types";
type DefaultAppState = Omit<AppState, "offsetTop" | "offsetLeft" | "name"> & { export const getDefaultAppState = (): Omit<
/** AppState,
* You should override this with current appState.name, or whatever is "offsetTop" | "offsetLeft"
* applicable at a given place where you get default appState. > => {
*/
name: undefined;
};
export const getDefaultAppState = (): DefaultAppState => {
return { return {
appearance: "light", appearance: "light",
collaborators: new Map(), isLoading: false,
currentChartType: "bar",
currentItemBackgroundColor: "transparent",
currentItemEndArrowhead: "arrow",
currentItemFillStyle: "hachure",
currentItemFontFamily: DEFAULT_FONT_FAMILY,
currentItemFontSize: DEFAULT_FONT_SIZE,
currentItemLinearStrokeSharpness: "round",
currentItemOpacity: 100,
currentItemRoughness: 1,
currentItemStartArrowhead: null,
currentItemStrokeColor: oc.black,
currentItemStrokeSharpness: "sharp",
currentItemStrokeStyle: "solid",
currentItemStrokeWidth: 1,
currentItemTextAlign: DEFAULT_TEXT_ALIGN,
cursorButton: "up",
draggingElement: null,
editingElement: null,
editingGroupId: null,
editingLinearElement: null,
elementLocked: false,
elementType: "selection",
errorMessage: null, errorMessage: null,
draggingElement: null,
resizingElement: null,
multiElement: null,
editingElement: null,
startBoundElement: null,
editingLinearElement: null,
elementType: "selection",
elementLocked: false,
exportBackground: true, exportBackground: true,
exportEmbedScene: false, exportEmbedScene: false,
fileHandle: null, shouldAddWatermark: false,
gridSize: null, currentItemStrokeColor: oc.black,
height: window.innerHeight, currentItemBackgroundColor: "transparent",
isBindingEnabled: true, currentItemFillStyle: "hachure",
isLibraryOpen: false, currentItemStrokeWidth: 1,
isLoading: false, currentItemStrokeStyle: "solid",
isResizing: false, currentItemRoughness: 1,
isRotating: false, currentItemOpacity: 100,
lastPointerDownWith: "mouse", currentItemFontSize: DEFAULT_FONT_SIZE,
multiElement: null, currentItemFontFamily: DEFAULT_FONT_FAMILY,
// for safety (because TS mostly doesn't distinguish optional types and currentItemTextAlign: DEFAULT_TEXT_ALIGN,
// undefined values), we set `name` to the fallback name, but we cast it to currentItemStrokeSharpness: "sharp",
// `undefined` so that TS forces us to explicitly specify it wherever currentItemLinearStrokeSharpness: "round",
// possible currentItemStartArrowhead: null,
name: (SCENE_NAME_FALLBACK as unknown) as undefined, currentItemEndArrowhead: "arrow",
openMenu: null, viewBackgroundColor: oc.white,
pasteDialog: { shown: false, data: null },
previousSelectedElementIds: {},
resizingElement: null,
scrolledOutside: false,
scrollX: 0 as FlooredNumber, scrollX: 0 as FlooredNumber,
scrollY: 0 as FlooredNumber, scrollY: 0 as FlooredNumber,
selectedElementIds: {}, cursorX: 0,
selectedGroupIds: {}, cursorY: 0,
cursorButton: "up",
scrolledOutside: false,
name: `${t("labels.untitled")}-${getDateTime()}`,
isBindingEnabled: true,
isResizing: false,
isRotating: false,
selectionElement: null, selectionElement: null,
shouldAddWatermark: false, zoom: {
value: 1 as NormalizedZoomValue,
translation: { x: 0, y: 0 },
},
openMenu: null,
lastPointerDownWith: "mouse",
selectedElementIds: {},
previousSelectedElementIds: {},
shouldCacheIgnoreZoom: false, shouldCacheIgnoreZoom: false,
showShortcutsDialog: false, showShortcutsDialog: false,
showStats: false,
startBoundElement: null,
suggestedBindings: [], suggestedBindings: [],
viewBackgroundColor: oc.white,
width: window.innerWidth,
zenModeEnabled: false, zenModeEnabled: false,
zoom: { value: 1 as NormalizedZoomValue, translation: { x: 0, y: 0 } }, showGrid: false,
editingGroupId: null,
selectedGroupIds: {},
width: window.innerWidth,
height: window.innerHeight,
isLibraryOpen: false,
fileHandle: null,
collaborators: new Map(),
showStats: false,
}; };
}; };
@@ -98,25 +93,26 @@ const APP_STATE_STORAGE_CONF = (<
config: { [K in keyof T]: K extends keyof AppState ? T[K] : never }, config: { [K in keyof T]: K extends keyof AppState ? T[K] : never },
) => config)({ ) => config)({
appearance: { browser: true, export: false }, appearance: { browser: true, export: false },
collaborators: { browser: false, export: false },
currentChartType: { browser: true, export: false },
currentItemBackgroundColor: { browser: true, export: false }, currentItemBackgroundColor: { browser: true, export: false },
currentItemEndArrowhead: { browser: true, export: false },
currentItemFillStyle: { browser: true, export: false }, currentItemFillStyle: { browser: true, export: false },
currentItemFontFamily: { browser: true, export: false }, currentItemFontFamily: { browser: true, export: false },
currentItemFontSize: { browser: true, export: false }, currentItemFontSize: { browser: true, export: false },
currentItemLinearStrokeSharpness: { browser: true, export: false },
currentItemOpacity: { browser: true, export: false }, currentItemOpacity: { browser: true, export: false },
currentItemRoughness: { browser: true, export: false }, currentItemRoughness: { browser: true, export: false },
currentItemStartArrowhead: { browser: true, export: false },
currentItemStrokeColor: { browser: true, export: false }, currentItemStrokeColor: { browser: true, export: false },
currentItemStrokeSharpness: { browser: true, export: false },
currentItemStrokeStyle: { browser: true, export: false }, currentItemStrokeStyle: { browser: true, export: false },
currentItemStrokeWidth: { browser: true, export: false }, currentItemStrokeWidth: { browser: true, export: false },
currentItemTextAlign: { browser: true, export: false }, currentItemTextAlign: { browser: true, export: false },
currentItemStrokeSharpness: { browser: true, export: false },
currentItemLinearStrokeSharpness: { browser: true, export: false },
currentItemStartArrowhead: { browser: true, export: false },
currentItemEndArrowhead: { browser: true, export: false },
cursorButton: { browser: true, export: false }, cursorButton: { browser: true, export: false },
cursorX: { browser: true, export: false },
cursorY: { browser: true, export: false },
draggingElement: { browser: false, export: false }, draggingElement: { browser: false, export: false },
editingElement: { browser: false, export: false }, editingElement: { browser: false, export: false },
startBoundElement: { browser: false, export: false },
editingGroupId: { browser: true, export: false }, editingGroupId: { browser: true, export: false },
editingLinearElement: { browser: false, export: false }, editingLinearElement: { browser: false, export: false },
elementLocked: { browser: true, export: false }, elementLocked: { browser: true, export: false },
@@ -124,8 +120,7 @@ const APP_STATE_STORAGE_CONF = (<
errorMessage: { browser: false, export: false }, errorMessage: { browser: false, export: false },
exportBackground: { browser: true, export: false }, exportBackground: { browser: true, export: false },
exportEmbedScene: { browser: true, export: false }, exportEmbedScene: { browser: true, export: false },
fileHandle: { browser: false, export: false }, showGrid: { browser: true, export: false },
gridSize: { browser: true, export: true },
height: { browser: false, export: false }, height: { browser: false, export: false },
isBindingEnabled: { browser: false, export: false }, isBindingEnabled: { browser: false, export: false },
isLibraryOpen: { browser: false, export: false }, isLibraryOpen: { browser: false, export: false },
@@ -135,10 +130,7 @@ const APP_STATE_STORAGE_CONF = (<
lastPointerDownWith: { browser: true, export: false }, lastPointerDownWith: { browser: true, export: false },
multiElement: { browser: false, export: false }, multiElement: { browser: false, export: false },
name: { browser: true, export: false }, name: { browser: true, export: false },
offsetLeft: { browser: false, export: false },
offsetTop: { browser: false, export: false },
openMenu: { browser: true, export: false }, openMenu: { browser: true, export: false },
pasteDialog: { browser: false, export: false },
previousSelectedElementIds: { browser: true, export: false }, previousSelectedElementIds: { browser: true, export: false },
resizingElement: { browser: false, export: false }, resizingElement: { browser: false, export: false },
scrolledOutside: { browser: true, export: false }, scrolledOutside: { browser: true, export: false },
@@ -150,13 +142,16 @@ const APP_STATE_STORAGE_CONF = (<
shouldAddWatermark: { browser: true, export: false }, shouldAddWatermark: { browser: true, export: false },
shouldCacheIgnoreZoom: { browser: true, export: false }, shouldCacheIgnoreZoom: { browser: true, export: false },
showShortcutsDialog: { browser: false, export: false }, showShortcutsDialog: { browser: false, export: false },
showStats: { browser: true, export: false },
startBoundElement: { browser: false, export: false },
suggestedBindings: { browser: false, export: false }, suggestedBindings: { browser: false, export: false },
viewBackgroundColor: { browser: true, export: true }, viewBackgroundColor: { browser: true, export: true },
width: { browser: false, export: false }, width: { browser: false, export: false },
zenModeEnabled: { browser: true, export: false }, zenModeEnabled: { browser: true, export: false },
zoom: { browser: true, export: false }, zoom: { browser: true, export: false },
offsetTop: { browser: false, export: false },
offsetLeft: { browser: false, export: false },
fileHandle: { browser: false, export: false },
collaborators: { browser: false, export: false },
showStats: { browser: true, export: false },
}); });
const _clearAppStateForStorage = <ExportType extends "export" | "browser">( const _clearAppStateForStorage = <ExportType extends "export" | "browser">(
+75 -271
View File
@@ -1,16 +1,13 @@
import { EVENT_MAGIC, trackEvent } from "./analytics"; import { EVENT_MAGIC, trackEvent } from "./analytics";
import colors from "./colors"; import colors from "./colors";
import { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, ENV } from "./constants"; import { DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE } from "./constants";
import { newElement, newLinearElement, newTextElement } from "./element"; import { newElement, newTextElement, newLinearElement } from "./element";
import { NonDeletedExcalidrawElement } from "./element/types"; import { ExcalidrawElement } from "./element/types";
import { randomId } from "./random"; import { randomId } from "./random";
export type ChartElements = readonly NonDeletedExcalidrawElement[];
const BAR_WIDTH = 32; const BAR_WIDTH = 32;
const BAR_GAP = 12; const BAR_GAP = 12;
const BAR_HEIGHT = 256; const BAR_HEIGHT = 256;
const GRID_OPACITY = 50;
export interface Spreadsheet { export interface Spreadsheet {
title: string | null; title: string | null;
@@ -142,72 +139,41 @@ export const tryParseSpreadsheet = (text: string): ParseSpreadsheetResult => {
return transposedResults; return transposedResults;
} }
} }
return result; return result;
}; };
const bgColors = colors.elementBackground.slice( // For the maths behind it https://excalidraw.com/#json=6320864370884608,O_5xfD-Agh32tytHpRJx1g
2, export const renderSpreadsheet = (
colors.elementBackground.length, spreadsheet: Spreadsheet,
); x: number,
y: number,
// Put all the common properties here so when the whole chart is selected ): ExcalidrawElement[] => {
// the properties dialog shows the correct selected values const values = spreadsheet.values;
const commonProps = { const max = Math.max(...values);
fillStyle: "hachure",
fontFamily: DEFAULT_FONT_FAMILY,
fontSize: DEFAULT_FONT_SIZE,
opacity: 100,
roughness: 1,
strokeColor: colors.elementStroke[0],
strokeSharpness: "sharp",
strokeStyle: "solid",
strokeWidth: 1,
verticalAlign: "middle",
} as const;
const getChartDimentions = (spreadsheet: Spreadsheet) => {
const chartWidth =
(BAR_WIDTH + BAR_GAP) * spreadsheet.values.length + BAR_GAP;
const chartHeight = BAR_HEIGHT + BAR_GAP * 2; const chartHeight = BAR_HEIGHT + BAR_GAP * 2;
return { chartWidth, chartHeight }; const chartWidth = (BAR_WIDTH + BAR_GAP) * values.length + BAR_GAP;
}; const maxColors = colors.elementBackground.length;
const bgColors = colors.elementBackground.slice(2, maxColors);
const chartXLabels = ( // Put all the common properties here so when the whole chart is selected
spreadsheet: Spreadsheet, // the properties dialog shows the correct selected values
x: number, const commonProps = {
y: number, backgroundColor: bgColors[Math.floor(Math.random() * bgColors.length)],
groupId: string, fillStyle: "hachure",
backgroundColor: string, fontFamily: DEFAULT_FONT_FAMILY,
): ChartElements => { fontSize: DEFAULT_FONT_SIZE,
return ( groupIds: [randomId()],
spreadsheet.labels?.map((label, index) => { opacity: 100,
return newTextElement({ roughness: 1,
groupIds: [groupId], strokeColor: colors.elementStroke[0],
backgroundColor, strokeSharpness: "sharp",
...commonProps, strokeStyle: "solid",
text: label.length > 8 ? `${label.slice(0, 5)}...` : label, strokeWidth: 1,
x: x + index * (BAR_WIDTH + BAR_GAP) + BAR_GAP * 2, verticalAlign: "middle",
y: y + BAR_GAP / 2, } as const;
width: BAR_WIDTH,
angle: 5.87,
fontSize: 16,
textAlign: "center",
verticalAlign: "top",
});
}) || []
);
};
const chartYLabels = (
spreadsheet: Spreadsheet,
x: number,
y: number,
groupId: string,
backgroundColor: string,
): ChartElements => {
const minYLabel = newTextElement({ const minYLabel = newTextElement({
groupIds: [groupId],
backgroundColor,
...commonProps, ...commonProps,
x: x - BAR_GAP, x: x - BAR_GAP,
y: y - BAR_GAP, y: y - BAR_GAP,
@@ -216,30 +182,14 @@ const chartYLabels = (
}); });
const maxYLabel = newTextElement({ const maxYLabel = newTextElement({
groupIds: [groupId],
backgroundColor,
...commonProps, ...commonProps,
x: x - BAR_GAP, x: x - BAR_GAP,
y: y - BAR_HEIGHT - minYLabel.height / 2, y: y - BAR_HEIGHT - minYLabel.height / 2,
text: Math.max(...spreadsheet.values).toLocaleString(), text: max.toLocaleString(),
textAlign: "right", textAlign: "right",
}); });
return [minYLabel, maxYLabel]; const xAxisLine = newLinearElement({
};
const chartLines = (
spreadsheet: Spreadsheet,
x: number,
y: number,
groupId: string,
backgroundColor: string,
): ChartElements => {
const { chartWidth, chartHeight } = getChartDimentions(spreadsheet);
const xLine = newLinearElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "line", type: "line",
x, x,
y, y,
@@ -250,12 +200,10 @@ const chartLines = (
[0, 0], [0, 0],
[chartWidth, 0], [chartWidth, 0],
], ],
...commonProps,
}); });
const yLine = newLinearElement({ const yAxisLine = newLinearElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "line", type: "line",
x, x,
y, y,
@@ -266,93 +214,27 @@ const chartLines = (
[0, 0], [0, 0],
[0, -chartHeight], [0, -chartHeight],
], ],
...commonProps,
}); });
const maxLine = newLinearElement({ const maxValueLine = newLinearElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "line", type: "line",
x, x,
y: y - BAR_HEIGHT - BAR_GAP, y: y - BAR_HEIGHT - BAR_GAP,
startArrowhead: null, startArrowhead: null,
endArrowhead: null, endArrowhead: null,
...commonProps,
strokeStyle: "dotted", strokeStyle: "dotted",
width: chartWidth, width: chartWidth,
opacity: GRID_OPACITY,
points: [ points: [
[0, 0], [0, 0],
[chartWidth, 0], [chartWidth, 0],
], ],
}); });
return [xLine, yLine, maxLine]; const bars = values.map((value, index) => {
};
// For the maths behind it https://excalidraw.com/#json=6320864370884608,O_5xfD-Agh32tytHpRJx1g
const chartBaseElements = (
spreadsheet: Spreadsheet,
x: number,
y: number,
groupId: string,
backgroundColor: string,
debug?: boolean,
): ChartElements => {
const { chartWidth, chartHeight } = getChartDimentions(spreadsheet);
const title = spreadsheet.title
? newTextElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
text: spreadsheet.title,
x: x + chartWidth / 2,
y: y - BAR_HEIGHT - BAR_GAP * 2 - DEFAULT_FONT_SIZE,
strokeSharpness: "sharp",
strokeStyle: "solid",
textAlign: "center",
})
: null;
const debugRect = debug
? newElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "rectangle",
x,
y: y - chartHeight,
width: chartWidth,
height: chartHeight,
strokeColor: colors.elementStroke[0],
fillStyle: "solid",
opacity: 6,
})
: null;
return [
...(debugRect ? [debugRect] : []),
...(title ? [title] : []),
...chartXLabels(spreadsheet, x, y, groupId, backgroundColor),
...chartYLabels(spreadsheet, x, y, groupId, backgroundColor),
...chartLines(spreadsheet, x, y, groupId, backgroundColor),
];
};
const chartTypeBar = (
spreadsheet: Spreadsheet,
x: number,
y: number,
): ChartElements => {
const max = Math.max(...spreadsheet.values);
const groupId = randomId();
const backgroundColor = bgColors[Math.floor(Math.random() * bgColors.length)];
const bars = spreadsheet.values.map((value, index) => {
const barHeight = (value / max) * BAR_HEIGHT; const barHeight = (value / max) * BAR_HEIGHT;
return newElement({ return newElement({
backgroundColor,
groupIds: [groupId],
...commonProps, ...commonProps,
type: "rectangle", type: "rectangle",
x: x + index * (BAR_WIDTH + BAR_GAP) + BAR_GAP, x: x + index * (BAR_WIDTH + BAR_GAP) + BAR_GAP,
@@ -362,120 +244,42 @@ const chartTypeBar = (
}); });
}); });
const xLabels =
spreadsheet.labels?.map((label, index) => {
return newTextElement({
...commonProps,
text: label.length > 8 ? `${label.slice(0, 5)}...` : label,
x: x + index * (BAR_WIDTH + BAR_GAP) + BAR_GAP * 2,
y: y + BAR_GAP / 2,
width: BAR_WIDTH,
angle: 5.87,
fontSize: 16,
textAlign: "center",
verticalAlign: "top",
});
}) || [];
const title = spreadsheet.title
? newTextElement({
...commonProps,
text: spreadsheet.title,
x: x + chartWidth / 2,
y: y - BAR_HEIGHT - BAR_GAP * 2 - maxYLabel.height,
strokeSharpness: "sharp",
strokeStyle: "solid",
textAlign: "center",
})
: null;
trackEvent(EVENT_MAGIC, "chart", "bars", bars.length);
return [ return [
title,
...bars, ...bars,
...chartBaseElements( ...xLabels,
spreadsheet, xAxisLine,
x, yAxisLine,
y, maxValueLine,
groupId, minYLabel,
backgroundColor, maxYLabel,
process.env.NODE_ENV === ENV.DEVELOPMENT, ].filter((element) => element !== null) as ExcalidrawElement[];
),
];
};
const chartTypeLine = (
spreadsheet: Spreadsheet,
x: number,
y: number,
): ChartElements => {
const max = Math.max(...spreadsheet.values);
const groupId = randomId();
const backgroundColor = bgColors[Math.floor(Math.random() * bgColors.length)];
let index = 0;
const points = [];
for (const value of spreadsheet.values) {
const cx = index * (BAR_WIDTH + BAR_GAP);
const cy = -(value / max) * BAR_HEIGHT;
points.push([cx, cy]);
index++;
}
const maxX = Math.max(...points.map((element) => element[0]));
const maxY = Math.max(...points.map((element) => element[1]));
const minX = Math.min(...points.map((element) => element[0]));
const minY = Math.min(...points.map((element) => element[1]));
const line = newLinearElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "line",
x: x + BAR_GAP + BAR_WIDTH / 2,
y: y - BAR_GAP,
startArrowhead: null,
endArrowhead: null,
height: maxY - minY,
width: maxX - minX,
strokeWidth: 2,
points: points as any,
});
const dots = spreadsheet.values.map((value, index) => {
const cx = index * (BAR_WIDTH + BAR_GAP) + BAR_GAP / 2;
const cy = -(value / max) * BAR_HEIGHT + BAR_GAP / 2;
return newElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
fillStyle: "solid",
strokeWidth: 2,
type: "ellipse",
x: x + cx + BAR_WIDTH / 2,
y: y + cy - BAR_GAP * 2,
width: BAR_GAP,
height: BAR_GAP,
});
});
const lines = spreadsheet.values.map((value, index) => {
const cx = index * (BAR_WIDTH + BAR_GAP) + BAR_GAP / 2;
const cy = (value / max) * BAR_HEIGHT + BAR_GAP / 2 + BAR_GAP;
return newLinearElement({
backgroundColor,
groupIds: [groupId],
...commonProps,
type: "line",
x: x + cx + BAR_WIDTH / 2 + BAR_GAP / 2,
y: y - cy,
startArrowhead: null,
endArrowhead: null,
height: cy,
strokeStyle: "dotted",
opacity: GRID_OPACITY,
points: [
[0, 0],
[0, cy],
],
});
});
return [
...chartBaseElements(
spreadsheet,
x,
y,
groupId,
backgroundColor,
process.env.NODE_ENV === ENV.DEVELOPMENT,
),
line,
...lines,
...dots,
];
};
export const renderSpreadsheet = (
chartType: string,
spreadsheet: Spreadsheet,
x: number,
y: number,
): ChartElements => {
trackEvent(EVENT_MAGIC, "chart", chartType, spreadsheet.values.length);
if (chartType === "line") {
return chartTypeLine(spreadsheet, x, y);
}
return chartTypeBar(spreadsheet, x, y);
}; };
+178 -190
View File
@@ -1,168 +1,181 @@
import { Point, simplify } from "points-on-curve";
import React from "react"; import React from "react";
import { RoughCanvas } from "roughjs/bin/canvas";
import rough from "roughjs/bin/rough"; import rough from "roughjs/bin/rough";
import "../actions"; import { RoughCanvas } from "roughjs/bin/canvas";
import { actionDeleteSelected, actionFinalize } from "../actions"; import { simplify, Point } from "points-on-curve";
import { createRedoAction, createUndoAction } from "../actions/actionHistory";
import { ActionManager } from "../actions/manager";
import { actions } from "../actions/register";
import { ActionResult } from "../actions/types";
import { import {
EVENT_DIALOG, newElement,
EVENT_LIBRARY, newTextElement,
EVENT_SHAPE, duplicateElement,
trackEvent, isInvisiblySmallElement,
} from "../analytics"; isTextElement,
textWysiwyg,
getCommonBounds,
getCursorForResizingElement,
getPerfectElementSize,
getNormalizedDimensions,
newLinearElement,
transformElements,
getElementWithTransformHandleType,
getResizeOffsetXY,
getResizeArrowDirection,
getTransformHandleTypeFromCoords,
isNonDeletedElement,
updateTextElement,
dragSelectedElements,
getDragOffsetXY,
dragNewElement,
hitTest,
isHittingElementBoundingBoxWithoutHittingElement,
getNonDeletedElements,
} from "../element";
import {
getElementsWithinSelection,
isOverScrollBars,
getElementsAtPosition,
getElementContainingPosition,
getNormalizedZoom,
getSelectedElements,
isSomeElementSelected,
calculateScrollCenter,
} from "../scene";
import { loadFromBlob, exportCanvas } from "../data";
import { renderScene } from "../renderer";
import {
AppState,
GestureEvent,
Gesture,
ExcalidrawProps,
SceneData,
} from "../types";
import {
ExcalidrawElement,
ExcalidrawTextElement,
NonDeleted,
ExcalidrawGenericElement,
ExcalidrawLinearElement,
ExcalidrawBindableElement,
} from "../element/types";
import { distance2d, isPathALoop, getGridPoint } from "../math";
import {
isWritableElement,
isInputLike,
isToolIcon,
debounce,
distance,
resetCursor,
viewportCoordsToSceneCoords,
sceneCoordsToViewportCoords,
setCursorForShape,
tupleToCoors,
ResolvablePromise,
resolvablePromise,
withBatchedUpdates,
} from "../utils";
import {
KEYS,
isArrowKey,
getResizeCenterPointKey,
getResizeWithSidesSameLengthKey,
getRotateWithDiscreteAngleKey,
CODES,
} from "../keys";
import { findShapeByKey } from "../shapes";
import { createHistory, SceneHistory } from "../history";
import ContextMenu from "./ContextMenu";
import { ActionManager } from "../actions/manager";
import "../actions";
import { actions } from "../actions/register";
import { ActionResult } from "../actions/types";
import { getDefaultAppState } from "../appState"; import { getDefaultAppState } from "../appState";
import { t, getLanguage } from "../i18n";
import { import {
copyToClipboard, copyToClipboard,
parseClipboard, parseClipboard,
probablySupportsClipboardBlob, probablySupportsClipboardBlob,
probablySupportsClipboardWriteText, probablySupportsClipboardWriteText,
} from "../clipboard"; } from "../clipboard";
import { normalizeScroll } from "../scene";
import { getCenter, getDistance } from "../gesture";
import { createUndoAction, createRedoAction } from "../actions/actionHistory";
import { import {
APP_NAME,
CANVAS_ONLY_ACTIONS,
CURSOR_TYPE, CURSOR_TYPE,
DEFAULT_VERTICAL_ALIGN,
DRAGGING_THRESHOLD,
ELEMENT_SHIFT_TRANSLATE_AMOUNT, ELEMENT_SHIFT_TRANSLATE_AMOUNT,
ELEMENT_TRANSLATE_AMOUNT, ELEMENT_TRANSLATE_AMOUNT,
ENV,
EVENT,
GRID_SIZE,
LINE_CONFIRM_THRESHOLD,
MIME_TYPES,
POINTER_BUTTON, POINTER_BUTTON,
TAP_TWICE_TIMEOUT, DRAGGING_THRESHOLD,
TEXT_TO_CENTER_SNAP_THRESHOLD, TEXT_TO_CENTER_SNAP_THRESHOLD,
LINE_CONFIRM_THRESHOLD,
EVENT,
ENV,
CANVAS_ONLY_ACTIONS,
DEFAULT_VERTICAL_ALIGN,
GRID_SIZE,
MIME_TYPES,
TAP_TWICE_TIMEOUT,
TOUCH_CTX_MENU_TIMEOUT, TOUCH_CTX_MENU_TIMEOUT,
APP_NAME,
} from "../constants"; } from "../constants";
import { exportCanvas, loadFromBlob } from "../data";
import { isValidLibrary } from "../data/json"; import LayerUI from "./LayerUI";
import { Library } from "../data/library"; import { ScrollBars, SceneState } from "../scene/types";
import { restore } from "../data/restore";
import {
dragNewElement,
dragSelectedElements,
duplicateElement,
getCommonBounds,
getCursorForResizingElement,
getDragOffsetXY,
getElementWithTransformHandleType,
getNonDeletedElements,
getNormalizedDimensions,
getPerfectElementSize,
getResizeArrowDirection,
getResizeOffsetXY,
getTransformHandleTypeFromCoords,
hitTest,
isHittingElementBoundingBoxWithoutHittingElement,
isInvisiblySmallElement,
isNonDeletedElement,
isTextElement,
newElement,
newLinearElement,
newTextElement,
textWysiwyg,
transformElements,
updateTextElement,
} from "../element";
import {
bindOrUnbindSelectedElements,
fixBindingsAfterDeletion,
fixBindingsAfterDuplication,
getEligibleElementsForBinding,
getHoveredElementForBinding,
isBindingEnabled,
isLinearElementSimpleAndAlreadyBound,
maybeBindLinearElement,
shouldEnableBindingForPointerEvent,
unbindLinearElements,
updateBoundElements,
} from "../element/binding";
import { LinearElementEditor } from "../element/linearElementEditor";
import { mutateElement } from "../element/mutateElement"; import { mutateElement } from "../element/mutateElement";
import { deepCopyElement } from "../element/newElement";
import { MaybeTransformHandleType } from "../element/transformHandles";
import {
isBindingElement,
isBindingElementType,
isLinearElement,
isLinearElementType,
} from "../element/typeChecks";
import {
ExcalidrawBindableElement,
ExcalidrawElement,
ExcalidrawGenericElement,
ExcalidrawLinearElement,
ExcalidrawTextElement,
NonDeleted,
} from "../element/types";
import { getCenter, getDistance } from "../gesture";
import {
editGroupForSelectedElement,
getElementsInGroup,
getSelectedGroupIdForElement,
getSelectedGroupIds,
isElementInGroup,
isSelectedViaGroup,
selectGroupsForSelectedElements,
} from "../groups";
import { createHistory, SceneHistory } from "../history";
import { t, getLanguage, setLanguage, languages, defaultLang } from "../i18n";
import {
CODES,
getResizeCenterPointKey,
getResizeWithSidesSameLengthKey,
getRotateWithDiscreteAngleKey,
isArrowKey,
KEYS,
} from "../keys";
import { distance2d, getGridPoint, isPathALoop } from "../math";
import { renderScene } from "../renderer";
import { invalidateShapeForElement } from "../renderer/renderElement"; import { invalidateShapeForElement } from "../renderer/renderElement";
import { import {
calculateScrollCenter, isLinearElement,
getElementContainingPosition, isLinearElementType,
getElementsAtPosition, isBindingElement,
getElementsWithinSelection, isBindingElementType,
getNormalizedZoom, } from "../element/typeChecks";
getSelectedElements, import { actionFinalize, actionDeleteSelected } from "../actions";
isOverScrollBars,
isSomeElementSelected, import { LinearElementEditor } from "../element/linearElementEditor";
normalizeScroll, import {
} from "../scene"; getSelectedGroupIds,
isSelectedViaGroup,
selectGroupsForSelectedElements,
isElementInGroup,
getSelectedGroupIdForElement,
getElementsInGroup,
editGroupForSelectedElement,
} from "../groups";
import { Library } from "../data/library";
import Scene from "../scene/Scene"; import Scene from "../scene/Scene";
import { SceneState, ScrollBars } from "../scene/types"; import {
getHoveredElementForBinding,
maybeBindLinearElement,
getEligibleElementsForBinding,
bindOrUnbindSelectedElements,
unbindLinearElements,
fixBindingsAfterDuplication,
fixBindingsAfterDeletion,
isLinearElementSimpleAndAlreadyBound,
isBindingEnabled,
updateBoundElements,
shouldEnableBindingForPointerEvent,
} from "../element/binding";
import { MaybeTransformHandleType } from "../element/transformHandles";
import { deepCopyElement } from "../element/newElement";
import { renderSpreadsheet } from "../charts";
import { isValidLibrary } from "../data/json";
import { getNewZoom } from "../scene/zoom"; import { getNewZoom } from "../scene/zoom";
import { findShapeByKey } from "../shapes"; import { restore } from "../data/restore";
import { import {
AppState, EVENT_DIALOG,
ExcalidrawProps, EVENT_LIBRARY,
Gesture, EVENT_SHAPE,
GestureEvent, trackEvent,
SceneData, } from "../analytics";
} from "../types";
import {
debounce,
distance,
getNewSceneName,
isInputLike,
isToolIcon,
isWritableElement,
resetCursor,
ResolvablePromise,
resolvablePromise,
sceneCoordsToViewportCoords,
setCursorForShape,
tupleToCoors,
viewportCoordsToSceneCoords,
withBatchedUpdates,
} from "../utils";
import ContextMenu from "./ContextMenu";
import LayerUI from "./LayerUI";
import { Stats } from "./Stats"; import { Stats } from "./Stats";
const { history } = createHistory(); const { history } = createHistory();
@@ -282,7 +295,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
} = props; } = props;
this.state = { this.state = {
...defaultAppState, ...defaultAppState,
name: getNewSceneName(),
isLoading: true, isLoading: true,
width, width,
height, height,
@@ -334,7 +346,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
offsetLeft, offsetLeft,
} = this.state; } = this.state;
const { onCollabButtonClick, onExportToBackend, renderFooter } = this.props; const { onCollabButtonClick, onExportToBackend } = this.props;
const canvasScale = window.devicePixelRatio; const canvasScale = window.devicePixelRatio;
const canvasWidth = canvasDOMWidth * canvasScale; const canvasWidth = canvasDOMWidth * canvasScale;
@@ -362,7 +374,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
elements={this.scene.getElements()} elements={this.scene.getElements()}
onCollabButtonClick={onCollabButtonClick} onCollabButtonClick={onCollabButtonClick}
onLockToggle={this.toggleLock} onLockToggle={this.toggleLock}
onInsertElements={(elements) => onInsertShape={(elements) =>
this.addElementsFromPasteOrLibrary( this.addElementsFromPasteOrLibrary(
elements, elements,
DEFAULT_PASTE_X, DEFAULT_PASTE_X,
@@ -371,10 +383,9 @@ class App extends React.Component<ExcalidrawProps, AppState> {
} }
zenModeEnabled={zenModeEnabled} zenModeEnabled={zenModeEnabled}
toggleZenMode={this.toggleZenMode} toggleZenMode={this.toggleZenMode}
langCode={getLanguage().code} lng={getLanguage().lng}
isCollaborating={this.props.isCollaborating || false} isCollaborating={this.props.isCollaborating || false}
onExportToBackend={onExportToBackend} onExportToBackend={onExportToBackend}
renderCustomFooter={renderFooter}
/> />
{this.state.showStats && ( {this.state.showStats && (
<Stats <Stats
@@ -530,7 +541,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
this.scene.replaceAllElements([]); this.scene.replaceAllElements([]);
this.setState((state) => ({ this.setState((state) => ({
...getDefaultAppState(), ...getDefaultAppState(),
name: getNewSceneName(),
isLoading: opts?.resetLoadingState ? false : state.isLoading, isLoading: opts?.resetLoadingState ? false : state.isLoading,
appearance: this.state.appearance, appearance: this.state.appearance,
})); }));
@@ -742,10 +752,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
} }
componentDidUpdate(prevProps: ExcalidrawProps, prevState: AppState) { componentDidUpdate(prevProps: ExcalidrawProps, prevState: AppState) {
if (prevProps.langCode !== this.props.langCode) {
this.updateLanguage();
}
if ( if (
prevProps.width !== this.props.width || prevProps.width !== this.props.width ||
prevProps.height !== this.props.height || prevProps.height !== this.props.height ||
@@ -869,16 +875,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
history.record(this.state, this.scene.getElementsIncludingDeleted()); history.record(this.state, this.scene.getElementsIncludingDeleted());
// Do not notify consumers if we're still loading the scene. Among other this.props.onChange?.(this.scene.getElementsIncludingDeleted(), this.state);
// potential issues, this fixes a case where the tab isn't focused during
// init, which would trigger onChange with empty elements, which would then
// override whatever is in localStorage currently.
if (!this.state.isLoading) {
this.props.onChange?.(
this.scene.getElementsIncludingDeleted(),
this.state,
);
}
} }
// Copy/paste // Copy/paste
@@ -1007,12 +1004,9 @@ class App extends React.Component<ExcalidrawProps, AppState> {
if (data.errorMessage) { if (data.errorMessage) {
this.setState({ errorMessage: data.errorMessage }); this.setState({ errorMessage: data.errorMessage });
} else if (data.spreadsheet) { } else if (data.spreadsheet) {
this.setState({ this.addElementsFromPasteOrLibrary(
pasteDialog: { renderSpreadsheet(data.spreadsheet, cursorX, cursorY),
data: data.spreadsheet, );
shown: true,
},
});
} else if (data.elements) { } else if (data.elements) {
this.addElementsFromPasteOrLibrary(data.elements); this.addElementsFromPasteOrLibrary(data.elements);
} else if (data.text) { } else if (data.text) {
@@ -1042,7 +1036,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
const dy = y - elementsCenterY; const dy = y - elementsCenterY;
const groupIdMap = new Map(); const groupIdMap = new Map();
const [gridX, gridY] = getGridPoint(dx, dy, this.state.gridSize); const [gridX, gridY] = getGridPoint(dx, dy, this.state.showGrid);
const oldIdToDuplicatedId = new Map(); const oldIdToDuplicatedId = new Map();
const newElements = clipboardElements.map((element) => { const newElements = clipboardElements.map((element) => {
@@ -1155,7 +1149,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
toggleGridMode = () => { toggleGridMode = () => {
this.setState({ this.setState({
gridSize: this.state.gridSize ? null : GRID_SIZE, showGrid: !this.state.showGrid,
}); });
}; };
@@ -1281,8 +1275,8 @@ class App extends React.Component<ExcalidrawProps, AppState> {
if (isArrowKey(event.key)) { if (isArrowKey(event.key)) {
const step = const step =
(this.state.gridSize && (this.state.showGrid &&
(event.shiftKey ? ELEMENT_TRANSLATE_AMOUNT : this.state.gridSize)) || (event.shiftKey ? ELEMENT_TRANSLATE_AMOUNT : GRID_SIZE)) ||
(event.shiftKey (event.shiftKey
? ELEMENT_SHIFT_TRANSLATE_AMOUNT ? ELEMENT_SHIFT_TRANSLATE_AMOUNT
: ELEMENT_TRANSLATE_AMOUNT); : ELEMENT_TRANSLATE_AMOUNT);
@@ -1825,7 +1819,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
scenePointerX, scenePointerX,
scenePointerY, scenePointerY,
this.state.editingLinearElement, this.state.editingLinearElement,
this.state.gridSize, this.state.showGrid,
); );
if (editingLinearElement !== this.state.editingLinearElement) { if (editingLinearElement !== this.state.editingLinearElement) {
this.setState({ editingLinearElement }); this.setState({ editingLinearElement });
@@ -2255,7 +2249,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
return { return {
origin, origin,
originInGrid: tupleToCoors( originInGrid: tupleToCoors(
getGridPoint(origin.x, origin.y, this.state.gridSize), getGridPoint(origin.x, origin.y, this.state.showGrid),
), ),
scrollbars: isOverScrollBars( scrollbars: isOverScrollBars(
currentScrollBars, currentScrollBars,
@@ -2468,7 +2462,8 @@ class App extends React.Component<ExcalidrawProps, AppState> {
// otherwise, it will trigger selection based on current // otherwise, it will trigger selection based on current
// state of the box // state of the box
if (!this.state.selectedElementIds[hitElement.id]) { if (!this.state.selectedElementIds[hitElement.id]) {
// if we are currently editing a group, exiting editing mode and deselect the group. // if we are currently editing a group, treat all selections outside of the group
// as exiting editing mode.
if ( if (
this.state.editingGroupId && this.state.editingGroupId &&
!isElementInGroup(hitElement, this.state.editingGroupId) !isElementInGroup(hitElement, this.state.editingGroupId)
@@ -2478,6 +2473,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
selectedGroupIds: {}, selectedGroupIds: {},
editingGroupId: null, editingGroupId: null,
}); });
return true;
} }
// Add hit element to selection. At this point if we're not holding // Add hit element to selection. At this point if we're not holding
@@ -2611,7 +2607,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
const [gridX, gridY] = getGridPoint( const [gridX, gridY] = getGridPoint(
pointerDownState.origin.x, pointerDownState.origin.x,
pointerDownState.origin.y, pointerDownState.origin.y,
elementType === "draw" ? null : this.state.gridSize, elementType === "draw" ? false : this.state.showGrid,
); );
/* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads. /* If arrow is pre-arrowheads, it will have undefined for both start and end arrowheads.
@@ -2673,7 +2669,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
const [gridX, gridY] = getGridPoint( const [gridX, gridY] = getGridPoint(
pointerDownState.origin.x, pointerDownState.origin.x,
pointerDownState.origin.y, pointerDownState.origin.y,
this.state.gridSize, this.state.showGrid,
); );
const element = newElement({ const element = newElement({
type: elementType, type: elementType,
@@ -2762,7 +2758,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
const [gridX, gridY] = getGridPoint( const [gridX, gridY] = getGridPoint(
pointerCoords.x, pointerCoords.x,
pointerCoords.y, pointerCoords.y,
this.state.gridSize, this.state.showGrid,
); );
// for arrows/lines, don't start dragging until a given threshold // for arrows/lines, don't start dragging until a given threshold
@@ -2834,7 +2830,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
const [dragX, dragY] = getGridPoint( const [dragX, dragY] = getGridPoint(
pointerCoords.x - pointerDownState.drag.offset.x, pointerCoords.x - pointerDownState.drag.offset.x,
pointerCoords.y - pointerDownState.drag.offset.y, pointerCoords.y - pointerDownState.drag.offset.y,
this.state.gridSize, this.state.showGrid,
); );
const [dragDistanceX, dragDistanceY] = [ const [dragDistanceX, dragDistanceY] = [
@@ -2886,7 +2882,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
const [originDragX, originDragY] = getGridPoint( const [originDragX, originDragY] = getGridPoint(
pointerDownState.origin.x - pointerDownState.drag.offset.x, pointerDownState.origin.x - pointerDownState.drag.offset.x,
pointerDownState.origin.y - pointerDownState.drag.offset.y, pointerDownState.origin.y - pointerDownState.drag.offset.y,
this.state.gridSize, this.state.showGrid,
); );
mutateElement(duplicatedElement, { mutateElement(duplicatedElement, {
x: duplicatedElement.x + (originDragX - dragX), x: duplicatedElement.x + (originDragX - dragX),
@@ -3546,7 +3542,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
const [gridX, gridY] = getGridPoint( const [gridX, gridY] = getGridPoint(
pointerCoords.x, pointerCoords.x,
pointerCoords.y, pointerCoords.y,
this.state.gridSize, this.state.showGrid,
); );
dragNewElement( dragNewElement(
draggingElement, draggingElement,
@@ -3584,7 +3580,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
const [resizeX, resizeY] = getGridPoint( const [resizeX, resizeY] = getGridPoint(
pointerCoords.x - pointerDownState.resize.offset.x, pointerCoords.x - pointerDownState.resize.offset.x,
pointerCoords.y - pointerDownState.resize.offset.y, pointerCoords.y - pointerDownState.resize.offset.y,
this.state.gridSize, this.state.showGrid,
); );
if ( if (
transformElements( transformElements(
@@ -3648,7 +3644,7 @@ class App extends React.Component<ExcalidrawProps, AppState> {
CANVAS_ONLY_ACTIONS.includes(action.name), CANVAS_ONLY_ACTIONS.includes(action.name),
), ),
{ {
checked: this.state.gridSize !== null, checked: this.state.showGrid,
shortcutName: "gridMode", shortcutName: "gridMode",
label: t("labels.gridMode"), label: t("labels.gridMode"),
action: this.toggleGridMode, action: this.toggleGridMode,
@@ -3857,14 +3853,6 @@ class App extends React.Component<ExcalidrawProps, AppState> {
offsetTop: typeof offsets?.offsetTop === "number" ? offsets.offsetTop : 0, offsetTop: typeof offsets?.offsetTop === "number" ? offsets.offsetTop : 0,
}; };
} }
private async updateLanguage() {
const currentLang =
languages.find((lang) => lang.code === this.props.langCode) ||
defaultLang;
await setLanguage(currentLang);
this.setAppState({});
}
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
+1 -1
View File
@@ -218,7 +218,7 @@
left: 2px; left: 2px;
} }
@media #{$is-mobile-query} { @media #{$media-query} {
display: none; display: none;
} }
} }
+5 -19
View File
@@ -1,4 +1,4 @@
@import "../css/_variables"; @import "open-color/open-color.scss";
.excalidraw { .excalidraw {
.context-menu { .context-menu {
@@ -42,16 +42,16 @@
} }
&.dangerous { &.dangerous {
.context-menu-option__label { div:nth-child(1) {
color: $oc-red-7; color: $oc-red-7;
} }
} }
.context-menu-option__label { div:nth-child(1) {
justify-self: start; justify-self: start;
margin-inline-end: 20px; margin-inline-end: 20px;
} }
.context-menu-option__shortcut { div:nth-child(2) {
justify-self: end; justify-self: end;
opacity: 0.6; opacity: 0.6;
font-size: 0.7rem; font-size: 0.7rem;
@@ -63,7 +63,7 @@
background-color: var(--select-highlight-color); background-color: var(--select-highlight-color);
&.dangerous { &.dangerous {
.context-menu-option__label { div:nth-child(1) {
color: var(--popup-background-color); color: var(--popup-background-color);
} }
background-color: $oc-red-6; background-color: $oc-red-6;
@@ -73,18 +73,4 @@
.context-menu-option:focus { .context-menu-option:focus {
z-index: 1; z-index: 1;
} }
@media #{$is-mobile-query} {
.context-menu-option {
display: block;
.context-menu-option__label {
margin-inline-end: 0;
}
.context-menu-option__shortcut {
display: none;
}
}
}
} }
+2 -2
View File
@@ -51,8 +51,8 @@ const ContextMenu = ({ options, onCloseRequest, top, left }: Props) => {
${checked ? "checkmark" : ""}`} ${checked ? "checkmark" : ""}`}
onClick={action} onClick={action}
> >
<div className="context-menu-option__label">{label}</div> <div>{label}</div>
<div className="context-menu-option__shortcut"> <div>
{shortcutName {shortcutName
? getShortcutFromShortcutName(shortcutName) ? getShortcutFromShortcutName(shortcutName)
: ""} : ""}
+7 -9
View File
@@ -7,9 +7,6 @@
margin-top: 0; margin-top: 0;
grid-template-columns: 1fr calc(var(--space-factor) * 7); grid-template-columns: 1fr calc(var(--space-factor) * 7);
grid-gap: var(--metric); grid-gap: var(--metric);
padding: calc(var(--space-factor) * 2);
text-align: center;
font-variant: small-caps;
} }
.Dialog__titleContent { .Dialog__titleContent {
@@ -21,11 +18,7 @@
margin: 0; margin: 0;
} }
.Dialog__content { @media #{$media-query} {
padding: 0 16px 16px;
}
@media #{$is-mobile-query} {
.Dialog { .Dialog {
--metric: calc(var(--space-factor) * 4); --metric: calc(var(--space-factor) * 4);
--inset-left: #{"max(var(--metric), var(--sal))"}; --inset-left: #{"max(var(--metric), var(--sal))"};
@@ -37,8 +30,13 @@
var(--space-factor) * 7 var(--space-factor) * 7
); );
position: sticky; position: sticky;
top: 0; top: calc(-1 * var(--metric));
margin: calc(-1 * var(--inset-right));
margin-top: calc(-1 * var(--metric));
margin-bottom: var(--metric);
padding: calc(var(--space-factor) * 2); padding: calc(var(--space-factor) * 2);
padding-left: var(--inset-left);
padding-right: var(--inset-right);
background: var(--bg-color-island); background: var(--bg-color-island);
font-size: 1.25em; font-size: 1.25em;
+14 -14
View File
@@ -1,12 +1,13 @@
import clsx from "clsx";
import React, { useCallback, useEffect, useState } from "react"; import React, { useCallback, useEffect, useState } from "react";
import clsx from "clsx";
import { Modal } from "./Modal";
import { Island } from "./Island";
import { t } from "../i18n"; import { t } from "../i18n";
import useIsMobile from "../is-mobile"; import useIsMobile from "../is-mobile";
import { KEYS } from "../keys";
import "./Dialog.scss";
import { back, close } from "./icons"; import { back, close } from "./icons";
import { Island } from "./Island"; import { KEYS } from "../keys";
import { Modal } from "./Modal";
import "./Dialog.scss";
const useRefState = <T,>() => { const useRefState = <T,>() => {
const [refValue, setRefValue] = useState<T | null>(null); const [refValue, setRefValue] = useState<T | null>(null);
@@ -19,10 +20,9 @@ const useRefState = <T,>() => {
export const Dialog = (props: { export const Dialog = (props: {
children: React.ReactNode; children: React.ReactNode;
className?: string; className?: string;
small?: boolean; maxWidth?: number;
onCloseRequest(): void; onCloseRequest(): void;
title: React.ReactNode; title: React.ReactNode;
autofocus?: boolean;
}) => { }) => {
const [islandNode, setIslandNode] = useRefState<HTMLDivElement>(); const [islandNode, setIslandNode] = useRefState<HTMLDivElement>();
@@ -33,7 +33,7 @@ export const Dialog = (props: {
const focusableElements = queryFocusableElements(islandNode); const focusableElements = queryFocusableElements(islandNode);
if (focusableElements.length > 0 && props.autofocus !== false) { if (focusableElements.length > 0) {
// If there's an element other than close, focus it. // If there's an element other than close, focus it.
(focusableElements[1] || focusableElements[0]).focus(); (focusableElements[1] || focusableElements[0]).focus();
} }
@@ -62,7 +62,7 @@ export const Dialog = (props: {
islandNode.addEventListener("keydown", handleKeyDown); islandNode.addEventListener("keydown", handleKeyDown);
return () => islandNode.removeEventListener("keydown", handleKeyDown); return () => islandNode.removeEventListener("keydown", handleKeyDown);
}, [islandNode, props.autofocus]); }, [islandNode]);
const queryFocusableElements = (node: HTMLElement) => { const queryFocusableElements = (node: HTMLElement) => {
const focusableElements = node.querySelectorAll<HTMLElement>( const focusableElements = node.querySelectorAll<HTMLElement>(
@@ -76,11 +76,11 @@ export const Dialog = (props: {
<Modal <Modal
className={clsx("Dialog", props.className)} className={clsx("Dialog", props.className)}
labelledBy="dialog-title" labelledBy="dialog-title"
maxWidth={props.small ? 550 : 800} maxWidth={props.maxWidth}
onCloseRequest={props.onCloseRequest} onCloseRequest={props.onCloseRequest}
> >
<Island ref={setIslandNode}> <Island padding={4} ref={setIslandNode}>
<h3 id="dialog-title" className="Dialog__title"> <h2 id="dialog-title" className="Dialog__title">
<span className="Dialog__titleContent">{props.title}</span> <span className="Dialog__titleContent">{props.title}</span>
<button <button
className="Modal__close" className="Modal__close"
@@ -89,8 +89,8 @@ export const Dialog = (props: {
> >
{useIsMobile() ? back : close} {useIsMobile() ? back : close}
</button> </button>
</h3> </h2>
<div className="Dialog__content">{props.children}</div> {props.children}
</Island> </Island>
</Modal> </Modal>
); );
+1 -1
View File
@@ -24,7 +24,7 @@ export const ErrorDialog = ({
<> <>
{modalIsShown && ( {modalIsShown && (
<Dialog <Dialog
small maxWidth={500}
onCloseRequest={handleClose} onCloseRequest={handleClose}
title={t("errorDialog.title")} title={t("errorDialog.title")}
> >
+3 -1
View File
@@ -37,7 +37,7 @@
} }
} }
@media #{$is-mobile-query} { @media (max-width: 550px) {
.ExportDialog { .ExportDialog {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@@ -51,7 +51,9 @@
.ExportDialog__actions > * { .ExportDialog__actions > * {
margin-bottom: calc(var(--space-factor) * 3); margin-bottom: calc(var(--space-factor) * 3);
} }
}
@media #{$media-query} {
.ExportDialog__preview canvas { .ExportDialog__preview canvas {
max-height: 30vh; max-height: 30vh;
} }
+5 -1
View File
@@ -262,7 +262,11 @@ export const ExportDialog = ({
ref={triggerButton} ref={triggerButton}
/> />
{modalIsShown && ( {modalIsShown && (
<Dialog onCloseRequest={handleClose} title={t("buttons.export")}> <Dialog
maxWidth={800}
onCloseRequest={handleClose}
title={t("buttons.export")}
>
<ExportModal <ExportModal
elements={elements} elements={elements}
appState={appState} appState={appState}
+5 -5
View File
@@ -1,8 +1,5 @@
@import "../css/_variables"; @import "../css/_variables";
// this is loosely based on the longest hint text
$wide-viewport-width: 1000px;
.excalidraw { .excalidraw {
.HintViewer { .HintViewer {
pointer-events: none; pointer-events: none;
@@ -19,9 +16,12 @@ $wide-viewport-width: 1000px;
color: $oc-gray-6; color: $oc-gray-6;
font-size: 0.8rem; font-size: 0.8rem;
@media #{$is-mobile-query} { @media (min-width: 1200px) {
white-space: pre;
}
@media #{$media-query} {
position: static; position: static;
padding-right: 2em;
} }
> span { > span {
+1 -1
View File
@@ -110,7 +110,7 @@
:root[dir="rtl"] & { :root[dir="rtl"] & {
left: 2px; left: 2px;
} }
@media #{$is-mobile-query} { @media #{$media-query} {
display: none; display: none;
} }
} }
+6 -17
View File
@@ -1,29 +1,18 @@
import React from "react"; import React from "react";
import { LoadingMessage } from "./LoadingMessage"; import { LoadingMessage } from "./LoadingMessage";
import { import { setLanguageFirstTime } from "../i18n";
defaultLang,
Language,
languages,
setLanguageFirstTime,
} from "../i18n";
interface Props { export class InitializeApp extends React.Component<
langCode: Language["code"]; any,
} { isLoading: boolean }
interface State { > {
isLoading: boolean;
}
export class InitializeApp extends React.Component<Props, State> {
public state: { isLoading: boolean } = { public state: { isLoading: boolean } = {
isLoading: true, isLoading: true,
}; };
async componentDidMount() { async componentDidMount() {
const currentLang = await setLanguageFirstTime();
languages.find((lang) => lang.code === this.props.langCode) ||
defaultLang;
await setLanguageFirstTime(currentLang);
this.setState({ this.setState({
isLoading: false, isLoading: false,
}); });
+1 -1
View File
@@ -4,7 +4,7 @@
background-color: var(--bg-color-island); background-color: var(--bg-color-island);
backdrop-filter: saturate(100%) blur(10px); backdrop-filter: saturate(100%) blur(10px);
box-shadow: var(--shadow-island); box-shadow: var(--shadow-island);
border-radius: 4px; border-radius: var(--border-radius-m);
padding: calc(var(--padding) * var(--space-factor)); padding: calc(var(--padding) * var(--space-factor));
position: relative; position: relative;
transition: box-shadow 0.5s ease-in-out; transition: box-shadow 0.5s ease-in-out;
@@ -1,16 +1,16 @@
import React from "react"; import React from "react";
import clsx from "clsx"; import clsx from "clsx";
import * as i18n from "../../i18n"; import * as i18n from "../i18n";
export const LanguageList = ({ export const LanguageList = ({
onChange, onChange,
languages = i18n.languages, languages = i18n.languages,
currentLangCode = i18n.getLanguage().code, currentLanguage = i18n.getLanguage().lng,
floating, floating,
}: { }: {
languages?: { code: string; label: string }[]; languages?: { lng: string; label: string }[];
onChange: (langCode: i18n.Language["code"]) => void; onChange: (value: string) => void;
currentLangCode?: i18n.Language["code"]; currentLanguage?: string;
floating?: boolean; floating?: boolean;
}) => ( }) => (
<React.Fragment> <React.Fragment>
@@ -19,12 +19,12 @@ export const LanguageList = ({
"dropdown-select--floating": floating, "dropdown-select--floating": floating,
})} })}
onChange={({ target }) => onChange(target.value)} onChange={({ target }) => onChange(target.value)}
value={currentLangCode} value={currentLanguage}
aria-label={i18n.t("buttons.selectLanguage")} aria-label={i18n.t("buttons.selectLanguage")}
> >
{languages.map((lang) => ( {languages.map((language) => (
<option key={lang.code} value={lang.code}> <option key={language.lng} value={language.lng}>
{lang.label} {language.label}
</option> </option>
))} ))}
</select> </select>
+5 -17
View File
@@ -7,23 +7,11 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
.layer-ui__library-header { .browse-libraries {
display: flex; position: absolute;
align-items: center; right: 12px;
width: 100%; top: 16px;
margin: 2px 0; white-space: nowrap;
button {
// 2px from the left to account for focus border of left-most button
margin: 0 2px;
}
a {
margin-left: auto;
// 17px for scrollbar (needed for overlay scrollbars on Big Sur?) + 1px extra
padding-right: 18px;
white-space: nowrap;
}
} }
} }
+77 -83
View File
@@ -19,7 +19,8 @@ import { FixedSideContainer } from "./FixedSideContainer";
import { UserList } from "./UserList"; import { UserList } from "./UserList";
import { LockIcon } from "./LockIcon"; import { LockIcon } from "./LockIcon";
import { ExportDialog, ExportCB } from "./ExportDialog"; import { ExportDialog, ExportCB } from "./ExportDialog";
import { Language, t } from "../i18n"; import { LanguageList } from "./LanguageList";
import { t, languages, setLanguage } from "../i18n";
import { HintViewer } from "./HintViewer"; import { HintViewer } from "./HintViewer";
import useIsMobile from "../is-mobile"; import useIsMobile from "../is-mobile";
@@ -50,7 +51,6 @@ import {
EVENT_LIBRARY, EVENT_LIBRARY,
trackEvent, trackEvent,
} from "../analytics"; } from "../analytics";
import { PasteChartDialog } from "./PasteChartDialog";
interface LayerUIProps { interface LayerUIProps {
actionManager: ActionManager; actionManager: ActionManager;
@@ -60,17 +60,16 @@ interface LayerUIProps {
elements: readonly NonDeletedExcalidrawElement[]; elements: readonly NonDeletedExcalidrawElement[];
onCollabButtonClick?: () => void; onCollabButtonClick?: () => void;
onLockToggle: () => void; onLockToggle: () => void;
onInsertElements: (elements: readonly NonDeletedExcalidrawElement[]) => void; onInsertShape: (elements: LibraryItem) => void;
zenModeEnabled: boolean; zenModeEnabled: boolean;
toggleZenMode: () => void; toggleZenMode: () => void;
langCode: Language["code"]; lng: string;
isCollaborating: boolean; isCollaborating: boolean;
onExportToBackend?: ( onExportToBackend?: (
exportedElements: readonly NonDeletedExcalidrawElement[], exportedElements: readonly NonDeletedExcalidrawElement[],
appState: AppState, appState: AppState,
canvas: HTMLCanvasElement | null, canvas: HTMLCanvasElement | null,
) => void; ) => void;
renderCustomFooter?: (isMobile: boolean) => JSX.Element;
} }
const useOnClickOutside = ( const useOnClickOutside = (
@@ -124,42 +123,9 @@ const LibraryMenuItems = ({
let addedPendingElements = false; let addedPendingElements = false;
rows.push( rows.push(
<div className="layer-ui__library-header"> <>
<ToolButton
key="import"
type="button"
title={t("buttons.load")}
aria-label={t("buttons.load")}
icon={load}
onClick={() => {
importLibraryFromJSON()
.then(() => {
// Maybe we should close and open the menu so that the items get updated.
// But for now we just close the menu.
setAppState({ isLibraryOpen: false });
})
.catch(muteFSAbortError)
.catch((error) => {
setAppState({ errorMessage: error.message });
});
}}
/>
<ToolButton
key="export"
type="button"
title={t("buttons.export")}
aria-label={t("buttons.export")}
icon={exportFile}
onClick={() => {
saveLibraryAsJSON()
.catch(muteFSAbortError)
.catch((error) => {
setAppState({ errorMessage: error.message });
});
}}
/>
<a <a
className="browse-libraries"
href="https://libraries.excalidraw.com" href="https://libraries.excalidraw.com"
target="_excalidraw_libraries" target="_excalidraw_libraries"
onClick={() => { onClick={() => {
@@ -168,7 +134,48 @@ const LibraryMenuItems = ({
> >
{t("labels.libraries")} {t("labels.libraries")}
</a> </a>
</div>,
<Stack.Row
align="center"
gap={1}
key={"actions"}
style={{ padding: "2px" }}
>
<ToolButton
key="import"
type="button"
title={t("buttons.load")}
aria-label={t("buttons.load")}
icon={load}
onClick={() => {
importLibraryFromJSON()
.then(() => {
// Maybe we should close and open the menu so that the items get updated.
// But for now we just close the menu.
setAppState({ isLibraryOpen: false });
})
.catch(muteFSAbortError)
.catch((error) => {
setAppState({ errorMessage: error.message });
});
}}
/>
<ToolButton
key="export"
type="button"
title={t("buttons.export")}
aria-label={t("buttons.export")}
icon={exportFile}
onClick={() => {
saveLibraryAsJSON()
.catch(muteFSAbortError)
.catch((error) => {
setAppState({ errorMessage: error.message });
});
}}
/>
</Stack.Row>
</>,
); );
for (let row = 0; row < numRows; row++) { for (let row = 0; row < numRows; row++) {
@@ -311,12 +318,11 @@ const LayerUI = ({
elements, elements,
onCollabButtonClick, onCollabButtonClick,
onLockToggle, onLockToggle,
onInsertElements, onInsertShape,
zenModeEnabled, zenModeEnabled,
toggleZenMode, toggleZenMode,
isCollaborating, isCollaborating,
onExportToBackend, onExportToBackend,
renderCustomFooter,
}: LayerUIProps) => { }: LayerUIProps) => {
const isMobile = useIsMobile(); const isMobile = useIsMobile();
@@ -450,7 +456,7 @@ const LayerUI = ({
<LibraryMenu <LibraryMenu
pendingElements={getSelectedElements(elements, appState)} pendingElements={getSelectedElements(elements, appState)}
onClickOutside={closeLibrary} onClickOutside={closeLibrary}
onInsertShape={onInsertElements} onInsertShape={onInsertShape}
onAddToLibrary={deselectItems} onAddToLibrary={deselectItems}
setAppState={setAppState} setAppState={setAppState}
/> />
@@ -552,7 +558,14 @@ const LayerUI = ({
"transition-right disable-pointerEvents": zenModeEnabled, "transition-right disable-pointerEvents": zenModeEnabled,
})} })}
> >
{renderCustomFooter?.(false)} <LanguageList
onChange={async (lng) => {
await setLanguage(lng);
setAppState({});
}}
languages={languages}
floating
/>
{actionManager.renderAction("toggleShortcuts")} {actionManager.renderAction("toggleShortcuts")}
</div> </div>
<button <button
@@ -579,8 +592,21 @@ const LayerUI = ({
</footer> </footer>
); );
const dialogs = ( return isMobile ? (
<> <MobileMenu
appState={appState}
elements={elements}
actionManager={actionManager}
libraryMenu={libraryMenu}
exportButton={renderExportDialog()}
setAppState={setAppState}
onCollabButtonClick={onCollabButtonClick}
onLockToggle={onLockToggle}
canvas={canvas}
isCollaborating={isCollaborating}
/>
) : (
<div className="layer-ui__wrapper">
{appState.isLoading && <LoadingMessage />} {appState.isLoading && <LoadingMessage />}
{appState.errorMessage && ( {appState.errorMessage && (
<ErrorDialog <ErrorDialog
@@ -593,41 +619,6 @@ const LayerUI = ({
onClose={() => setAppState({ showShortcutsDialog: false })} onClose={() => setAppState({ showShortcutsDialog: false })}
/> />
)} )}
{appState.pasteDialog.shown && (
<PasteChartDialog
setAppState={setAppState}
appState={appState}
onInsertChart={onInsertElements}
onClose={() =>
setAppState({
pasteDialog: { shown: false, data: null },
})
}
/>
)}
</>
);
return isMobile ? (
<>
{dialogs}
<MobileMenu
appState={appState}
elements={elements}
actionManager={actionManager}
libraryMenu={libraryMenu}
exportButton={renderExportDialog()}
setAppState={setAppState}
onCollabButtonClick={onCollabButtonClick}
onLockToggle={onLockToggle}
canvas={canvas}
isCollaborating={isCollaborating}
renderCustomFooter={renderCustomFooter}
/>
</>
) : (
<div className="layer-ui__wrapper">
{dialogs}
{renderFixedSideContainer()} {renderFixedSideContainer()}
{renderBottomAppMenu()} {renderBottomAppMenu()}
{ {
@@ -650,6 +641,8 @@ const LayerUI = ({
const areEqual = (prev: LayerUIProps, next: LayerUIProps) => { const areEqual = (prev: LayerUIProps, next: LayerUIProps) => {
const getNecessaryObj = (appState: AppState): Partial<AppState> => { const getNecessaryObj = (appState: AppState): Partial<AppState> => {
const { const {
cursorX,
cursorY,
suggestedBindings, suggestedBindings,
startBoundElement: boundElement, startBoundElement: boundElement,
...ret ...ret
@@ -660,8 +653,9 @@ const areEqual = (prev: LayerUIProps, next: LayerUIProps) => {
const nextAppState = getNecessaryObj(next.appState); const nextAppState = getNecessaryObj(next.appState);
const keys = Object.keys(prevAppState) as (keyof Partial<AppState>)[]; const keys = Object.keys(prevAppState) as (keyof Partial<AppState>)[];
return ( return (
prev.langCode === next.langCode && prev.lng === next.lng &&
prev.elements === next.elements && prev.elements === next.elements &&
keys.every((key) => prevAppState[key] === nextAppState[key]) keys.every((key) => prevAppState[key] === nextAppState[key])
); );
+6 -6
View File
@@ -1,13 +1,13 @@
import React, { useRef, useEffect, useState } from "react";
import clsx from "clsx"; import clsx from "clsx";
import oc from "open-color"; import { exportToSvg } from "../scene/export";
import React, { useEffect, useRef, useState } from "react";
import { close } from "../components/icons"; import { close } from "../components/icons";
import { MIME_TYPES } from "../constants";
import "./LibraryUnit.scss";
import { t } from "../i18n"; import { t } from "../i18n";
import useIsMobile from "../is-mobile"; import useIsMobile from "../is-mobile";
import { exportToSvg } from "../scene/export";
import { LibraryItem } from "../types"; import { LibraryItem } from "../types";
import "./LibraryUnit.scss"; import { MIME_TYPES } from "../constants";
// fa-plus // fa-plus
const PLUS_ICON = ( const PLUS_ICON = (
@@ -38,7 +38,7 @@ export const LibraryUnit = ({
} }
const svg = exportToSvg(elementsToRender, { const svg = exportToSvg(elementsToRender, {
exportBackground: false, exportBackground: false,
viewBackgroundColor: oc.white, viewBackgroundColor: "#fff",
shouldAddWatermark: false, shouldAddWatermark: false,
}); });
for (const child of ref.current!.children) { for (const child of ref.current!.children) {
+13 -4
View File
@@ -1,8 +1,9 @@
import React from "react"; import React from "react";
import { AppState } from "../types"; import { AppState } from "../types";
import { ActionManager } from "../actions/manager"; import { ActionManager } from "../actions/manager";
import { t } from "../i18n"; import { t, setLanguage } from "../i18n";
import Stack from "./Stack"; import Stack from "./Stack";
import { LanguageList } from "./LanguageList";
import { showSelectedShapeActions } from "../element"; import { showSelectedShapeActions } from "../element";
import { NonDeletedExcalidrawElement } from "../element/types"; import { NonDeletedExcalidrawElement } from "../element/types";
import { FixedSideContainer } from "./FixedSideContainer"; import { FixedSideContainer } from "./FixedSideContainer";
@@ -14,6 +15,7 @@ import { Section } from "./Section";
import CollabButton from "./CollabButton"; import CollabButton from "./CollabButton";
import { SCROLLBAR_WIDTH, SCROLLBAR_MARGIN } from "../scene/scrollbars"; import { SCROLLBAR_WIDTH, SCROLLBAR_MARGIN } from "../scene/scrollbars";
import { LockIcon } from "./LockIcon"; import { LockIcon } from "./LockIcon";
import { LoadingMessage } from "./LoadingMessage";
import { UserList } from "./UserList"; import { UserList } from "./UserList";
import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle"; import { BackgroundPickerAndDarkModeToggle } from "./BackgroundPickerAndDarkModeToggle";
import { EVENT_ACTION, trackEvent } from "../analytics"; import { EVENT_ACTION, trackEvent } from "../analytics";
@@ -29,7 +31,6 @@ type MobileMenuProps = {
onLockToggle: () => void; onLockToggle: () => void;
canvas: HTMLCanvasElement | null; canvas: HTMLCanvasElement | null;
isCollaborating: boolean; isCollaborating: boolean;
renderCustomFooter?: (isMobile: boolean) => JSX.Element;
}; };
export const MobileMenu = ({ export const MobileMenu = ({
@@ -43,9 +44,9 @@ export const MobileMenu = ({
onLockToggle, onLockToggle,
canvas, canvas,
isCollaborating, isCollaborating,
renderCustomFooter,
}: MobileMenuProps) => ( }: MobileMenuProps) => (
<> <>
{appState.isLoading && <LoadingMessage />}
<FixedSideContainer side="top"> <FixedSideContainer side="top">
<Section heading="shapes"> <Section heading="shapes">
{(heading) => ( {(heading) => (
@@ -103,7 +104,15 @@ export const MobileMenu = ({
appState={appState} appState={appState}
setAppState={setAppState} setAppState={setAppState}
/> />
{renderCustomFooter?.(true)} <fieldset>
<legend>{t("labels.language")}</legend>
<LanguageList
onChange={async (lng) => {
await setLanguage(lng);
setAppState({});
}}
/>
</fieldset>
<fieldset> <fieldset>
<legend>{t("labels.collaborators")}</legend> <legend>{t("labels.collaborators")}</legend>
<UserList mobile> <UserList mobile>
+8 -10
View File
@@ -30,26 +30,18 @@
z-index: 2; z-index: 2;
width: 100%; width: 100%;
max-width: var(--max-width); max-width: var(--max-width);
max-height: 100%;
opacity: 0; opacity: 0;
transform: translateY(10px); transform: translateY(10px);
animation: Modal__content_fade-in 0.1s ease-out 0.05s forwards; animation: Modal__content_fade-in 0.1s ease-out 0.05s forwards;
position: relative; position: relative;
overflow-y: auto;
// for modals, reset blurry bg // for modals, reset blurry bg
background: var(--bg-color-island); background: var(--bg-color-island);
backdrop-filter: none; backdrop-filter: none;
border: 1px solid var(--dialog-border); @media #{$media-query} {
box-shadow: 0 2px 10px transparentize($oc-black, 0.75);
border-radius: 6px;
@media #{$is-mobile-query} {
max-width: 100%; max-width: 100%;
border: 0;
border-radius: 0;
} }
} }
@@ -76,7 +68,13 @@
} }
} }
@media #{$is-mobile-query} { .Modal__close--floating {
position: absolute;
right: calc(var(--space-factor) * 5);
top: calc(var(--space-factor) * 5);
}
@media #{$media-query} {
.Modal { .Modal {
padding: 0; padding: 0;
} }
+5 -1
View File
@@ -36,7 +36,11 @@ export const Modal = (props: {
<div className="Modal__background" onClick={props.onCloseRequest}></div> <div className="Modal__background" onClick={props.onCloseRequest}></div>
<div <div
className="Modal__content" className="Modal__content"
style={{ "--max-width": `${props.maxWidth}px` }} style={{
"--max-width": `${props.maxWidth}px`,
maxHeight: "100%",
overflowY: "scroll",
}}
> >
{props.children} {props.children}
</div> </div>
-46
View File
@@ -1,46 +0,0 @@
@import "../css/_variables";
.excalidraw {
.PasteChartDialog {
@media #{$is-mobile-query} {
.Island {
display: flex;
flex-direction: column;
}
}
.container {
display: flex;
align-items: center;
justify-content: space-around;
flex-wrap: wrap;
@media #{$is-mobile-query} {
flex-direction: column;
justify-content: center;
}
}
.ChartPreview {
margin: 8px;
text-align: center;
width: 192px;
height: 128px;
border-radius: 2px;
padding: 1px;
border: 1px solid $oc-gray-4;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
div {
display: inline-block;
}
svg {
max-height: 120px;
max-width: 186px;
}
&:hover {
padding: 0;
border: 2px solid $oc-blue-5;
}
}
}
}
-122
View File
@@ -1,122 +0,0 @@
import oc from "open-color";
import React, { useLayoutEffect, useRef, useState } from "react";
import { ChartElements, renderSpreadsheet, Spreadsheet } from "../charts";
import { ChartType } from "../element/types";
import { t } from "../i18n";
import { exportToSvg } from "../scene/export";
import { AppState, LibraryItem } from "../types";
import { Dialog } from "./Dialog";
import "./PasteChartDialog.scss";
type OnInsertChart = (chartType: ChartType, elements: ChartElements) => void;
const ChartPreviewBtn = (props: {
spreadsheet: Spreadsheet | null;
chartType: ChartType;
selected: boolean;
onClick: OnInsertChart;
}) => {
const previewRef = useRef<HTMLDivElement | null>(null);
const [chartElements, setChartElements] = useState<ChartElements | null>(
null,
);
useLayoutEffect(() => {
if (!props.spreadsheet) {
return;
}
const elements = renderSpreadsheet(
props.chartType,
props.spreadsheet,
0,
0,
);
setChartElements(elements);
const svg = exportToSvg(elements, {
exportBackground: false,
viewBackgroundColor: oc.white,
shouldAddWatermark: false,
});
const previewNode = previewRef.current!;
previewNode.appendChild(svg);
if (props.selected) {
(previewNode.parentNode as HTMLDivElement).focus();
}
return () => {
previewNode.removeChild(svg);
};
}, [props.spreadsheet, props.chartType, props.selected]);
return (
<button
className="ChartPreview"
onClick={() => {
if (chartElements) {
props.onClick(props.chartType, chartElements);
}
}}
>
<div ref={previewRef} />
</button>
);
};
export const PasteChartDialog = ({
setAppState,
appState,
onClose,
onInsertChart,
}: {
appState: AppState;
onClose: () => void;
setAppState: React.Component<any, AppState>["setState"];
onInsertChart: (elements: LibraryItem) => void;
}) => {
const handleClose = React.useCallback(() => {
if (onClose) {
onClose();
}
}, [onClose]);
const handleChartClick = (chartType: ChartType, elements: ChartElements) => {
onInsertChart(elements);
setAppState({
currentChartType: chartType,
pasteDialog: {
shown: false,
data: null,
},
});
};
return (
<Dialog
small
onCloseRequest={handleClose}
title={t("labels.pasteCharts")}
className={"PasteChartDialog"}
autofocus={false}
>
<div className={"container"}>
<ChartPreviewBtn
chartType="bar"
spreadsheet={appState.pasteDialog.data}
selected={appState.currentChartType === "bar"}
onClick={handleChartClick}
/>
<ChartPreviewBtn
chartType="line"
spreadsheet={appState.pasteDialog.data}
selected={appState.currentChartType === "line"}
onClick={handleChartClick}
/>
</div>
</Dialog>
);
};
+5 -1
View File
@@ -130,7 +130,11 @@ export const ShortcutsDialog = ({ onClose }: { onClose?: () => void }) => {
return ( return (
<> <>
<Dialog onCloseRequest={handleClose} title={t("shortcutsDialog.title")}> <Dialog
maxWidth={900}
onCloseRequest={handleClose}
title={t("shortcutsDialog.title")}
>
<Columns> <Columns>
<Column> <Column>
<ShortcutIsland caption={t("shortcutsDialog.shapes")}> <ShortcutIsland caption={t("shortcutsDialog.shapes")}>
+1
View File
@@ -85,6 +85,7 @@ export const Stats = (props: {
<td>{t("stats.total")}</td> <td>{t("stats.total")}</td>
<td>{nFormatter(storageSizes.total, 1)}</td> <td>{nFormatter(storageSizes.total, 1)}</td>
</tr> </tr>
{selectedElements.length === 1 && ( {selectedElements.length === 1 && (
<tr> <tr>
<th colSpan={2}>{t("stats.element")}</th> <th colSpan={2}>{t("stats.element")}</th>
+1 -5
View File
@@ -142,7 +142,6 @@
user-select: none; user-select: none;
} }
// shrink shape icons on small viewports to make them fit
@media (max-width: 425px) { @media (max-width: 425px) {
.Shape .ToolIcon__icon { .Shape .ToolIcon__icon {
width: 2rem; width: 2rem;
@@ -154,8 +153,6 @@
} }
} }
// move the lock button out of the way on small viewports
// it begins to collide with the GitHub icon before we switch to mobile mode
@media (max-width: 760px) { @media (max-width: 760px) {
.ToolIcon.ToolIcon__lock { .ToolIcon.ToolIcon__lock {
display: inline-block; display: inline-block;
@@ -165,7 +162,6 @@
margin-left: 0; margin-left: 0;
border-radius: 20px 0 0 20px; border-radius: 20px 0 0 20px;
z-index: 1;
background-color: var(--button-gray-1); background-color: var(--button-gray-1);
@@ -193,7 +189,7 @@
margin-left: 5px; margin-left: 5px;
margin-top: 1px; margin-top: 1px;
@media #{$is-mobile-query} { @media #{$media-query} {
display: none; display: none;
} }
} }
+1 -3
View File
@@ -73,7 +73,7 @@ export const DEFAULT_VERTICAL_ALIGN = "top";
export const CANVAS_ONLY_ACTIONS = ["selectAll"]; export const CANVAS_ONLY_ACTIONS = ["selectAll"];
export const GRID_SIZE = 20; // TODO make it configurable? export const GRID_SIZE = 20;
export const MIME_TYPES = { export const MIME_TYPES = {
excalidraw: "application/vnd.excalidraw+json", excalidraw: "application/vnd.excalidraw+json",
@@ -88,5 +88,3 @@ export const STORAGE_KEYS = {
export const TAP_TWICE_TIMEOUT = 300; export const TAP_TWICE_TIMEOUT = 300;
export const TOUCH_CTX_MENU_TIMEOUT = 500; export const TOUCH_CTX_MENU_TIMEOUT = 500;
export const TITLE_TIMEOUT = 10000; export const TITLE_TIMEOUT = 10000;
export const SCENE_NAME_FALLBACK = "Untitled";
+1 -2
View File
@@ -1,4 +1,3 @@
@import "open-color/open-color.scss"; @import "open-color/open-color.scss";
// keep up to date with is-mobile.tsx $media-query: "(max-width: 600px), (max-height: 500px) and (max-width: 1000px)";
$is-mobile-query: "(max-width: 600px), (max-height: 500px) and (max-width: 1000px)";
+1 -1
View File
@@ -441,7 +441,7 @@
} }
} }
@media #{$is-mobile-query} { @media #{$media-query} {
aside { aside {
display: none; display: none;
} }
+6 -2
View File
@@ -3,6 +3,7 @@
:root { :root {
--bg-color-island: rgba(255, 255, 255, 0.9); --bg-color-island: rgba(255, 255, 255, 0.9);
--popup-background-color: #{$oc-white}; --popup-background-color: #{$oc-white};
--border-radius-m: 4px;
--space-factor: 0.25rem; --space-factor: 0.25rem;
--button-gray-1: #{$oc-gray-2}; --button-gray-1: #{$oc-gray-2};
--button-gray-2: #{$oc-gray-4}; --button-gray-2: #{$oc-gray-4};
@@ -14,6 +15,7 @@
--icon-fill-color: #{$oc-black}; --icon-fill-color: #{$oc-black};
--icon-green-fill-color: #{$oc-green-9}; --icon-green-fill-color: #{$oc-green-9};
--keybinding-color: #{$oc-gray-5}; --keybinding-color: #{$oc-gray-5};
--color-overlay-text-color: #ccc;
--sat: env(safe-area-inset-top); --sat: env(safe-area-inset-top);
--sab: env(safe-area-inset-bottom); --sab: env(safe-area-inset-bottom);
--sal: env(safe-area-inset-left); --sal: env(safe-area-inset-left);
@@ -21,6 +23,8 @@
--text-color-primary: #{$oc-gray-8}; --text-color-primary: #{$oc-gray-8};
--shadow-island: 0 1px 5px #{transparentize($oc-black, 0.85)}; --shadow-island: 0 1px 5px #{transparentize($oc-black, 0.85)};
--overlay-background-color: #{transparentize($oc-white, 0.12)}; --overlay-background-color: #{transparentize($oc-white, 0.12)};
--border-radius-m: 4px;
--space-factor: 0.25rem;
--dropdown-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="292.4" height="292.4" viewBox="0 0 292 292"><path d="M287 197L159 69c-4-3-8-5-13-5s-9 2-13 5L5 197c-3 4-5 8-5 13s2 9 5 13c4 4 8 5 13 5h256c5 0 9-1 13-5s5-8 5-13-1-9-5-13z"/></svg>'); --dropdown-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="292.4" height="292.4" viewBox="0 0 292 292"><path d="M287 197L159 69c-4-3-8-5-13-5s-9 2-13 5L5 197c-3 4-5 8-5 13s2 9 5 13c4 4 8 5 13 5h256c5 0 9-1 13-5s5-8 5-13-1-9-5-13z"/></svg>');
--focus-highlight-color: #{$oc-blue-2}; --focus-highlight-color: #{$oc-blue-2};
--select-highlight-color: #{$oc-blue-5}; --select-highlight-color: #{$oc-blue-5};
@@ -31,7 +35,6 @@
--popup-secondary-background-color: #{$oc-gray-1}; --popup-secondary-background-color: #{$oc-gray-1};
--popup-text-color: #{$oc-black}; --popup-text-color: #{$oc-black};
--popup-text-inverted-color: #{$oc-white}; --popup-text-inverted-color: #{$oc-white};
--dialog-border: #{$oc-gray-6};
} }
.excalidraw { .excalidraw {
@@ -57,8 +60,10 @@
--icon-fill-color: #{$oc-gray-4}; --icon-fill-color: #{$oc-gray-4};
--icon-green-fill-color: #{$oc-green-4}; --icon-green-fill-color: #{$oc-green-4};
--keybinding-color: #{$oc-gray-6}; --keybinding-color: #{$oc-gray-6};
--color-overlay-text-color: #bbb;
--shadow-island: 0 1px 5px #{transparentize($oc-black, 0.7)}; --shadow-island: 0 1px 5px #{transparentize($oc-black, 0.7)};
--overlay-background-color: rgba(30, 30, 30, 0.88); --overlay-background-color: rgba(30, 30, 30, 0.88);
// #{$oc-gray-4}; inlined
--dropdown-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="292.4" height="292.4" viewBox="0 0 292 292"><path fill="%23ced4da" d="M287 197L159 69c-4-3-8-5-13-5s-9 2-13 5L5 197c-3 4-5 8-5 13s2 9 5 13c4 4 8 5 13 5h256c5 0 9-1 13-5s5-8 5-13-1-9-5-13z"/></svg>'); --dropdown-icon: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="292.4" height="292.4" viewBox="0 0 292 292"><path fill="%23ced4da" d="M287 197L159 69c-4-3-8-5-13-5s-9 2-13 5L5 197c-3 4-5 8-5 13s2 9 5 13c4 4 8 5 13 5h256c5 0 9-1 13-5s5-8 5-13-1-9-5-13z"/></svg>');
--focus-highlight-color: #{$oc-blue-6}; --focus-highlight-color: #{$oc-blue-6};
--select-highlight-color: #{$oc-blue-4}; --select-highlight-color: #{$oc-blue-4};
@@ -69,6 +74,5 @@
--popup-secondary-background-color: #222; --popup-secondary-background-color: #222;
--popup-text-color: #{$oc-gray-4}; --popup-text-color: #{$oc-gray-4};
--popup-text-inverted-color: #2c2c2c; --popup-text-inverted-color: #2c2c2c;
--dialog-border: #{$oc-gray-9};
} }
} }
-2
View File
@@ -15,7 +15,6 @@ import {
DEFAULT_VERTICAL_ALIGN, DEFAULT_VERTICAL_ALIGN,
} from "../constants"; } from "../constants";
import { getDefaultAppState } from "../appState"; import { getDefaultAppState } from "../appState";
import { getNewSceneName } from "../utils";
const getFontFamilyByName = (fontFamilyName: string): FontFamily => { const getFontFamilyByName = (fontFamilyName: string): FontFamily => {
for (const [id, fontFamilyString] of Object.entries(FONT_FAMILY)) { for (const [id, fontFamilyString] of Object.entries(FONT_FAMILY)) {
@@ -167,7 +166,6 @@ const restoreAppState = (
return { return {
...nextAppState, ...nextAppState,
name: appState.name ?? localAppState?.name ?? getNewSceneName(),
offsetLeft: appState.offsetLeft || 0, offsetLeft: appState.offsetLeft || 0,
offsetTop: appState.offsetTop || 0, offsetTop: appState.offsetTop || 0,
// Migrates from previous version where appState.zoom was a number // Migrates from previous version where appState.zoom was a number
+6 -6
View File
@@ -102,7 +102,7 @@ export class LinearElementEditor {
element, element,
scenePointerX - editingLinearElement.pointerOffset.x, scenePointerX - editingLinearElement.pointerOffset.x,
scenePointerY - editingLinearElement.pointerOffset.y, scenePointerY - editingLinearElement.pointerOffset.y,
appState.gridSize, appState.showGrid,
); );
LinearElementEditor.movePoint(element, activePointIndex, newPoint); LinearElementEditor.movePoint(element, activePointIndex, newPoint);
if (isBindingElement(element)) { if (isBindingElement(element)) {
@@ -198,7 +198,7 @@ export class LinearElementEditor {
element, element,
scenePointer.x, scenePointer.x,
scenePointer.y, scenePointer.y,
appState.gridSize, appState.showGrid,
), ),
], ],
}); });
@@ -282,7 +282,7 @@ export class LinearElementEditor {
scenePointerX: number, scenePointerX: number,
scenePointerY: number, scenePointerY: number,
editingLinearElement: LinearElementEditor, editingLinearElement: LinearElementEditor,
gridSize: number | null, isGridOn: boolean,
): LinearElementEditor { ): LinearElementEditor {
const { elementId, lastUncommittedPoint } = editingLinearElement; const { elementId, lastUncommittedPoint } = editingLinearElement;
const element = LinearElementEditor.getElement(elementId); const element = LinearElementEditor.getElement(elementId);
@@ -304,7 +304,7 @@ export class LinearElementEditor {
element, element,
scenePointerX - editingLinearElement.pointerOffset.x, scenePointerX - editingLinearElement.pointerOffset.x,
scenePointerY - editingLinearElement.pointerOffset.y, scenePointerY - editingLinearElement.pointerOffset.y,
gridSize, isGridOn,
); );
if (lastPoint === lastUncommittedPoint) { if (lastPoint === lastUncommittedPoint) {
@@ -398,9 +398,9 @@ export class LinearElementEditor {
element: NonDeleted<ExcalidrawLinearElement>, element: NonDeleted<ExcalidrawLinearElement>,
scenePointerX: number, scenePointerX: number,
scenePointerY: number, scenePointerY: number,
gridSize: number | null, isGridOn: boolean,
): Point { ): Point {
const pointerOnGrid = getGridPoint(scenePointerX, scenePointerY, gridSize); const pointerOnGrid = getGridPoint(scenePointerX, scenePointerY, isGridOn);
const [x1, y1, x2, y2] = getElementAbsoluteCoords(element); const [x1, y1, x2, y2] = getElementAbsoluteCoords(element);
const cx = (x1 + x2) / 2; const cx = (x1 + x2) / 2;
const cy = (y1 + y2) / 2; const cy = (y1 + y2) / 2;
-11
View File
@@ -1,7 +1,6 @@
import { Point } from "../types"; import { Point } from "../types";
import { FONT_FAMILY } from "../constants"; import { FONT_FAMILY } from "../constants";
export type ChartType = "bar" | "line";
export type FillStyle = "hachure" | "cross-hatch" | "solid"; export type FillStyle = "hachure" | "cross-hatch" | "solid";
export type FontFamily = keyof typeof FONT_FAMILY; export type FontFamily = keyof typeof FONT_FAMILY;
export type FontString = string & { _brand: "fontString" }; export type FontString = string & { _brand: "fontString" };
@@ -27,21 +26,11 @@ type _ExcalidrawElementBase = Readonly<{
width: number; width: number;
height: number; height: number;
angle: number; angle: number;
/** Random integer used to seed shape generation so that the roughjs shape
doesn't differ across renders. */
seed: number; seed: number;
/** Integer that is sequentially incremented on each change. Used to reconcile
elements during collaboration or when saving to server. */
version: number; version: number;
/** Random integer that is regenerated on each change.
Used for deterministic reconciliation of updates during collaboration,
in case the versions (see above) are identical. */
versionNonce: number; versionNonce: number;
isDeleted: boolean; isDeleted: boolean;
/** List of groups the element belongs to.
Ordered from deepest to shallowest. */
groupIds: readonly GroupId[]; groupIds: readonly GroupId[];
/** Ids of (linear) elements that are bound to this element. */
boundElementIds: readonly ExcalidrawLinearElement["id"][] | null; boundElementIds: readonly ExcalidrawLinearElement["id"][] | null;
}>; }>;
+5 -1
View File
@@ -123,7 +123,11 @@ const RoomDialog = ({
); );
}; };
return ( return (
<Dialog small onCloseRequest={handleClose} title={t("labels.createRoom")}> <Dialog
maxWidth={800}
onCloseRequest={handleClose}
title={t("labels.createRoom")}
>
{renderRoomDialog()} {renderRoomDialog()}
</Dialog> </Dialog>
); );
+1 -2
View File
@@ -6,7 +6,6 @@ import {
} from "../../appState"; } from "../../appState";
import { clearElementsForLocalStorage } from "../../element"; import { clearElementsForLocalStorage } from "../../element";
import { STORAGE_KEYS as APP_STORAGE_KEYS } from "../../constants"; import { STORAGE_KEYS as APP_STORAGE_KEYS } from "../../constants";
import { ImportedDataState } from "../../data/types";
export const STORAGE_KEYS = { export const STORAGE_KEYS = {
LOCAL_STORAGE_ELEMENTS: "excalidraw", LOCAL_STORAGE_ELEMENTS: "excalidraw",
@@ -82,7 +81,7 @@ export const importFromLocalStorage = () => {
} }
} }
let appState: ImportedDataState["appState"] = null; let appState = null;
if (savedState) { if (savedState) {
try { try {
appState = { appState = {
+18 -66
View File
@@ -1,16 +1,6 @@
import React, { import React, { useState, useLayoutEffect, useEffect, useRef } from "react";
useState,
useLayoutEffect,
useEffect,
useRef,
useCallback,
} from "react";
import LanguageDetector from "i18next-browser-languagedetector";
import Excalidraw, { import Excalidraw from "../packages/excalidraw/index";
languages,
defaultLang,
} from "../packages/excalidraw/index";
import { import {
getTotalStorageSize, getTotalStorageSize,
@@ -22,7 +12,7 @@ import {
import { ImportedDataState } from "../data/types"; import { ImportedDataState } from "../data/types";
import CollabWrapper, { CollabAPI } from "./collab/CollabWrapper"; import CollabWrapper, { CollabAPI } from "./collab/CollabWrapper";
import { TopErrorBoundary } from "../components/TopErrorBoundary"; import { TopErrorBoundary } from "../components/TopErrorBoundary";
import { Language, t } from "../i18n"; import { t } from "../i18n";
import { exportToBackend, loadScene } from "./data"; import { exportToBackend, loadScene } from "./data";
import { getCollaborationLinkData } from "./data"; import { getCollaborationLinkData } from "./data";
import { EVENT } from "../constants"; import { EVENT } from "../constants";
@@ -39,16 +29,6 @@ import { EVENT_LOAD, EVENT_SHARE, trackEvent } from "../analytics";
import { ErrorDialog } from "../components/ErrorDialog"; import { ErrorDialog } from "../components/ErrorDialog";
import { getDefaultAppState } from "../appState"; import { getDefaultAppState } from "../appState";
import { APP_NAME, TITLE_TIMEOUT } from "../constants"; import { APP_NAME, TITLE_TIMEOUT } from "../constants";
import { LanguageList } from "./components/LanguageList";
const languageDetector = new LanguageDetector();
languageDetector.init({
languageUtils: {
formatLanguageCode: (langCode: Language["code"]) => langCode,
isWhitelisted: () => true,
},
checkWhitelist: false,
});
const excalidrawRef: React.MutableRefObject< const excalidrawRef: React.MutableRefObject<
MarkRequired<ExcalidrawAPIRefValue, "ready" | "readyPromise"> MarkRequired<ExcalidrawAPIRefValue, "ready" | "readyPromise">
@@ -113,6 +93,7 @@ type Scene = ImportedDataState & { commitToHistory: boolean };
const initializeScene = async (opts: { const initializeScene = async (opts: {
resetScene: ExcalidrawImperativeAPI["resetScene"]; resetScene: ExcalidrawImperativeAPI["resetScene"];
initializeSocketClient: CollabAPI["initializeSocketClient"]; initializeSocketClient: CollabAPI["initializeSocketClient"];
onLateInitialization?: (scene: Scene) => void;
}): Promise<Scene | null> => { }): Promise<Scene | null> => {
const searchParams = new URLSearchParams(window.location.search); const searchParams = new URLSearchParams(window.location.search);
const id = searchParams.get("id"); const id = searchParams.get("id");
@@ -143,15 +124,17 @@ const initializeScene = async (opts: {
} else { } else {
// https://github.com/excalidraw/excalidraw/issues/1919 // https://github.com/excalidraw/excalidraw/issues/1919
if (document.hidden) { if (document.hidden) {
return new Promise((resolve, reject) => { window.addEventListener(
window.addEventListener( "focus",
"focus", () =>
() => initializeScene(opts).then(resolve).catch(reject), initializeScene(opts).then((_scene) => {
{ opts?.onLateInitialization?.(_scene || scene);
once: true, }),
}, {
); once: true,
}); },
);
return null;
} }
isCollabScene = false; isCollabScene = false;
@@ -202,8 +185,6 @@ function ExcalidrawWrapper(props: { collab: CollabAPI }) {
height: window.innerHeight, height: window.innerHeight,
}); });
const [errorMessage, setErrorMessage] = useState(""); const [errorMessage, setErrorMessage] = useState("");
const currentLangCode = languageDetector.detect() || defaultLang.code;
const [langCode, setLangCode] = useState(currentLangCode);
useLayoutEffect(() => { useLayoutEffect(() => {
const onResize = () => { const onResize = () => {
@@ -241,6 +222,9 @@ function ExcalidrawWrapper(props: { collab: CollabAPI }) {
initializeScene({ initializeScene({
resetScene: excalidrawApi.resetScene, resetScene: excalidrawApi.resetScene,
initializeSocketClient: collab.initializeSocketClient, initializeSocketClient: collab.initializeSocketClient,
onLateInitialization: (scene) => {
initialStatePromiseRef.current.promise.resolve(scene);
},
}).then((scene) => { }).then((scene) => {
initialStatePromiseRef.current.promise.resolve(scene); initialStatePromiseRef.current.promise.resolve(scene);
}); });
@@ -278,10 +262,6 @@ function ExcalidrawWrapper(props: { collab: CollabAPI }) {
}; };
}, [collab.initializeSocketClient]); }, [collab.initializeSocketClient]);
useEffect(() => {
languageDetector.cacheUserLanguage(langCode);
}, [langCode]);
const onChange = ( const onChange = (
elements: readonly ExcalidrawElement[], elements: readonly ExcalidrawElement[],
appState: AppState, appState: AppState,
@@ -317,32 +297,6 @@ function ExcalidrawWrapper(props: { collab: CollabAPI }) {
} }
} }
}; };
const renderFooter = useCallback(
(isMobile: boolean) => {
const renderLanguageList = () => (
<LanguageList
onChange={(langCode) => {
setLangCode(langCode);
}}
languages={languages}
floating={!isMobile}
currentLangCode={langCode}
/>
);
if (isMobile) {
return (
<fieldset>
<legend>{t("labels.language")}</legend>
{renderLanguageList()}
</fieldset>
);
}
return renderLanguageList();
},
[langCode],
);
return ( return (
<> <>
<Excalidraw <Excalidraw
@@ -356,8 +310,6 @@ function ExcalidrawWrapper(props: { collab: CollabAPI }) {
isCollaborating={collab.isCollaborating} isCollaborating={collab.isCollaborating}
onPointerUpdate={collab.onPointerUpdate} onPointerUpdate={collab.onPointerUpdate}
onExportToBackend={onExportToBackend} onExportToBackend={onExportToBackend}
renderFooter={renderFooter}
langCode={langCode}
/> />
{errorMessage && ( {errorMessage && (
<ErrorDialog <ErrorDialog
+73 -56
View File
@@ -1,85 +1,93 @@
import LanguageDetector from "i18next-browser-languagedetector";
import { EVENT_CHANGE, trackEvent } from "./analytics"; import { EVENT_CHANGE, trackEvent } from "./analytics";
import fallbackLangData from "./locales/en.json"; import fallbackLanguageData from "./locales/en.json";
import percentages from "./locales/percentages.json"; import percentages from "./locales/percentages.json";
const COMPLETION_THRESHOLD = 85; const COMPLETION_THRESHOLD_TO_EXCEED = 85;
export interface Language { interface Language {
code: string; lng: string;
label: string; label: string;
rtl?: boolean; rtl?: boolean;
} }
const allLanguages: Language[] = [ const allLanguages: Language[] = [
{ code: "ar-SA", label: "العربية", rtl: true }, { lng: "ar-SA", label: "العربية", rtl: true },
{ code: "bg-BG", label: "Български" }, { lng: "bg-BG", label: "Български" },
{ code: "ca-ES", label: "Catalan" }, { lng: "ca-ES", label: "Catalan" },
{ code: "de-DE", label: "Deutsch" }, { lng: "de-DE", label: "Deutsch" },
{ code: "el-GR", label: "Ελληνικά" }, { lng: "el-GR", label: "Ελληνικά" },
{ code: "es-ES", label: "Español" }, { lng: "es-ES", label: "Español" },
{ code: "fa-IR", label: "فارسی", rtl: true }, { lng: "fa-IR", label: "فارسی", rtl: true },
{ code: "fi-FI", label: "Suomi" }, { lng: "fi-FI", label: "Suomi" },
{ code: "fr-FR", label: "Français" }, { lng: "fr-FR", label: "Français" },
{ code: "he-IL", label: "עברית", rtl: true }, { lng: "he-IL", label: "עברית", rtl: true },
{ code: "hi-IN", label: "हिन्दी" }, { lng: "hi-IN", label: "हिन्दी" },
{ code: "hu-HU", label: "Magyar" }, { lng: "hu-HU", label: "Magyar" },
{ code: "id-ID", label: "Bahasa Indonesia" }, { lng: "id-ID", label: "Bahasa Indonesia" },
{ code: "it-IT", label: "Italiano" }, { lng: "it-IT", label: "Italiano" },
{ code: "ja-JP", label: "日本語" }, { lng: "ja-JP", label: "日本語" },
{ code: "ko-KR", label: "한국어" }, { lng: "ko-KR", label: "한국어" },
{ code: "my-MM", label: "Burmese" }, { lng: "my-MM", label: "Burmese" },
{ code: "nb-NO", label: "Norsk bokmål" }, { lng: "nb-NO", label: "Norsk bokmål" },
{ code: "nl-NL", label: "Nederlands" }, { lng: "nl-NL", label: "Nederlands" },
{ code: "nn-NO", label: "Norsk nynorsk" }, { lng: "nn-NO", label: "Norsk nynorsk" },
{ code: "pl-PL", label: "Polski" }, { lng: "pl-PL", label: "Polski" },
{ code: "pt-BR", label: "Português Brasileiro" }, { lng: "pt-PT", label: "Português" },
{ code: "pt-PT", label: "Português" }, { lng: "ro-RO", label: "Română" },
{ code: "ro-RO", label: "Română" }, { lng: "ru-RU", label: "Русский" },
{ code: "ru-RU", label: "Русский" }, { lng: "sk-SK", label: "Slovenčina" },
{ code: "sk-SK", label: "Slovenčina" }, { lng: "sv-SE", label: "Svenska" },
{ code: "sv-SE", label: "Svenska" }, { lng: "tr-TR", label: "Türkçe" },
{ code: "tr-TR", label: "Türkçe" }, { lng: "uk-UA", label: "Українська" },
{ code: "uk-UA", label: "Українська" }, { lng: "zh-CN", label: "简体中文" },
{ code: "zh-CN", label: "简体中文" }, { lng: "zh-TW", label: "繁體中文" },
{ code: "zh-TW", label: "繁體中文" },
]; ];
export const defaultLang = { code: "en", label: "English" }; export const languages: Language[] = [{ lng: "en", label: "English" }]
export const languages: Language[] = [defaultLang]
.concat( .concat(
allLanguages.sort((left, right) => (left.label > right.label ? 1 : -1)), allLanguages.sort((left, right) => (left.label > right.label ? 1 : -1)),
) )
.filter( .filter(
(lang) => (lang) =>
(percentages as Record<string, number>)[lang.code] >= (percentages as Record<string, number>)[lang.lng] >
COMPLETION_THRESHOLD, COMPLETION_THRESHOLD_TO_EXCEED,
); );
let currentLang: Language = defaultLang; let currentLanguage = languages[0];
let currentLangData = {}; let currentLanguageData = {};
const fallbackLanguage = languages[0];
export const setLanguage = async (lang: Language) => { export const setLanguage = async (newLng: string | undefined) => {
currentLang = lang; currentLanguage =
document.documentElement.dir = currentLang.rtl ? "rtl" : "ltr"; languages.find((language) => language.lng === newLng) || fallbackLanguage;
currentLangData = await import( document.documentElement.dir = currentLanguage.rtl ? "rtl" : "ltr";
/* webpackChunkName: "i18n-[request]" */ `./locales/${currentLang.code}.json`
currentLanguageData = await import(
/* webpackChunkName: "i18n-[request]" */ `./locales/${currentLanguage.lng}.json`
); );
trackEvent(EVENT_CHANGE, "language", currentLang.code); languageDetector.cacheUserLanguage(currentLanguage.lng);
trackEvent(EVENT_CHANGE, "language", currentLanguage.lng);
}; };
export const setLanguageFirstTime = async (lang: Language) => { export const setLanguageFirstTime = async () => {
currentLang = lang; const newLng: string | undefined = languageDetector.detect();
document.documentElement.dir = currentLang.rtl ? "rtl" : "ltr";
currentLangData = await import( currentLanguage =
/* webpackChunkName: "i18n-[request]" */ `./locales/${currentLang.code}.json` languages.find((language) => language.lng === newLng) || fallbackLanguage;
document.documentElement.dir = currentLanguage.rtl ? "rtl" : "ltr";
currentLanguageData = await import(
/* webpackChunkName: "i18n-[request]" */ `./locales/${currentLanguage.lng}.json`
); );
languageDetector.cacheUserLanguage(currentLanguage.lng);
}; };
export const getLanguage = () => currentLang; export const getLanguage = () => currentLanguage;
const findPartsForData = (data: any, parts: string[]) => { const findPartsForData = (data: any, parts: string[]) => {
for (let index = 0; index < parts.length; ++index) { for (let index = 0; index < parts.length; ++index) {
@@ -98,8 +106,8 @@ const findPartsForData = (data: any, parts: string[]) => {
export const t = (path: string, replacement?: { [key: string]: string }) => { export const t = (path: string, replacement?: { [key: string]: string }) => {
const parts = path.split("."); const parts = path.split(".");
let translation = let translation =
findPartsForData(currentLangData, parts) || findPartsForData(currentLanguageData, parts) ||
findPartsForData(fallbackLangData, parts); findPartsForData(fallbackLanguageData, parts);
if (translation === undefined) { if (translation === undefined) {
throw new Error(`Can't find translation for ${path}`); throw new Error(`Can't find translation for ${path}`);
} }
@@ -111,3 +119,12 @@ export const t = (path: string, replacement?: { [key: string]: string }) => {
} }
return translation; return translation;
}; };
const languageDetector = new LanguageDetector();
languageDetector.init({
languageUtils: {
formatLanguageCode: (lng: string) => lng,
isWhitelisted: () => true,
},
checkWhitelist: false,
});
-2
View File
@@ -1,6 +1,5 @@
import { exportToCanvas } from "./scene/export"; import { exportToCanvas } from "./scene/export";
import { getDefaultAppState } from "./appState"; import { getDefaultAppState } from "./appState";
import { SCENE_NAME_FALLBACK } from "./constants";
const { registerFont, createCanvas } = require("canvas"); const { registerFont, createCanvas } = require("canvas");
@@ -62,7 +61,6 @@ const canvas = exportToCanvas(
elements as any, elements as any,
{ {
...getDefaultAppState(), ...getDefaultAppState(),
name: SCENE_NAME_FALLBACK,
offsetTop: 0, offsetTop: 0,
offsetLeft: 0, offsetLeft: 0,
}, },
-1
View File
@@ -11,7 +11,6 @@ export const IsMobileProvider = ({
if (!query.current) { if (!query.current) {
query.current = window.matchMedia query.current = window.matchMedia
? window.matchMedia( ? window.matchMedia(
// keep up to date with _variables.scss
"(max-width: 640px), (max-height: 500px) and (max-width: 1000px)", "(max-width: 640px), (max-height: 500px) and (max-width: 1000px)",
) )
: (({ : (({
+7 -8
View File
@@ -37,7 +37,7 @@
"fontSize": "حجم الخط", "fontSize": "حجم الخط",
"fontFamily": "نوع الخط", "fontFamily": "نوع الخط",
"onlySelected": "المحدد فقط", "onlySelected": "المحدد فقط",
"withBackground": "", "withBackground": "مع الخلفية",
"exportEmbedScene": "تضمين المشهد في ملف التصدير", "exportEmbedScene": "تضمين المشهد في ملف التصدير",
"exportEmbedScene_details": "سيتم حفظ بيانات المشهد في ملف PNG/SVG المصدّر بحيث يمكن استعادة المشهد منه.\nسيزيد حجم الملف المصدر.", "exportEmbedScene_details": "سيتم حفظ بيانات المشهد في ملف PNG/SVG المصدّر بحيث يمكن استعادة المشهد منه.\nسيزيد حجم الملف المصدر.",
"addWatermark": "إضافة \"مصنوعة بواسطة Excalidraw\"", "addWatermark": "إضافة \"مصنوعة بواسطة Excalidraw\"",
@@ -76,7 +76,8 @@
"group": "تحديد مجموعة", "group": "تحديد مجموعة",
"ungroup": "إلغاء تحديد مجموعة", "ungroup": "إلغاء تحديد مجموعة",
"collaborators": "المتعاونون", "collaborators": "المتعاونون",
"gridMode": "", "toggleGridMode": "التبديل إلى وضع الشبكة",
"toggleStats": "",
"addToLibrary": "أضف إلى المكتبة", "addToLibrary": "أضف إلى المكتبة",
"removeFromLibrary": "حذف من المكتبة", "removeFromLibrary": "حذف من المكتبة",
"libraryLoadingMessage": "جارٍ تحميل المكتبة...", "libraryLoadingMessage": "جارٍ تحميل المكتبة...",
@@ -117,10 +118,9 @@
"redo": "إعادة تنفيذ", "redo": "إعادة تنفيذ",
"roomDialog": "بدء المشاركة الحية", "roomDialog": "بدء المشاركة الحية",
"createNewRoom": "إنشاء غرفة جديدة", "createNewRoom": "إنشاء غرفة جديدة",
"fullScreen": "", "toggleFullScreen": "التبديل لوضع ملء الشاشة",
"darkMode": "", "toggleDarkMode": "تبديل الوضع الليلي",
"lightMode": "", "toggleZenMode": "تبديل الوضع الليلي",
"zenMode": "",
"exitZenMode": "إلغاء الوضع الليلى" "exitZenMode": "إلغاء الوضع الليلى"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "تحميل الرسم الخارجي سيحل محل المحتوى الموجود لديك. هل ترغب في المتابعة؟", "loadSceneOverridePrompt": "تحميل الرسم الخارجي سيحل محل المحتوى الموجود لديك. هل ترغب في المتابعة؟",
"errorLoadingLibrary": "حصل خطأ أثناء تحميل مكتبة الطرف الثالث.", "errorLoadingLibrary": "حصل خطأ أثناء تحميل مكتبة الطرف الثالث.",
"confirmAddLibrary": "هذا سيضيف {{numShapes}} شكل إلى مكتبتك. هل أنت متأكد؟", "confirmAddLibrary": "هذا سيضيف {{numShapes}} شكل إلى مكتبتك. هل أنت متأكد؟",
"imageDoesNotContainScene": "", "imageDoesNotContainScene": "لا يحتوي ملف الصورة على بيانات المشهد. هل قمت بتمكين هذا أثناء التصدير؟",
"cannotRestoreFromImage": "تعذر استعادة المشهد من ملف الصورة" "cannotRestoreFromImage": "تعذر استعادة المشهد من ملف الصورة"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "انقر واسحب، افرج عند الانتهاء", "freeDraw": "انقر واسحب، افرج عند الانتهاء",
"text": "نصيحة: يمكنك أيضًا إضافة نص بالنقر المزدوج في أي مكان بأداة الاختيار", "text": "نصيحة: يمكنك أيضًا إضافة نص بالنقر المزدوج في أي مكان بأداة الاختيار",
"linearElementMulti": "انقر فوق النقطة الأخيرة أو اضغط على Esc أو Enter للإنهاء", "linearElementMulti": "انقر فوق النقطة الأخيرة أو اضغط على Esc أو Enter للإنهاء",
"lockAngle": "",
"resize": "يمكنك تقييد النسب بالضغط على SHIFT أثناء تغيير الحجم،\nاضغط على ALT لتغيير الحجم من المركز", "resize": "يمكنك تقييد النسب بالضغط على SHIFT أثناء تغيير الحجم،\nاضغط على ALT لتغيير الحجم من المركز",
"rotate": "يمكنك تقييد الزوايا من خلال الضغط على SHIFT أثناء الدوران", "rotate": "يمكنك تقييد الزوايا من خلال الضغط على SHIFT أثناء الدوران",
"lineEditor_info": "انقر نقراً مزدوجاً أو اضغط Enter لتعديل النقاط", "lineEditor_info": "انقر نقراً مزدوجاً أو اضغط Enter لتعديل النقاط",
+7 -8
View File
@@ -31,13 +31,13 @@
"round": "", "round": "",
"arrowheads": "", "arrowheads": "",
"arrowhead_none": "", "arrowhead_none": "",
"arrowhead_arrow": "Стрелка", "arrowhead_arrow": "",
"arrowhead_bar": "", "arrowhead_bar": "",
"arrowhead_dot": "", "arrowhead_dot": "",
"fontSize": "Размер на шрифта", "fontSize": "Размер на шрифта",
"fontFamily": "Семейство шрифтове", "fontFamily": "Семейство шрифтове",
"onlySelected": "Само избраното", "onlySelected": "Само избраното",
"withBackground": "", "withBackground": "С фон",
"exportEmbedScene": "", "exportEmbedScene": "",
"exportEmbedScene_details": "", "exportEmbedScene_details": "",
"addWatermark": "", "addWatermark": "",
@@ -76,7 +76,8 @@
"group": "", "group": "",
"ungroup": "", "ungroup": "",
"collaborators": "", "collaborators": "",
"gridMode": "", "toggleGridMode": "",
"toggleStats": "",
"addToLibrary": "", "addToLibrary": "",
"removeFromLibrary": "", "removeFromLibrary": "",
"libraryLoadingMessage": "", "libraryLoadingMessage": "",
@@ -117,10 +118,9 @@
"redo": "Повтори", "redo": "Повтори",
"roomDialog": "Започнете сътрудничество на живо", "roomDialog": "Започнете сътрудничество на живо",
"createNewRoom": "Създай нова стая", "createNewRoom": "Създай нова стая",
"fullScreen": "", "toggleFullScreen": "Превключване на цял екран",
"darkMode": "", "toggleDarkMode": "",
"lightMode": "", "toggleZenMode": "",
"zenMode": "",
"exitZenMode": "" "exitZenMode": ""
}, },
"alerts": { "alerts": {
@@ -161,7 +161,6 @@
"freeDraw": "", "freeDraw": "",
"text": "", "text": "",
"linearElementMulti": "Кликнете върху последната точка или натиснете Escape или Enter, за да завършите", "linearElementMulti": "Кликнете върху последната точка или натиснете Escape или Enter, за да завършите",
"lockAngle": "",
"resize": "", "resize": "",
"rotate": "Можете да ограничите ъглите, като държите SHIFT, докато се въртите", "rotate": "Можете да ограничите ъглите, като държите SHIFT, докато се въртите",
"lineEditor_info": "", "lineEditor_info": "",
+6 -7
View File
@@ -37,7 +37,7 @@
"fontSize": "Mida de lletra", "fontSize": "Mida de lletra",
"fontFamily": "Tipus de lletra", "fontFamily": "Tipus de lletra",
"onlySelected": "Només seleccionats", "onlySelected": "Només seleccionats",
"withBackground": "", "withBackground": "Amb fons",
"exportEmbedScene": "", "exportEmbedScene": "",
"exportEmbedScene_details": "", "exportEmbedScene_details": "",
"addWatermark": "Afegir \"Fet amb Excalidraw\"", "addWatermark": "Afegir \"Fet amb Excalidraw\"",
@@ -76,7 +76,8 @@
"group": "Agrupar la selecció", "group": "Agrupar la selecció",
"ungroup": "Desagrupar la selecció", "ungroup": "Desagrupar la selecció",
"collaborators": "Col·laboradors", "collaborators": "Col·laboradors",
"gridMode": "", "toggleGridMode": "Commutar línies de graella",
"toggleStats": "",
"addToLibrary": "Afegir a la biblioteca", "addToLibrary": "Afegir a la biblioteca",
"removeFromLibrary": "Eliminar de la biblioteca", "removeFromLibrary": "Eliminar de la biblioteca",
"libraryLoadingMessage": "Carregant la biblioteca...", "libraryLoadingMessage": "Carregant la biblioteca...",
@@ -117,10 +118,9 @@
"redo": "Refer", "redo": "Refer",
"roomDialog": "Començar col·laboració en directe", "roomDialog": "Començar col·laboració en directe",
"createNewRoom": "Crear sala nova", "createNewRoom": "Crear sala nova",
"fullScreen": "", "toggleFullScreen": "Commutar pantalla completa",
"darkMode": "", "toggleDarkMode": "Commutar modo fosc",
"lightMode": "", "toggleZenMode": "Commutar modo zen",
"zenMode": "",
"exitZenMode": "Sortir de modo zen" "exitZenMode": "Sortir de modo zen"
}, },
"alerts": { "alerts": {
@@ -161,7 +161,6 @@
"freeDraw": "Fer clic i arrosegar, deixar anar al punt final", "freeDraw": "Fer clic i arrosegar, deixar anar al punt final",
"text": "Consell: també pots afegir text fent doble clic a qualsevol lloc amb l'eina de selecció", "text": "Consell: també pots afegir text fent doble clic a qualsevol lloc amb l'eina de selecció",
"linearElementMulti": "Fer clic a l'ultim punt, o polsar Escape o Enter per acabar", "linearElementMulti": "Fer clic a l'ultim punt, o polsar Escape o Enter per acabar",
"lockAngle": "",
"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", "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",
"rotate": "Per restringir els angles mentre gira, mantenir premut el majúscul (SHIFT)", "rotate": "Per restringir els angles mentre gira, mantenir premut el majúscul (SHIFT)",
"lineEditor_info": "Fes doble clic o premi Enter per editar punts", "lineEditor_info": "Fes doble clic o premi Enter per editar punts",
+7 -8
View File
@@ -76,7 +76,8 @@
"group": "Auswahl gruppieren", "group": "Auswahl gruppieren",
"ungroup": "Gruppierung aufheben", "ungroup": "Gruppierung aufheben",
"collaborators": "Mitarbeitende", "collaborators": "Mitarbeitende",
"gridMode": "Rastermodus", "toggleGridMode": "Gitterlinien ein-/ausschalten",
"toggleStats": "Statistiken für Nerds ein-/ausschalten",
"addToLibrary": "Zur Bibliothek hinzufügen", "addToLibrary": "Zur Bibliothek hinzufügen",
"removeFromLibrary": "Aus Bibliothek entfernen", "removeFromLibrary": "Aus Bibliothek entfernen",
"libraryLoadingMessage": "Lade Bibliothek...", "libraryLoadingMessage": "Lade Bibliothek...",
@@ -117,10 +118,9 @@
"redo": "Wiederholen", "redo": "Wiederholen",
"roomDialog": "Live-Kollaborationssitzung starten", "roomDialog": "Live-Kollaborationssitzung starten",
"createNewRoom": "Neuen Raum erstellen", "createNewRoom": "Neuen Raum erstellen",
"fullScreen": "Vollbildanzeige", "toggleFullScreen": "Vollbild umschalten",
"darkMode": "Dunkles Design", "toggleDarkMode": "Dunkles Design umschalten",
"lightMode": "Helles Design", "toggleZenMode": "Zen-Modus umschalten",
"zenMode": "Zen-Modus",
"exitZenMode": "Zen-Modus verlassen" "exitZenMode": "Zen-Modus verlassen"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Das Laden der externen Zeichnung ersetzt den vorhandenen Inhalt. Möchtest Du fortfahren?", "loadSceneOverridePrompt": "Das Laden der externen Zeichnung ersetzt den vorhandenen Inhalt. Möchtest Du fortfahren?",
"errorLoadingLibrary": "Beim Laden der Drittanbieter-Bibliothek ist ein Fehler aufgetreten.", "errorLoadingLibrary": "Beim Laden der Drittanbieter-Bibliothek ist ein Fehler aufgetreten.",
"confirmAddLibrary": "Dieses fügt {{numShapes}} Form(en) zu deiner Bibliothek hinzu. Bist du sicher?", "confirmAddLibrary": "Dieses fügt {{numShapes}} Form(en) zu deiner Bibliothek hinzu. Bist du sicher?",
"imageDoesNotContainScene": "Das Importieren von Bildern wird derzeit nicht unterstützt.\n\nMöchtest du eine Szene importieren? Dieses Bild scheint keine Zeichnungsdaten zu enthalten. Hast du dies beim Exportieren aktiviert?", "imageDoesNotContainScene": "Bilddatei enthält keine Zeichnungsdaten. Hast du das Einbetten beim Export aktiviert?",
"cannotRestoreFromImage": "Die Zeichnung konnte aus dieser Bilddatei nicht wiederhergestellt werden" "cannotRestoreFromImage": "Die Zeichnung konnte aus dieser Bilddatei nicht wiederhergestellt werden"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Klicke und ziehe. Lass los, wenn du fertig bist", "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", "text": "Tipp: Du kannst auch Text hinzufügen indem Du mit dem Auswahlwerkzeug auf eine beliebige Stelle doppelklickst",
"linearElementMulti": "Zum Beenden auf den letzten Punkt klicken oder Escape oder Eingabe drücken", "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", "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",
"rotate": "Du kannst Winkel einschränken, indem du SHIFT während der Drehung gedrückt hältst", "rotate": "Du kannst Winkel einschränken, indem du SHIFT während der Drehung gedrückt hältst",
"lineEditor_info": "Doppelklicken oder Eingabetaste drücken, um Punkte zu bearbeiten", "lineEditor_info": "Doppelklicken oder Eingabetaste drücken, um Punkte zu bearbeiten",
@@ -214,7 +213,7 @@
"textNewLine": "Neue Zeile hinzufügen (Text)", "textNewLine": "Neue Zeile hinzufügen (Text)",
"textFinish": "Bearbeiten beenden (Text)", "textFinish": "Bearbeiten beenden (Text)",
"zoomToFit": "Zoomen um alle Elemente einzupassen", "zoomToFit": "Zoomen um alle Elemente einzupassen",
"zoomToSelection": "Zoomauswahl", "zoomToSelection": "",
"preventBinding": "Pfeil-Bindung verhindern" "preventBinding": "Pfeil-Bindung verhindern"
}, },
"encrypted": { "encrypted": {
+10 -11
View File
@@ -37,7 +37,7 @@
"fontSize": "Μέγεθος γραμματοσειράς", "fontSize": "Μέγεθος γραμματοσειράς",
"fontFamily": "Γραμματοσειρά", "fontFamily": "Γραμματοσειρά",
"onlySelected": "Μόνο τα Επιλεγμένα", "onlySelected": "Μόνο τα Επιλεγμένα",
"withBackground": "Με φόντο", "withBackground": "Με Φόντο",
"exportEmbedScene": "Ενσωμάτωση της σκηνής στο αρχείο προς εξαγωγή", "exportEmbedScene": "Ενσωμάτωση της σκηνής στο αρχείο προς εξαγωγή",
"exportEmbedScene_details": "Τα δεδομένα σκηνής θα αποθηκευτούν στο αρχείο PNG/SVG προς εξαγωγή ώστε η σκηνή να είναι δυνατό να αποκατασταθεί από αυτό.\nΘα αυξήσει το μέγεθος του αρχείου προς εξαγωγή.", "exportEmbedScene_details": "Τα δεδομένα σκηνής θα αποθηκευτούν στο αρχείο PNG/SVG προς εξαγωγή ώστε η σκηνή να είναι δυνατό να αποκατασταθεί από αυτό.\nΘα αυξήσει το μέγεθος του αρχείου προς εξαγωγή.",
"addWatermark": "Προσθήκη \"Φτιαγμένο με Excalidraw\"", "addWatermark": "Προσθήκη \"Φτιαγμένο με Excalidraw\"",
@@ -76,7 +76,8 @@
"group": "Δημιουργία ομάδας από επιλογή", "group": "Δημιουργία ομάδας από επιλογή",
"ungroup": "Κατάργηση ομάδας από επιλογή", "ungroup": "Κατάργηση ομάδας από επιλογή",
"collaborators": "Συνεργάτες", "collaborators": "Συνεργάτες",
"gridMode": "Εμφάνιση σε πλέγμα", "toggleGridMode": "Εναλλαγή λειτουργίας πλέγματος",
"toggleStats": "",
"addToLibrary": "Προσθήκη στη βιβλιοθήκη", "addToLibrary": "Προσθήκη στη βιβλιοθήκη",
"removeFromLibrary": "Αφαίρεση από τη βιβλιοθήκη", "removeFromLibrary": "Αφαίρεση από τη βιβλιοθήκη",
"libraryLoadingMessage": "Φόρτωση βιβλιοθήκης...", "libraryLoadingMessage": "Φόρτωση βιβλιοθήκης...",
@@ -117,10 +118,9 @@
"redo": "Επαναφορά", "redo": "Επαναφορά",
"roomDialog": "Έναρξη ζωντανής συνεργασίας", "roomDialog": "Έναρξη ζωντανής συνεργασίας",
"createNewRoom": "Δημιουργία νέου χώρου", "createNewRoom": "Δημιουργία νέου χώρου",
"fullScreen": "Πλήρης οθόνη", "toggleFullScreen": "Εναλλαγή πλήρους οθόνης",
"darkMode": "Σκοτεινή λειτουργία", "toggleDarkMode": "Εναλλαγή εμφάνισης σε dark",
"lightMode": "Φωτεινή λειτουργία", "toggleZenMode": "Εναλλαγή λειτουργίας Zen",
"zenMode": "Λειτουργία Zεν",
"exitZenMode": "Έξοδος απο την λειτουργία Zen" "exitZenMode": "Έξοδος απο την λειτουργία Zen"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Η φόρτωση εξωτερικού σχεδίου θα αντικαταστήσει το υπάρχον περιεχόμενο. Επιθυμείτε να συνεχίσετε;", "loadSceneOverridePrompt": "Η φόρτωση εξωτερικού σχεδίου θα αντικαταστήσει το υπάρχον περιεχόμενο. Επιθυμείτε να συνεχίσετε;",
"errorLoadingLibrary": "Υπήρξε ένα σφάλμα κατά τη φόρτωση της βιβλιοθήκης τρίτου μέρους.", "errorLoadingLibrary": "Υπήρξε ένα σφάλμα κατά τη φόρτωση της βιβλιοθήκης τρίτου μέρους.",
"confirmAddLibrary": "Αυτό θα προσθέσει {{numShapes}} σχήμα(τα) στη βιβιλιοθήκη σας. Είστε σίγουροι;", "confirmAddLibrary": "Αυτό θα προσθέσει {{numShapes}} σχήμα(τα) στη βιβιλιοθήκη σας. Είστε σίγουροι;",
"imageDoesNotContainScene": "", "imageDoesNotContainScene": "Το αρχείο εικόνας δεν έχει δεδομένα σκηνής. Το είχατε ενεργοποιήσει αυτό κατά την εξαγωγή;",
"cannotRestoreFromImage": "Η σκηνή δεν ήταν δυνατό να αποκατασταθεί από αυτό το αρχείο εικόνας" "cannotRestoreFromImage": "Η σκηνή δεν ήταν δυνατό να αποκατασταθεί από αυτό το αρχείο εικόνας"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Κάντε κλικ και σύρατε, απελευθερώσατε όταν έχετε τελειώσει", "freeDraw": "Κάντε κλικ και σύρατε, απελευθερώσατε όταν έχετε τελειώσει",
"text": "Tip: μπορείτε επίσης να προσθέστε κείμενο με διπλό-κλικ οπουδήποτε με το εργαλείο επιλογών", "text": "Tip: μπορείτε επίσης να προσθέστε κείμενο με διπλό-κλικ οπουδήποτε με το εργαλείο επιλογών",
"linearElementMulti": "Κάνε κλικ στο τελευταίο σημείο ή πάτησε Escape ή Enter για να τελειώσεις", "linearElementMulti": "Κάνε κλικ στο τελευταίο σημείο ή πάτησε Escape ή Enter για να τελειώσεις",
"lockAngle": "",
"resize": "Μπορείς να περιορίσεις τις αναλογίες κρατώντας το SHIFT ενώ αλλάζεις μέγεθος,\nκράτησε πατημένο το ALT για αλλαγή μεγέθους από το κέντρο", "resize": "Μπορείς να περιορίσεις τις αναλογίες κρατώντας το SHIFT ενώ αλλάζεις μέγεθος,\nκράτησε πατημένο το ALT για αλλαγή μεγέθους από το κέντρο",
"rotate": "Μπορείς να περιορίσεις τις γωνίες κρατώντας πατημένο το πλήκτρο SHIFT κατά την περιστροφή", "rotate": "Μπορείς να περιορίσεις τις γωνίες κρατώντας πατημένο το πλήκτρο SHIFT κατά την περιστροφή",
"lineEditor_info": "Διπλό-κλικ ή πιέστε Enter για να επεξεργαστείτε τα σημεία", "lineEditor_info": "Διπλό-κλικ ή πιέστε Enter για να επεξεργαστείτε τα σημεία",
@@ -170,7 +169,7 @@
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "", "cannotShowPreview": "",
"canvasTooBig": "Ο καμβάς μπορεί να είναι μεγάλος.", "canvasTooBig": "",
"canvasTooBigTip": "" "canvasTooBigTip": ""
}, },
"errorSplash": { "errorSplash": {
@@ -225,10 +224,10 @@
"element": "Στοιχείο", "element": "Στοιχείο",
"elements": "Στοιχεία", "elements": "Στοιχεία",
"height": "Ύψος", "height": "Ύψος",
"scene": "Σκηνή", "scene": "",
"selected": "Επιλεγμένα", "selected": "Επιλεγμένα",
"storage": "Χώρος", "storage": "Χώρος",
"title": "Στατιστικά για σπασίκλες", "title": "",
"total": "Σύνολο ", "total": "Σύνολο ",
"width": "Πλάτος" "width": "Πλάτος"
} }
-1
View File
@@ -1,7 +1,6 @@
{ {
"labels": { "labels": {
"paste": "Paste", "paste": "Paste",
"pasteCharts": "Paste charts",
"selectAll": "Select all", "selectAll": "Select all",
"multiSelect": "Add element to selection", "multiSelect": "Add element to selection",
"moveCanvas": "Move canvas", "moveCanvas": "Move canvas",
+41 -42
View File
@@ -4,7 +4,7 @@
"selectAll": "Seleccionar todo", "selectAll": "Seleccionar todo",
"multiSelect": "Añadir elemento a la selección", "multiSelect": "Añadir elemento a la selección",
"moveCanvas": "Mover el lienzo", "moveCanvas": "Mover el lienzo",
"cut": "Cortar", "cut": "",
"copy": "Copiar", "copy": "Copiar",
"copyAsPng": "Copiar al portapapeles como PNG", "copyAsPng": "Copiar al portapapeles como PNG",
"copyAsSvg": "Copiar al portapapeles como SVG", "copyAsSvg": "Copiar al portapapeles como SVG",
@@ -29,17 +29,17 @@
"edges": "Bordes", "edges": "Bordes",
"sharp": "Afilado", "sharp": "Afilado",
"round": "Redondo", "round": "Redondo",
"arrowheads": "Puntas de flecha", "arrowheads": "",
"arrowhead_none": "Vacía", "arrowhead_none": "",
"arrowhead_arrow": "Flecha", "arrowhead_arrow": "",
"arrowhead_bar": "Barra", "arrowhead_bar": "",
"arrowhead_dot": "Punto", "arrowhead_dot": "",
"fontSize": "Tamaño de la fuente", "fontSize": "Tamaño de la fuente",
"fontFamily": "Tipo de fuente", "fontFamily": "Tipo de fuente",
"onlySelected": "Sólo seleccionados", "onlySelected": "Sólo seleccionados",
"withBackground": "Con fondo", "withBackground": "Con fondo",
"exportEmbedScene": "Insertar escena en el archivo exportado", "exportEmbedScene": "",
"exportEmbedScene_details": "Los datos de escena se guardarán en el archivo PNG/SVG exportado para que la escena pueda ser restaurada de ella.\nIncrementará el tamaño del archivo exportado.", "exportEmbedScene_details": "",
"addWatermark": "Agregar \"Hecho con Excalidraw\"", "addWatermark": "Agregar \"Hecho con Excalidraw\"",
"handDrawn": "Dibujado a mano", "handDrawn": "Dibujado a mano",
"normal": "Normal", "normal": "Normal",
@@ -60,7 +60,7 @@
"architect": "Arquitecto", "architect": "Arquitecto",
"artist": "Artista", "artist": "Artista",
"cartoonist": "Caricatura", "cartoonist": "Caricatura",
"fileTitle": "Título del archivo", "fileTitle": "",
"colorPicker": "Selector de color", "colorPicker": "Selector de color",
"canvasBackground": "Fondo del lienzo", "canvasBackground": "Fondo del lienzo",
"drawingCanvas": "Lienzo de dibujo", "drawingCanvas": "Lienzo de dibujo",
@@ -69,28 +69,29 @@
"language": "Idioma", "language": "Idioma",
"createRoom": "Compartir una sesión de colaboración en vivo", "createRoom": "Compartir una sesión de colaboración en vivo",
"duplicateSelection": "Duplicar", "duplicateSelection": "Duplicar",
"untitled": "Sin título", "untitled": "",
"name": "Nombre", "name": "Nombre",
"yourName": "Tu nombre", "yourName": "Tu nombre",
"madeWithExcalidraw": "Hecho con Excalidraw", "madeWithExcalidraw": "Hecho con Excalidraw",
"group": "Selección de grupo", "group": "Selección de grupo",
"ungroup": "Desagrupar", "ungroup": "Desagrupar",
"collaborators": "Colaboradores", "collaborators": "Colaboradores",
"gridMode": "Modo cuadrícula", "toggleGridMode": "Alternar modo cuadrícula",
"toggleStats": "",
"addToLibrary": "Añadir a la biblioteca", "addToLibrary": "Añadir a la biblioteca",
"removeFromLibrary": "Eliminar de la biblioteca", "removeFromLibrary": "Eliminar de la biblioteca",
"libraryLoadingMessage": "Cargando biblioteca...", "libraryLoadingMessage": "Cargando biblioteca...",
"libraries": "Explorar librerías", "libraries": "",
"loadingScene": "Cargando escena...", "loadingScene": "Cargando escena...",
"align": "Alinear", "align": "",
"alignTop": "Alinear arriba", "alignTop": "",
"alignBottom": "Alinear abajo", "alignBottom": "",
"alignLeft": "Alinear a la izquierda", "alignLeft": "",
"alignRight": "Alinear a la derecha", "alignRight": "",
"centerVertically": "Centrar verticalmente", "centerVertically": "",
"centerHorizontally": "Centrar horizontalmente", "centerHorizontally": "",
"distributeHorizontally": "Distribuir horizontalmente", "distributeHorizontally": "",
"distributeVertically": "Distribuir verticalmente" "distributeVertically": ""
}, },
"buttons": { "buttons": {
"clearReset": "Limpiar lienzo y reiniciar el color de fondo", "clearReset": "Limpiar lienzo y reiniciar el color de fondo",
@@ -117,16 +118,15 @@
"redo": "Rehacer", "redo": "Rehacer",
"roomDialog": "Iniciar colaboración en vivo", "roomDialog": "Iniciar colaboración en vivo",
"createNewRoom": "Crear nueva sala", "createNewRoom": "Crear nueva sala",
"fullScreen": "Pantalla completa", "toggleFullScreen": "Alternar pantalla completa",
"darkMode": "Modo oscuro", "toggleDarkMode": "Cambiar a modo oscuro",
"lightMode": "Modo claro", "toggleZenMode": "Alternar modo zen",
"zenMode": "Modo Zen",
"exitZenMode": "Salir del modo Zen" "exitZenMode": "Salir del modo Zen"
}, },
"alerts": { "alerts": {
"clearReset": "Esto limpiará todo el lienzo. Estás seguro?", "clearReset": "Esto limpiará todo el lienzo. Estás seguro?",
"couldNotCreateShareableLink": "No se pudo crear un enlace para compartir.", "couldNotCreateShareableLink": "No se pudo crear un enlace para compartir.",
"couldNotCreateShareableLinkTooBig": "No se pudo crear el enlace para compartir: la escena es demasiado grande", "couldNotCreateShareableLinkTooBig": "",
"couldNotLoadInvalidFile": "No se pudo cargar el archivo inválido", "couldNotLoadInvalidFile": "No se pudo cargar el archivo inválido",
"importBackendFailed": "La importación falló.", "importBackendFailed": "La importación falló.",
"cannotExportEmptyCanvas": "No se puede exportar un lienzo vació", "cannotExportEmptyCanvas": "No se puede exportar un lienzo vació",
@@ -136,8 +136,8 @@
"loadSceneOverridePrompt": "Si carga este dibujo externo, reemplazará el que tiene. ¿Desea continuar?", "loadSceneOverridePrompt": "Si carga este dibujo externo, reemplazará el que tiene. ¿Desea continuar?",
"errorLoadingLibrary": "Se ha producido un error al cargar la biblioteca de terceros.", "errorLoadingLibrary": "Se ha producido un error al cargar la biblioteca de terceros.",
"confirmAddLibrary": "Esto añadirá {{numShapes}} forma(s) a tu biblioteca. ¿Estás seguro?", "confirmAddLibrary": "Esto añadirá {{numShapes}} forma(s) a tu biblioteca. ¿Estás seguro?",
"imageDoesNotContainScene": "La importación de imágenes no está soportada en este momento.\n\n¿Querías importar una escena? Esta imagen no parece contener ningún dato de escena. ¿Lo ha activado durante la exportación?", "imageDoesNotContainScene": "",
"cannotRestoreFromImage": "No se pudo restaurar la escena desde este archivo de imagen" "cannotRestoreFromImage": ""
}, },
"toolBar": { "toolBar": {
"selection": "Selección", "selection": "Selección",
@@ -161,7 +161,6 @@
"freeDraw": "Haz clic y arrastra, suelta al terminar", "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", "text": "Consejo: también puedes añadir texto haciendo doble clic en cualquier lugar con la herramienta de selección",
"linearElementMulti": "Haga clic en el último punto o pulse Escape o Enter para finalizar", "linearElementMulti": "Haga clic en el último punto o pulse Escape o Enter para finalizar",
"lockAngle": "",
"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", "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",
"rotate": "Puede restringir los ángulos manteniendo presionado SHIFT mientras gira", "rotate": "Puede restringir los ángulos manteniendo presionado SHIFT mientras gira",
"lineEditor_info": "haga doble clic o pulse Enter para editar puntos", "lineEditor_info": "haga doble clic o pulse Enter para editar puntos",
@@ -169,9 +168,9 @@
"lineEditor_nothingSelected": "Seleccione un punto para mover o eliminar, o mantenga pulsado Alt y haga clic para añadir nuevos puntos" "lineEditor_nothingSelected": "Seleccione un punto para mover o eliminar, o mantenga pulsado Alt y haga clic para añadir nuevos puntos"
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "No se puede mostrar la vista previa", "cannotShowPreview": "",
"canvasTooBig": "El lienzo podría ser demasiado grande.", "canvasTooBig": "",
"canvasTooBigTip": "Sugerencia: intenta acercar un poco los elementos más lejanos." "canvasTooBigTip": ""
}, },
"errorSplash": { "errorSplash": {
"headingMain_pre": "Se encontró un error. Intente ", "headingMain_pre": "Se encontró un error. Intente ",
@@ -214,22 +213,22 @@
"textNewLine": "Añadir nueva línea (texto)", "textNewLine": "Añadir nueva línea (texto)",
"textFinish": "Finalizar edición (texto)", "textFinish": "Finalizar edición (texto)",
"zoomToFit": "Ajustar para mostrar todos los elementos", "zoomToFit": "Ajustar para mostrar todos los elementos",
"zoomToSelection": "Hacer zoom a la selección", "zoomToSelection": "",
"preventBinding": "Evitar enlace de flecha" "preventBinding": "Evitar enlace de flecha"
}, },
"encrypted": { "encrypted": {
"tooltip": "Tus dibujos están cifrados de punto a punto, por lo que los servidores de Excalidraw nunca los verán." "tooltip": "Tus dibujos están cifrados de punto a punto, por lo que los servidores de Excalidraw nunca los verán."
}, },
"stats": { "stats": {
"angle": "Ángulo", "angle": "",
"element": "Elemento", "element": "",
"elements": "Elementos", "elements": "",
"height": "Alto", "height": "",
"scene": "Escena", "scene": "",
"selected": "Seleccionado", "selected": "",
"storage": "Almacenamiento", "storage": "",
"title": "", "title": "",
"total": "Total", "total": "",
"width": "Ancho" "width": ""
} }
} }
+7 -8
View File
@@ -37,7 +37,7 @@
"fontSize": "اندازه قلم", "fontSize": "اندازه قلم",
"fontFamily": "نوع قلم", "fontFamily": "نوع قلم",
"onlySelected": "فقط انتخاب شده ها", "onlySelected": "فقط انتخاب شده ها",
"withBackground": "", "withBackground": "با پس زمینه",
"exportEmbedScene": "قرار دادن صحنه در فایل خروجی", "exportEmbedScene": "قرار دادن صحنه در فایل خروجی",
"exportEmbedScene_details": "متحوای صحنه به فایل خروجی SVG/PNG اضافه خواهد شد برای بازیابی صحنه به آن اضافه خواهد شد.\nباعث افزایش حجم فایل خروجی میشود.", "exportEmbedScene_details": "متحوای صحنه به فایل خروجی SVG/PNG اضافه خواهد شد برای بازیابی صحنه به آن اضافه خواهد شد.\nباعث افزایش حجم فایل خروجی میشود.",
"addWatermark": "\"ساخته شده با Excalidraw\" را اضافه کن", "addWatermark": "\"ساخته شده با Excalidraw\" را اضافه کن",
@@ -76,7 +76,8 @@
"group": "گروهبندی انتخابها", "group": "گروهبندی انتخابها",
"ungroup": "حذف گروهبندی انتخابها", "ungroup": "حذف گروهبندی انتخابها",
"collaborators": "همکاران", "collaborators": "همکاران",
"gridMode": "", "toggleGridMode": "سويچ خطوط راهنما",
"toggleStats": "",
"addToLibrary": "افزودن به کتابخانه", "addToLibrary": "افزودن به کتابخانه",
"removeFromLibrary": "حذف از کتابخانه", "removeFromLibrary": "حذف از کتابخانه",
"libraryLoadingMessage": "بارگذاری کتابخانه...", "libraryLoadingMessage": "بارگذاری کتابخانه...",
@@ -117,10 +118,9 @@
"redo": "از سر", "redo": "از سر",
"roomDialog": "همکاری آنلاین را شروع کنید", "roomDialog": "همکاری آنلاین را شروع کنید",
"createNewRoom": "ایجاد یک اتاق جدید", "createNewRoom": "ایجاد یک اتاق جدید",
"fullScreen": "", "toggleFullScreen": "تغییر به حالت تمام صفحه",
"darkMode": "", "toggleDarkMode": "تغییر به حالت تاریک",
"lightMode": "", "toggleZenMode": "تغییر به حالت تمرکز",
"zenMode": "",
"exitZenMode": "خروج از حالت تمرکز" "exitZenMode": "خروج از حالت تمرکز"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "بارگزاری یک طرح خارجی محتوای فعلی رو از بین میبرد. آیا میخواهید ادامه دهید؟", "loadSceneOverridePrompt": "بارگزاری یک طرح خارجی محتوای فعلی رو از بین میبرد. آیا میخواهید ادامه دهید؟",
"errorLoadingLibrary": "خطایی در بارگذاری کتابخانه ثالث وجود داشت.", "errorLoadingLibrary": "خطایی در بارگذاری کتابخانه ثالث وجود داشت.",
"confirmAddLibrary": "{{numShapes}} از اشکال به کتابخانه شما اضافه خواهد شد. مطمئن هستید؟", "confirmAddLibrary": "{{numShapes}} از اشکال به کتابخانه شما اضافه خواهد شد. مطمئن هستید؟",
"imageDoesNotContainScene": "", "imageDoesNotContainScene": "فایل تصویر دارای محتوای صحنه نیست. آیا در هنگام خروجی گرفتن آن را فعال کرده‌اید؟",
"cannotRestoreFromImage": "صحنه را نمی توان از این فایل تصویری بازیابی کرد" "cannotRestoreFromImage": "صحنه را نمی توان از این فایل تصویری بازیابی کرد"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "کلیک کنید و بکشید و وقتی کار تمام شد رها کنید", "freeDraw": "کلیک کنید و بکشید و وقتی کار تمام شد رها کنید",
"text": "نکته: با برنامه انتخاب شده شما میتوانید با دوبار کلیک کردن هرکجا میخواید متن اظاف کنید", "text": "نکته: با برنامه انتخاب شده شما میتوانید با دوبار کلیک کردن هرکجا میخواید متن اظاف کنید",
"linearElementMulti": "روی آخرین نقطه کلیک کنید یا کلید ESC را بزنید یا کلید Enter را بزنید برای اتمام کار", "linearElementMulti": "روی آخرین نقطه کلیک کنید یا کلید ESC را بزنید یا کلید Enter را بزنید برای اتمام کار",
"lockAngle": "",
"resize": "می توانید با نگه داشتن SHIFT در هنگام تغییر اندازه، نسبت ها را محدود کنید،ALT را برای تغییر اندازه از مرکز نگه دارید", "resize": "می توانید با نگه داشتن SHIFT در هنگام تغییر اندازه، نسبت ها را محدود کنید،ALT را برای تغییر اندازه از مرکز نگه دارید",
"rotate": "با نگه داشتن SHIFT هنگام چرخش می توانید زاویه ها را محدود کنید", "rotate": "با نگه داشتن SHIFT هنگام چرخش می توانید زاویه ها را محدود کنید",
"lineEditor_info": "دوبار کلیک کنید یا Enter را فشار دهید تا نقاط را ویرایش کنید", "lineEditor_info": "دوبار کلیک کنید یا Enter را فشار دهید تا نقاط را ویرایش کنید",
+6 -7
View File
@@ -76,7 +76,8 @@
"group": "Ryhmitä valinta", "group": "Ryhmitä valinta",
"ungroup": "Pura valittu ryhmä", "ungroup": "Pura valittu ryhmä",
"collaborators": "Yhteistyökumppanit", "collaborators": "Yhteistyökumppanit",
"gridMode": "Ruudukkotila", "toggleGridMode": "Ruudukko päälle/pois",
"toggleStats": "Nörttien tilastot päälle/pois",
"addToLibrary": "Lisää kirjastoon", "addToLibrary": "Lisää kirjastoon",
"removeFromLibrary": "Poista kirjastosta", "removeFromLibrary": "Poista kirjastosta",
"libraryLoadingMessage": "Ladataan kirjastoa...", "libraryLoadingMessage": "Ladataan kirjastoa...",
@@ -117,10 +118,9 @@
"redo": "Tee uudelleen", "redo": "Tee uudelleen",
"roomDialog": "Aloita live-yhteistyö", "roomDialog": "Aloita live-yhteistyö",
"createNewRoom": "Luo huone", "createNewRoom": "Luo huone",
"fullScreen": "Koko näyttö", "toggleFullScreen": "Koko näytön tila päälle/pois",
"darkMode": "Tumma tila", "toggleDarkMode": "Pimeä tila päälle/pois",
"lightMode": "Vaalea tila", "toggleZenMode": "Zen-tila päälle",
"zenMode": "Zen-tila",
"exitZenMode": "Poistu zen-tilasta" "exitZenMode": "Poistu zen-tilasta"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Ulkopuolisen piirroksen lataaminen korvaa nykyisen sisältösi. Haluatko jatkaa?", "loadSceneOverridePrompt": "Ulkopuolisen piirroksen lataaminen korvaa nykyisen sisältösi. Haluatko jatkaa?",
"errorLoadingLibrary": "Kolmannen osapuolen kirjastoa ladattaessa tapahtui virhe.", "errorLoadingLibrary": "Kolmannen osapuolen kirjastoa ladattaessa tapahtui virhe.",
"confirmAddLibrary": "Tämä lisää {{numShapes}} muotoa kirjastoosi. Oletko varma?", "confirmAddLibrary": "Tämä lisää {{numShapes}} muotoa kirjastoosi. Oletko varma?",
"imageDoesNotContainScene": "Kuvien lisääminen ei ole tällä hetkellä mahdollista.\n\nHaluatko tuoda piirroksen? Tämä kuva ei näytä sisältävän tarvittavia tietoja. Oletko ottanut piirrostietojen tallennuksen käyttöön viennin aikana?", "imageDoesNotContainScene": "Kuvatiedosto ei sisällä teostietoja. Valitsitko sisällyttää ne tallennusvaiheessa?",
"cannotRestoreFromImage": "Teosta ei voitu palauttaa tästä kuvatiedostosta" "cannotRestoreFromImage": "Teosta ei voitu palauttaa tästä kuvatiedostosta"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Paina ja raahaa, päästä irti kun olet valmis", "freeDraw": "Paina ja raahaa, päästä irti kun olet valmis",
"text": "Vinkki: voit myös lisätä tekstiä kaksoisnapsauttamalla mihin tahansa valintatyökalulla", "text": "Vinkki: voit myös lisätä tekstiä kaksoisnapsauttamalla mihin tahansa valintatyökalulla",
"linearElementMulti": "Klikkaa viimeistä pistettä, paina Escape tai paina Enter lopettaaksesi", "linearElementMulti": "Klikkaa viimeistä pistettä, paina Escape tai paina Enter lopettaaksesi",
"lockAngle": "Voit rajoittaa kulmaa pitämällä SHIFT pohjassa",
"resize": "Voit rajoittaa mittasuhteet pitämällä SHIFT pohjassa kun muutat kokoa, pidä ALT pohjassa muuttaaksesi kokoa keskipisteen suhteen", "resize": "Voit rajoittaa mittasuhteet pitämällä SHIFT pohjassa kun muutat kokoa, pidä ALT pohjassa muuttaaksesi kokoa keskipisteen suhteen",
"rotate": "Voit rajoittaa kulman pitämällä SHIFT pohjassa pyörittäessäsi", "rotate": "Voit rajoittaa kulman pitämällä SHIFT pohjassa pyörittäessäsi",
"lineEditor_info": "Kaksoisnapauta tai paina Enter muokataksesi pisteitä", "lineEditor_info": "Kaksoisnapauta tai paina Enter muokataksesi pisteitä",
+12 -13
View File
@@ -76,21 +76,22 @@
"group": "Grouper la sélection", "group": "Grouper la sélection",
"ungroup": "Dégrouper la sélection", "ungroup": "Dégrouper la sélection",
"collaborators": "Collaborateurs", "collaborators": "Collaborateurs",
"gridMode": "Mode grille", "toggleGridMode": "Basculer le mode grille",
"toggleStats": "Activer/désactiver les stats pour les nerds",
"addToLibrary": "Ajouter à la bibliothèque", "addToLibrary": "Ajouter à la bibliothèque",
"removeFromLibrary": "Supprimer de la bibliothèque", "removeFromLibrary": "Supprimer de la bibliothèque",
"libraryLoadingMessage": "Chargement de la bibliothèque...", "libraryLoadingMessage": "Chargement de la bibliothèque...",
"libraries": "Explorer les bibliothèques", "libraries": "Explorer les bibliothèques",
"loadingScene": "Chargement de la scène...", "loadingScene": "Chargement de la scène...",
"align": "Alignement", "align": "Aligner",
"alignTop": "Aligner en haut", "alignTop": "Aligner en haut",
"alignBottom": "Aligner en bas", "alignBottom": "Aligner en bas",
"alignLeft": "Aligner à gauche", "alignLeft": "Aligner à gauche",
"alignRight": "Aligner à droite", "alignRight": "Aligner à droite",
"centerVertically": "Centrer verticalement", "centerVertically": "Centrer verticalement",
"centerHorizontally": "Centrer horizontalement", "centerHorizontally": "Centrer horizontalement",
"distributeHorizontally": "Distribuer horizontalement", "distributeHorizontally": "Répartir horizontalement",
"distributeVertically": "Distribuer verticalement" "distributeVertically": "Répartir verticalement"
}, },
"buttons": { "buttons": {
"clearReset": "Effacer le canvas & réinitialiser la couleur d'arrière-plan", "clearReset": "Effacer le canvas & réinitialiser la couleur d'arrière-plan",
@@ -117,10 +118,9 @@
"redo": "Rétablir", "redo": "Rétablir",
"roomDialog": "Démarrer le collaboration en temps réel", "roomDialog": "Démarrer le collaboration en temps réel",
"createNewRoom": "Créer un nouveau salon", "createNewRoom": "Créer un nouveau salon",
"fullScreen": "Plein écran", "toggleFullScreen": "Activer/désactiver le mode plein écran",
"darkMode": "Mode sombre", "toggleDarkMode": "Activer/désactiver le mode sombre",
"lightMode": "Mode Clair", "toggleZenMode": "Activer/désactiver le mode zen",
"zenMode": "Mode Zen",
"exitZenMode": "Quitter le mode zen" "exitZenMode": "Quitter le mode zen"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Le chargement d'un dessin externe remplacera votre contenu actuel. Souhaitez-vous continuer ?", "loadSceneOverridePrompt": "Le chargement d'un dessin externe remplacera votre contenu actuel. Souhaitez-vous continuer ?",
"errorLoadingLibrary": "Une erreur s'est produite lors du chargement de la bibliothèque tierce.", "errorLoadingLibrary": "Une erreur s'est produite lors du chargement de la bibliothèque tierce.",
"confirmAddLibrary": "Cela va ajouter {{numShapes}} forme(s) à votre bibliothèque. Êtes-vous sûr(e) ?", "confirmAddLibrary": "Cela va ajouter {{numShapes}} forme(s) à votre bibliothèque. Êtes-vous sûr(e) ?",
"imageDoesNotContainScene": "L'importation des images n'est pas prise en charge pour le moment.\n\nVoulez-vous importer une scène ? Cette image ne semble pas contenir de données de scène. Avez-vous activé cette option lors de l'exportation ?", "imageDoesNotContainScene": "Le fichier image ne contient pas de données de scène. L'avez-vous activé lors de l'export ?",
"cannotRestoreFromImage": "Impossible de restaurer la scène depuis ce fichier image" "cannotRestoreFromImage": "Impossible de restaurer la scène depuis ce fichier image"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Cliquez et faites glissez, relâchez quand vous avez terminé", "freeDraw": "Cliquez et faites glissez, relâchez quand vous avez terminé",
"text": "Astuce : vous pouvez également ajouter du texte en double-cliquant n'importe où avec l'outil de sélection", "text": "Astuce : vous pouvez également ajouter du texte en double-cliquant n'importe où avec l'outil de sélection",
"linearElementMulti": "Cliquez sur le dernier point ou appuyez sur Échap ou Entrée pour terminer", "linearElementMulti": "Cliquez sur le dernier point ou appuyez sur Échap ou Entrée pour terminer",
"lockAngle": "Vous pouvez contraindre l'angle en maintenant SHIFT",
"resize": "Vous pouvez conserver les proportions en maintenant la touche SHIFT pendant le redimensionnement,\nen maintenant la touche ALT pour redimensionner par rapport au centre", "resize": "Vous pouvez conserver les proportions en maintenant la touche SHIFT pendant le redimensionnement,\nen maintenant la touche ALT pour redimensionner par rapport au centre",
"rotate": "Vous pouvez contraindre les angles en maintenant MAJ enfoncé pendant la rotation", "rotate": "Vous pouvez contraindre les angles en maintenant MAJ enfoncé pendant la rotation",
"lineEditor_info": "Double-cliquez ou appuyez sur Entrée pour éditer les points", "lineEditor_info": "Double-cliquez ou appuyez sur Entrée pour éditer les points",
@@ -170,8 +169,8 @@
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "Impossible dafficher laperçu", "cannotShowPreview": "Impossible dafficher laperçu",
"canvasTooBig": "Le dessin est peut-être trop grand.", "canvasTooBig": "Le tableau peut être trop grand.",
"canvasTooBigTip": "Conseil : essayez de rapprocher un peu plus les éléments les plus éloignés." "canvasTooBigTip": "Astuce : essayez de rapprocher un peu les éléments les plus éloignés ensemble."
}, },
"errorSplash": { "errorSplash": {
"headingMain_pre": "Une erreur est survenue. Essayez ", "headingMain_pre": "Une erreur est survenue. Essayez ",
@@ -228,7 +227,7 @@
"scene": "Scène", "scene": "Scène",
"selected": "Sélectionné", "selected": "Sélectionné",
"storage": "Stockage", "storage": "Stockage",
"title": "Stats pour les nerds", "title": "Stats pour nerds",
"total": "Total", "total": "Total",
"width": "Largeur" "width": "Largeur"
} }
+62 -63
View File
@@ -2,9 +2,9 @@
"labels": { "labels": {
"paste": "הדבק", "paste": "הדבק",
"selectAll": "בחר הכל", "selectAll": "בחר הכל",
"multiSelect": "הוסף אובייקט לבחירה", "multiSelect": "",
"moveCanvas": "הזז את הקנבס", "moveCanvas": "",
"cut": "חתוך", "cut": "",
"copy": "העתק", "copy": "העתק",
"copyAsPng": "העתק ללוח כ PNG", "copyAsPng": "העתק ללוח כ PNG",
"copyAsSvg": "העתק ללוח כ SVG", "copyAsSvg": "העתק ללוח כ SVG",
@@ -26,20 +26,20 @@
"sloppiness": "סגנון", "sloppiness": "סגנון",
"opacity": "אטימות", "opacity": "אטימות",
"textAlign": "יישור טקסט", "textAlign": "יישור טקסט",
"edges": "קצוות", "edges": "",
"sharp": "חד", "sharp": "",
"round": "עגול", "round": "",
"arrowheads": "ראשי חצים", "arrowheads": "",
"arrowhead_none": "ללא", "arrowhead_none": "",
"arrowhead_arrow": "חץ", "arrowhead_arrow": "",
"arrowhead_bar": "שורה", "arrowhead_bar": "",
"arrowhead_dot": "נקודה", "arrowhead_dot": "",
"fontSize": "גודל גופן", "fontSize": "גודל גופן",
"fontFamily": "סוג הגופן", "fontFamily": "סוג הגופן",
"onlySelected": "רק מה שנבחר", "onlySelected": "רק מה שנבחר",
"withBackground": "עם רקע", "withBackground": "עם רקע",
"exportEmbedScene": "שלב את התצוגה בקובץ המיוצא", "exportEmbedScene": "",
"exportEmbedScene_details": "מידע התצוגה יישמר לקובץ המיוצא מסוג PNG/SVG כך שיהיה ניתן לשחזרה ממנו.\nהפעולה תגדיל את גודל הקובץ המיוצא.", "exportEmbedScene_details": "",
"addWatermark": "הוסף \"נוצר באמצעות Excalidraw\"", "addWatermark": "הוסף \"נוצר באמצעות Excalidraw\"",
"handDrawn": "כתב יד", "handDrawn": "כתב יד",
"normal": "רגיל", "normal": "רגיל",
@@ -60,7 +60,7 @@
"architect": "ארכיטקט", "architect": "ארכיטקט",
"artist": "אמן", "artist": "אמן",
"cartoonist": "קריקטוריסט", "cartoonist": "קריקטוריסט",
"fileTitle": "כותרת הקובץ", "fileTitle": "",
"colorPicker": "בחירת צבע", "colorPicker": "בחירת צבע",
"canvasBackground": "רקע הלוח", "canvasBackground": "רקע הלוח",
"drawingCanvas": "לוח ציור", "drawingCanvas": "לוח ציור",
@@ -69,28 +69,29 @@
"language": "שפה", "language": "שפה",
"createRoom": "התחל שיתוף פעולה חי", "createRoom": "התחל שיתוף פעולה חי",
"duplicateSelection": "שכפל", "duplicateSelection": "שכפל",
"untitled": "ללא כותרת", "untitled": "",
"name": "שם", "name": "שם",
"yourName": "שם", "yourName": "שם",
"madeWithExcalidraw": "נוצר באמצעות Excalidraw", "madeWithExcalidraw": "נוצר באמצעות Excalidraw",
"group": "אחד לקבוצה", "group": "אחד לקבוצה",
"ungroup": "פרק קבוצה", "ungroup": "פרק קבוצה",
"collaborators": "שותפים", "collaborators": "",
"gridMode": "", "toggleGridMode": "",
"addToLibrary": "הוסף לספריה", "toggleStats": "",
"removeFromLibrary": "הסר מספריה", "addToLibrary": "",
"libraryLoadingMessage": "טוען ספריה...", "removeFromLibrary": "",
"libraries": "דפדף בספריות", "libraryLoadingMessage": "",
"loadingScene": "טוען תצוגה...", "libraries": "",
"align": "יישר", "loadingScene": "",
"alignTop": "יישר למעלה", "align": "",
"alignBottom": "יישר למטה", "alignTop": "",
"alignLeft": "יישר לשמאל", "alignBottom": "",
"alignRight": "יישר לימין", "alignLeft": "",
"centerVertically": "מרכז אנכית", "alignRight": "",
"centerHorizontally": "מרכז אופקית", "centerVertically": "",
"distributeHorizontally": "חלוקה אופקית", "centerHorizontally": "",
"distributeVertically": "חלוקה אנכית" "distributeHorizontally": "",
"distributeVertically": ""
}, },
"buttons": { "buttons": {
"clearReset": "אפס את הלוח", "clearReset": "אפס את הלוח",
@@ -99,9 +100,9 @@
"exportToSvg": "יצא ל SVG", "exportToSvg": "יצא ל SVG",
"copyToClipboard": "העתק ללוח", "copyToClipboard": "העתק ללוח",
"copyPngToClipboard": "העתק PNG ללוח", "copyPngToClipboard": "העתק PNG ללוח",
"scale": "קנה מידה", "scale": "",
"save": "שמור", "save": "שמור",
"saveAs": "שמירה בשם", "saveAs": "",
"load": "טען", "load": "טען",
"getShareableLink": "קבל קישור לשיתוף", "getShareableLink": "קבל קישור לשיתוף",
"close": "סגור", "close": "סגור",
@@ -117,27 +118,26 @@
"redo": "בצע מחדש", "redo": "בצע מחדש",
"roomDialog": "התחל שיתוף חי", "roomDialog": "התחל שיתוף חי",
"createNewRoom": "צור חדר", "createNewRoom": "צור חדר",
"fullScreen": "", "toggleFullScreen": "הפעל/הפסק מסך מלא",
"darkMode": "", "toggleDarkMode": "",
"lightMode": "", "toggleZenMode": "התחל/הפסק מצב תפריט מרחף",
"zenMode": "",
"exitZenMode": "צא ממצב תפריט מרחף" "exitZenMode": "צא ממצב תפריט מרחף"
}, },
"alerts": { "alerts": {
"clearReset": "פעולה זו תנקה את כל הלוח. אתה בטוח?", "clearReset": "פעולה זו תנקה את כל הלוח. אתה בטוח?",
"couldNotCreateShareableLink": "לא ניתן לייצר לינק לשיתוף.", "couldNotCreateShareableLink": "לא ניתן לייצר לינק לשיתוף.",
"couldNotCreateShareableLinkTooBig": "לא הצלחנו לייצר קישור לשיתוף: התצוגה גדולה מדי", "couldNotCreateShareableLinkTooBig": "",
"couldNotLoadInvalidFile": "לא ניתן לטעון קובץ שאיננו תואם", "couldNotLoadInvalidFile": "לא ניתן לטעון קובץ שאיננו תואם",
"importBackendFailed": "ייבוא מהשרת נכשל.", "importBackendFailed": "ייבוא מהשרת נכשל.",
"cannotExportEmptyCanvas": "לא ניתן לייצא לוח ריק.", "cannotExportEmptyCanvas": "לא ניתן לייצא לוח ריק.",
"couldNotCopyToClipboard": "לא ניתן להעתיק ללוח. נסה להשתמש בדפדפן Chrome.", "couldNotCopyToClipboard": "לא ניתן להעתיק ללוח. נסה להשתמש בדפדפן Chrome.",
"decryptFailed": "לא ניתן לפענח מידע.", "decryptFailed": "לא ניתן לפענח מידע.",
"uploadedSecurly": "ההעלאה הוצפנה מקצה לקצה, ולכן שרת Excalidraw וצד שלישי לא יכולים לקרוא את התוכן.", "uploadedSecurly": "ההעלאה הוצפנה מקצה לקצה, ולכן שרת Excalidraw וצד שלישי לא יכולים לקרוא את התוכן.",
"loadSceneOverridePrompt": "טעינה של ציור חיצוני תחליף את התוכן הקיים שלך. האם תרצה להמשיך?", "loadSceneOverridePrompt": "",
"errorLoadingLibrary": "קרתה שגיאה בטעינת הספריה החיצונית.", "errorLoadingLibrary": "",
"confirmAddLibrary": "הפעולה תוסיף {{numShapes}} צורה(ות) לספריה שלך. האם אתה בטוח?", "confirmAddLibrary": "",
"imageDoesNotContainScene": "", "imageDoesNotContainScene": "",
"cannotRestoreFromImage": "לא הצלחנו לשחזר את התצוגה מקובץ התמונה" "cannotRestoreFromImage": ""
}, },
"toolBar": { "toolBar": {
"selection": "בחירה", "selection": "בחירה",
@@ -148,7 +148,7 @@
"arrow": "חץ", "arrow": "חץ",
"line": "קו", "line": "קו",
"text": "טקסט", "text": "טקסט",
"library": "ספריה", "library": "",
"lock": "השאר את הכלי הנבחר פעיל גם לאחר סיום הציור" "lock": "השאר את הכלי הנבחר פעיל גם לאחר סיום הציור"
}, },
"headings": { "headings": {
@@ -159,19 +159,18 @@
"hints": { "hints": {
"linearElement": "הקלק בשביל לבחור נקודות מרובות, גרור בשביל קו בודד", "linearElement": "הקלק בשביל לבחור נקודות מרובות, גרור בשביל קו בודד",
"freeDraw": "לחץ וגרור, שחרר כשסיימת", "freeDraw": "לחץ וגרור, שחרר כשסיימת",
"text": "טיפ: אפשר להוסיף טקסט על ידי לחיצה כפולה בכל מקום עם כלי הבחירה", "text": "",
"linearElementMulti": "הקלק על הנקודה האחרונה או הקש Escape או Enter לסיום", "linearElementMulti": "הקלק על הנקודה האחרונה או הקש Escape או Enter לסיום",
"lockAngle": "",
"resize": "ניתן להגביל פרופורציות על ידי לחיצה על SHIFT תוך כדי שינוי גודל,\nהחזק ALT בשביל לשנות גודל ביחס למרכז", "resize": "ניתן להגביל פרופורציות על ידי לחיצה על SHIFT תוך כדי שינוי גודל,\nהחזק ALT בשביל לשנות גודל ביחס למרכז",
"rotate": "ניתן להגביל זוויות על ידי לחיצה על SHIFT תוך כדי סיבוב", "rotate": "ניתן להגביל זוויות על ידי לחיצה על SHIFT תוך כדי סיבוב",
"lineEditor_info": "לחץ לחיצה כפולה או אנטר לעריכת הנקודות", "lineEditor_info": "",
"lineEditor_pointSelected": "לחץ על Delete להסרת נקודה, CtrlOrCmd+D לשכפל, או גרור להזזה", "lineEditor_pointSelected": "",
"lineEditor_nothingSelected": "בחר נקודה להזזה או הסרה, או החזק את כפתור Alt והקלק להוספת נקודות חדשות" "lineEditor_nothingSelected": ""
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "לא הצלחנו להציג את התצוגה המקדימה", "cannotShowPreview": "",
"canvasTooBig": "הקנבס עלול להיות גדול מדי.", "canvasTooBig": "",
"canvasTooBigTip": "טיפ: נסה להזיז את האלמנטים הרחוקים ביותר מעט קרוב יותר יחד." "canvasTooBigTip": ""
}, },
"errorSplash": { "errorSplash": {
"headingMain_pre": "אירעה שגיאה. נסה ", "headingMain_pre": "אירעה שגיאה. נסה ",
@@ -214,22 +213,22 @@
"textNewLine": "הוסף שורה חדשה (טקסט)", "textNewLine": "הוסף שורה חדשה (טקסט)",
"textFinish": "סיים עריכה (טקסט)", "textFinish": "סיים עריכה (טקסט)",
"zoomToFit": "זום להתאמת כל האלמנטים למסך", "zoomToFit": "זום להתאמת כל האלמנטים למסך",
"zoomToSelection": "התמקד בבחירה", "zoomToSelection": "",
"preventBinding": "מנע השתלבות חצים" "preventBinding": ""
}, },
"encrypted": { "encrypted": {
"tooltip": "הרישומים שלך מוצפנים מקצה לקצה כך שהשרתים של Excalidraw לא יראו אותם לעולם." "tooltip": "הרישומים שלך מוצפנים מקצה לקצה כך שהשרתים של Excalidraw לא יראו אותם לעולם."
}, },
"stats": { "stats": {
"angle": "זווית", "angle": "",
"element": "אלמנט", "element": "",
"elements": "אלמנטים", "elements": "",
"height": "גובה", "height": "",
"scene": "תצוגה", "scene": "",
"selected": "נבחר/ים", "selected": "",
"storage": "אחסון", "storage": "",
"title": "סטטיסטיקות לחנונים", "title": "",
"total": "סה״כ", "total": "",
"width": "רוחב" "width": ""
} }
} }
+9 -10
View File
@@ -29,11 +29,11 @@
"edges": "किनारा", "edges": "किनारा",
"sharp": "नुकीला", "sharp": "नुकीला",
"round": "गोल", "round": "गोल",
"arrowheads": "तीर शीर्ष", "arrowheads": "",
"arrowhead_none": "कोई भी नहीं", "arrowhead_none": "",
"arrowhead_arrow": "तीर", "arrowhead_arrow": "तीर",
"arrowhead_bar": "बार", "arrowhead_bar": "",
"arrowhead_dot": "बिंदु", "arrowhead_dot": "",
"fontSize": "फ़ॉन्ट का आकार", "fontSize": "फ़ॉन्ट का आकार",
"fontFamily": "फ़ॉन्ट का परिवार", "fontFamily": "फ़ॉन्ट का परिवार",
"onlySelected": "केवल चयनित", "onlySelected": "केवल चयनित",
@@ -76,7 +76,8 @@
"group": "समूह चयन", "group": "समूह चयन",
"ungroup": "समूह चयन असमूहीकृत करें", "ungroup": "समूह चयन असमूहीकृत करें",
"collaborators": "सहयोगी", "collaborators": "सहयोगी",
"gridMode": "", "toggleGridMode": "टॉगल ग्रिड मोड",
"toggleStats": "",
"addToLibrary": "लाइब्रेरी से जोड़ें", "addToLibrary": "लाइब्रेरी से जोड़ें",
"removeFromLibrary": "लाइब्रेरी से निकालें", "removeFromLibrary": "लाइब्रेरी से निकालें",
"libraryLoadingMessage": "लाइब्रेरी खुल रही है", "libraryLoadingMessage": "लाइब्रेरी खुल रही है",
@@ -117,10 +118,9 @@
"redo": "फिर से करें", "redo": "फिर से करें",
"roomDialog": "लाइव सहयोग शुरू करें", "roomDialog": "लाइव सहयोग शुरू करें",
"createNewRoom": "एक नया कमरा बनाएं", "createNewRoom": "एक नया कमरा बनाएं",
"fullScreen": "", "toggleFullScreen": "पूर्णस्क्रीन चालू करें",
"darkMode": "", "toggleDarkMode": "",
"lightMode": "", "toggleZenMode": "टॉगल ज़ेन मोड",
"zenMode": "",
"exitZenMode": "जेन मोड से बाहर निकलें" "exitZenMode": "जेन मोड से बाहर निकलें"
}, },
"alerts": { "alerts": {
@@ -161,7 +161,6 @@
"freeDraw": "क्लिक करें और खींचें। समाप्त करने के लिए, छोड़ो", "freeDraw": "क्लिक करें और खींचें। समाप्त करने के लिए, छोड़ो",
"text": "", "text": "",
"linearElementMulti": "अंतिम बिंदु पर क्लिक करें या समाप्त होने के लिए एस्केप या एंटर दबाएं", "linearElementMulti": "अंतिम बिंदु पर क्लिक करें या समाप्त होने के लिए एस्केप या एंटर दबाएं",
"lockAngle": "",
"resize": "आकार बदलते समय आप SHIFT को पकड़ कर अनुपात में कमी कर सकते हैं,\nकेंद्र से आकार बदलने के लिए ALT दबाए रखें", "resize": "आकार बदलते समय आप SHIFT को पकड़ कर अनुपात में कमी कर सकते हैं,\nकेंद्र से आकार बदलने के लिए ALT दबाए रखें",
"rotate": "आप घूर्णन करते समय SHIFT पकड़कर कोणों को विवश कर सकते हैं", "rotate": "आप घूर्णन करते समय SHIFT पकड़कर कोणों को विवश कर सकते हैं",
"lineEditor_info": "बिंदुओं को संपादित करने के लिए Enter पर डबल-क्लिक करें या दबाएँ", "lineEditor_info": "बिंदुओं को संपादित करने के लिए Enter पर डबल-क्लिक करें या दबाएँ",
+106 -107
View File
@@ -2,95 +2,96 @@
"labels": { "labels": {
"paste": "Beillesztés", "paste": "Beillesztés",
"selectAll": "Összes kijelölése", "selectAll": "Összes kijelölése",
"multiSelect": "Elem hozzáadása a kiválasztáshoz", "multiSelect": "",
"moveCanvas": "Vászon mozgatása", "moveCanvas": "",
"cut": "Kivágás", "cut": "",
"copy": "Másolás", "copy": "Másolás",
"copyAsPng": "Vágólapra másolás mint PNG", "copyAsPng": "Vágólapra másolás mint PNG",
"copyAsSvg": "Vágólapra másolás mint SVG", "copyAsSvg": "Vágólapra másolás mint SVG",
"bringForward": "Előrébb hozás", "bringForward": "Előrébb hozás",
"sendToBack": "Hátraküldés", "sendToBack": "",
"bringToFront": "Előrehozás", "bringToFront": "",
"sendBackward": "Hátrébb küldés", "sendBackward": "",
"delete": "Törlés", "delete": "Törlés",
"copyStyles": "Stílus másolása", "copyStyles": "",
"pasteStyles": "Stílus beillesztése", "pasteStyles": "",
"stroke": "Körvonal", "stroke": "Körvonal",
"background": "Háttér", "background": "Háttér",
"fill": "Kitöltés", "fill": "Kitöltés",
"strokeWidth": "Körvonal vastagsága", "strokeWidth": "",
"strokeStyle": "Körvonal stílusa", "strokeStyle": "",
"strokeStyle_solid": "Kitöltött", "strokeStyle_solid": "",
"strokeStyle_dashed": "Szaggatott", "strokeStyle_dashed": "",
"strokeStyle_dotted": "Pontozott", "strokeStyle_dotted": "",
"sloppiness": "Stílus", "sloppiness": "Stílus",
"opacity": "Áttetszőség", "opacity": "Áttetszőség",
"textAlign": "Szöveg igazítása", "textAlign": "",
"edges": "Szélek", "edges": "",
"sharp": "Éles", "sharp": "",
"round": "Kerek", "round": "",
"arrowheads": "Nyílhegyek", "arrowheads": "",
"arrowhead_none": "Nincs", "arrowhead_none": "",
"arrowhead_arrow": "Nyíl", "arrowhead_arrow": "",
"arrowhead_bar": "Oszlop", "arrowhead_bar": "",
"arrowhead_dot": "Pont", "arrowhead_dot": "",
"fontSize": "Betűméret", "fontSize": "",
"fontFamily": "Betűkészlet család", "fontFamily": "",
"onlySelected": "Csak a kiválasztott", "onlySelected": "Csak a kiválasztott",
"withBackground": "", "withBackground": "Háttérrel együtt",
"exportEmbedScene": "Jelenet beágyazása az exportált fájlba", "exportEmbedScene": "",
"exportEmbedScene_details": "", "exportEmbedScene_details": "",
"addWatermark": "Add hozzá, hogy \"Excalidraw-val készült\"", "addWatermark": "",
"handDrawn": "Kézzel rajzolt", "handDrawn": "",
"normal": "Normál", "normal": "Normál",
"code": "Code", "code": "Code",
"small": "Kicsi", "small": "Kicsi",
"medium": "Közepes", "medium": "Közepes",
"large": "Nagy", "large": "Nagy",
"veryLarge": "Nagyon nagy", "veryLarge": "",
"solid": "Kitöltött", "solid": "Kitöltött",
"hachure": "Vonalkázott", "hachure": "Vonalkázott",
"crossHatch": "Keresztcsíkozott", "crossHatch": "",
"thin": "Vékony", "thin": "Vékony",
"bold": "Félkövér", "bold": "Félkövér",
"left": "Bal", "left": "Bal",
"center": "Közép", "center": "",
"right": "Jobb", "right": "",
"extraBold": "Extra Félkövér", "extraBold": "",
"architect": "Tervezői", "architect": "Tervezői",
"artist": "Művészi", "artist": "Művészi",
"cartoonist": "Karikatúrás", "cartoonist": "Karikatúrás",
"fileTitle": "Fájl címe", "fileTitle": "",
"colorPicker": "Színválasztó", "colorPicker": "Színválasztó",
"canvasBackground": "Vászon háttérszíne", "canvasBackground": "Vászon háttérszíne",
"drawingCanvas": "Rajzvászon", "drawingCanvas": "",
"layers": "Rétegek", "layers": "Rétegek",
"actions": "Műveletek", "actions": "Műveletek",
"language": "Nyelv", "language": "Nyelv",
"createRoom": "Élő együttmüködés megosztása", "createRoom": "Élő együttmüködés megosztása",
"duplicateSelection": "Duplikálás", "duplicateSelection": "",
"untitled": "Névtelen", "untitled": "",
"name": "Név", "name": "Név",
"yourName": "Neved", "yourName": "",
"madeWithExcalidraw": "Excalidraw-val készült", "madeWithExcalidraw": "",
"group": "Csoportosítás", "group": "",
"ungroup": "Csoportbontás", "ungroup": "",
"collaborators": "Közreműködők", "collaborators": "",
"gridMode": "", "toggleGridMode": "",
"addToLibrary": "Hozzáadás a könyvtárhoz", "toggleStats": "",
"removeFromLibrary": "Eltávólítás a könyvtárból", "addToLibrary": "",
"libraryLoadingMessage": "Könyvtár betöltése...", "removeFromLibrary": "",
"libraries": "Könyvtárak böngészése", "libraryLoadingMessage": "",
"loadingScene": "Jelenet betöltése...", "libraries": "",
"align": "Igazítás", "loadingScene": "",
"alignTop": "Felülre igazítás", "align": "",
"alignBottom": "Alulra igazítás", "alignTop": "",
"alignLeft": "Balra igazítás", "alignBottom": "",
"alignRight": "Jobbra igazítás", "alignLeft": "",
"centerVertically": "Függőlegesen középre igazított", "alignRight": "",
"centerHorizontally": "Vízszintesen középre igazított", "centerVertically": "",
"distributeHorizontally": "Vízszintes elosztás", "centerHorizontally": "",
"distributeVertically": "Függőleges elosztás" "distributeHorizontally": "",
"distributeVertically": ""
}, },
"buttons": { "buttons": {
"clearReset": "Vászon törlése", "clearReset": "Vászon törlése",
@@ -99,13 +100,13 @@
"exportToSvg": "Exportálás SVG-be", "exportToSvg": "Exportálás SVG-be",
"copyToClipboard": "Vágólapra másolás", "copyToClipboard": "Vágólapra másolás",
"copyPngToClipboard": "PNG másolása a vágólapra", "copyPngToClipboard": "PNG másolása a vágólapra",
"scale": "Nagyítás", "scale": "",
"save": "Mentés", "save": "Mentés",
"saveAs": "Mentés másként", "saveAs": "",
"load": "Betöltés", "load": "Betöltés",
"getShareableLink": "Megosztható link létrehozása", "getShareableLink": "Megosztható link létrehozása",
"close": "Bezárás", "close": "Bezárás",
"selectLanguage": "Nyelv kiválasztása", "selectLanguage": "",
"scrollBackToContent": "Visszagörgetés a tartalomhoz", "scrollBackToContent": "Visszagörgetés a tartalomhoz",
"zoomIn": "Nagyítás", "zoomIn": "Nagyítás",
"zoomOut": "Kicsinyítés", "zoomOut": "Kicsinyítés",
@@ -117,38 +118,37 @@
"redo": "Újra végrehajtás", "redo": "Újra végrehajtás",
"roomDialog": "Élő együttműködés indítása", "roomDialog": "Élő együttműködés indítása",
"createNewRoom": "Új szoba létrehozása", "createNewRoom": "Új szoba létrehozása",
"fullScreen": "", "toggleFullScreen": "",
"darkMode": "", "toggleDarkMode": "",
"lightMode": "", "toggleZenMode": "",
"zenMode": "", "exitZenMode": ""
"exitZenMode": "Zen mód elhagyása"
}, },
"alerts": { "alerts": {
"clearReset": "Ez a művelet törli a vászont. Biztos benne?", "clearReset": "Ez a művelet törli a vászont. Biztos benne?",
"couldNotCreateShareableLink": "Nem sikerült megosztható linket létrehozni.", "couldNotCreateShareableLink": "Nem sikerült megosztható linket létrehozni.",
"couldNotCreateShareableLinkTooBig": "Nem sikerült megosztható linket látrehozni: túl nagy a jelenet", "couldNotCreateShareableLinkTooBig": "",
"couldNotLoadInvalidFile": "Nem sikerült betölteni a helytelen fájlt", "couldNotLoadInvalidFile": "",
"importBackendFailed": "Nem sikerült betölteni a szerverről.", "importBackendFailed": "Nem sikerült betölteni a szerverről.",
"cannotExportEmptyCanvas": "Üres vászont nem lehet exportálni.", "cannotExportEmptyCanvas": "Üres vászont nem lehet exportálni.",
"couldNotCopyToClipboard": "Nem sikerült vágólapra menteni. Próbálja meg Chrome böngészővel.", "couldNotCopyToClipboard": "Nem sikerült vágólapra menteni. Próbálja meg Chrome böngészővel.",
"decryptFailed": "Nem sikerült visszafejteni a titkosított adatot.", "decryptFailed": "Nem sikerült dekódolni az adatot.",
"uploadedSecurly": "A feltöltést végpontok közötti titkosítással biztosítottuk, ami azt jelenti, hogy az Excalidraw szerver és harmadik felek nem tudják elolvasni a feltöltés tartalmát.", "uploadedSecurly": "A feltöltést végpontok közötti titkosítással biztosítottuk, ami azt jelenti, hogy az Excalidraw szerver és harmadik felek nem tudják elolvasni a feltöltés tartalmát.",
"loadSceneOverridePrompt": "A betöltött külső rajz felül fogja írnia meglévőt. Szeretnéd folytatni?", "loadSceneOverridePrompt": "",
"errorLoadingLibrary": "Hibába ütközött a harmarmadik féltől származó könyvtár betöltése.", "errorLoadingLibrary": "",
"confirmAddLibrary": "Ez a művelet {{numShapes}} formát fog hozzáadni a könyvtáradhoz. Biztos vagy benne?", "confirmAddLibrary": "",
"imageDoesNotContainScene": "", "imageDoesNotContainScene": "",
"cannotRestoreFromImage": "" "cannotRestoreFromImage": ""
}, },
"toolBar": { "toolBar": {
"selection": "Kiválasztás", "selection": "Kiválasztás",
"draw": "Szabadkézi rajz", "draw": "",
"rectangle": "Téglalap", "rectangle": "Téglalap",
"diamond": "Rombusz", "diamond": "Rombusz",
"ellipse": "Ellipszis", "ellipse": "Ellipszis",
"arrow": "Nyíl", "arrow": "Nyíl",
"line": "Vonal", "line": "Vonal",
"text": "Szöveg", "text": "Szöveg",
"library": "Könyvtár", "library": "",
"lock": "Rajzolás után az aktív eszközt tartsa kiválasztva" "lock": "Rajzolás után az aktív eszközt tartsa kiválasztva"
}, },
"headings": { "headings": {
@@ -158,20 +158,19 @@
}, },
"hints": { "hints": {
"linearElement": "Kattintson a több pont elindításához, húzza az egyenes vonalhoz", "linearElement": "Kattintson a több pont elindításához, húzza az egyenes vonalhoz",
"freeDraw": "Kattints és húzd, majd engedd el, amikor végeztél", "freeDraw": "",
"text": "Tipp: A kiválasztó eszközzel bárhol létrehozhatsz szöveget dupla kattintással", "text": "",
"linearElementMulti": "Kattintson az utolsó pontra, vagy nyomja meg az Escape vagy az Enter billentyűt a befejezéshez", "linearElementMulti": "Kattintson az utolsó pontra, vagy nyomja meg az Escape vagy az Enter billentyűt a befejezéshez",
"lockAngle": "",
"resize": "", "resize": "",
"rotate": "A SHIFT billentyű lenyomva tartásával korlátozhatja a szögek illesztését", "rotate": "A SHIFT billentyű lenyomva tartásával korlátozhatja a szögek illesztését",
"lineEditor_info": "Kattints duplán, vagy nyomj entert a pontok szerkesztéséhez", "lineEditor_info": "",
"lineEditor_pointSelected": "Nyomd meg a delete gombot a pont eltávolításához, Ctrl vagy Cmd + D-t a duplikáláshoz, vagy húzva mozgasd", "lineEditor_pointSelected": "",
"lineEditor_nothingSelected": "Válassz ki egy pontot a mozgatáshoz vagy törtléshez, vagy az Alt lenyomása mellett kattintva hozz létre új pontokat" "lineEditor_nothingSelected": ""
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "Előnézet nem jeleníthető meg", "cannotShowPreview": "",
"canvasTooBig": "A vászon talán túl nagy.", "canvasTooBig": "",
"canvasTooBigTip": "Tipp: próbáld meg a legtávolabbi elemeket közelebb mozgazni egy máshoz." "canvasTooBigTip": ""
}, },
"errorSplash": { "errorSplash": {
"headingMain_pre": "Hiba történt. Próbálja ", "headingMain_pre": "Hiba történt. Próbálja ",
@@ -193,43 +192,43 @@
"button_stopSession": "Munkamenet leállítása", "button_stopSession": "Munkamenet leállítása",
"desc_inProgressIntro": "Az élő együttműködési munkamenet folyamatban van.", "desc_inProgressIntro": "Az élő együttműködési munkamenet folyamatban van.",
"desc_shareLink": "Ossza meg ezt a linket bárkivel, akivel együtt szeretne működni:", "desc_shareLink": "Ossza meg ezt a linket bárkivel, akivel együtt szeretne működni:",
"desc_exitSession": "Az munkamenet leállítása kilépteti önt a szobából, de folytathatja a munkát a saját gépén. Vegye figyelembe, hogy ez nem érinti más emberek munkáját és ők továbbra is együttműködhetnek a saját változatukon." "desc_exitSession": ""
}, },
"errorDialog": { "errorDialog": {
"title": "Hiba" "title": ""
}, },
"shortcutsDialog": { "shortcutsDialog": {
"title": "Gyorsbillentyűk", "title": "",
"shapes": "Formák", "shapes": "",
"or": "vagy", "or": "",
"click": "klikk", "click": "",
"drag": "húzd", "drag": "",
"curvedArrow": "Ívelt nyíl", "curvedArrow": "",
"curvedLine": "Ívelt vonal", "curvedLine": "",
"editor": "Szerkesztő", "editor": "",
"view": "Nézet", "view": "",
"blog": "Olvasd a blogunkat", "blog": "",
"howto": "Kövesd az útmutatóinkat", "howto": "",
"github": "Hibát találtál? Küld be", "github": "",
"textNewLine": "Új sor hozzáadása (szöveg)", "textNewLine": "",
"textFinish": "Szerkesztés befejezése (szöveg)", "textFinish": "",
"zoomToFit": "", "zoomToFit": "",
"zoomToSelection": "Kijelölésre nagyítás", "zoomToSelection": "",
"preventBinding": "" "preventBinding": ""
}, },
"encrypted": { "encrypted": {
"tooltip": "" "tooltip": ""
}, },
"stats": { "stats": {
"angle": "Szög", "angle": "",
"element": "Elem", "element": "",
"elements": "Elemek", "elements": "",
"height": "Magasság", "height": "",
"scene": "", "scene": "",
"selected": "Kiválasztott", "selected": "",
"storage": "Tárhely", "storage": "",
"title": "", "title": "",
"total": "Összesen", "total": "",
"width": "Szélesség" "width": ""
} }
} }
+8 -9
View File
@@ -37,7 +37,7 @@
"fontSize": "Ukuran font", "fontSize": "Ukuran font",
"fontFamily": "Jenis font", "fontFamily": "Jenis font",
"onlySelected": "Hanya yang Dipilih", "onlySelected": "Hanya yang Dipilih",
"withBackground": "Dengan latar", "withBackground": "Dengan Latar",
"exportEmbedScene": "Sematkan pemandangan ke dalam file yang diekspor", "exportEmbedScene": "Sematkan pemandangan ke dalam file yang diekspor",
"exportEmbedScene_details": "Data pemandangan akan disimpan dalam file PNG/SVG yang diekspor, sehingga pemandangan itu dapat dipulihkan darinya.\nAkan membesarkan ukuran file yang diekspor.", "exportEmbedScene_details": "Data pemandangan akan disimpan dalam file PNG/SVG yang diekspor, sehingga pemandangan itu dapat dipulihkan darinya.\nAkan membesarkan ukuran file yang diekspor.",
"addWatermark": "Tambahkan \"Dibuat dengan Excalidraw\"", "addWatermark": "Tambahkan \"Dibuat dengan Excalidraw\"",
@@ -76,7 +76,8 @@
"group": "Kelompokan pilihan", "group": "Kelompokan pilihan",
"ungroup": "Pisahkan pilihan", "ungroup": "Pisahkan pilihan",
"collaborators": "Kolaborator", "collaborators": "Kolaborator",
"gridMode": "Mode grid", "toggleGridMode": "Aktifkan/Matikan mode kisi",
"toggleStats": "Aktifkan statistik untuk nerd",
"addToLibrary": "Tambahkan ke pustaka", "addToLibrary": "Tambahkan ke pustaka",
"removeFromLibrary": "Hapus dari pustaka", "removeFromLibrary": "Hapus dari pustaka",
"libraryLoadingMessage": "Memuat pustaka...", "libraryLoadingMessage": "Memuat pustaka...",
@@ -117,10 +118,9 @@
"redo": "Ulangi", "redo": "Ulangi",
"roomDialog": "Mulai kolaborasi langsung", "roomDialog": "Mulai kolaborasi langsung",
"createNewRoom": "Buat ruang baru", "createNewRoom": "Buat ruang baru",
"fullScreen": "Layar penuh", "toggleFullScreen": "Beralih ke layar penuh",
"darkMode": "Mode gelap", "toggleDarkMode": "Aktifkan/Matikan mode gelap",
"lightMode": "Mode terang", "toggleZenMode": "Aktifkan/Matikan mode zen",
"zenMode": "Mode zen",
"exitZenMode": "Keluar dari mode zen" "exitZenMode": "Keluar dari mode zen"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Memuat gambar external akan mengganti konten Anda yang ada. Apakah Anda ingin melanjutkan?", "loadSceneOverridePrompt": "Memuat gambar external akan mengganti konten Anda yang ada. Apakah Anda ingin melanjutkan?",
"errorLoadingLibrary": "Terdapat kesalahan dalam memuat pustaka pihak ketiga.", "errorLoadingLibrary": "Terdapat kesalahan dalam memuat pustaka pihak ketiga.",
"confirmAddLibrary": "Ini akan menambahkan {{numShapes}} bentuk ke pustaka Anda. Anda yakin?", "confirmAddLibrary": "Ini akan menambahkan {{numShapes}} bentuk ke pustaka Anda. Anda yakin?",
"imageDoesNotContainScene": "Mengimpor gambar tidak didukung saat ini.\n\nApakah Anda ingin impor pemandangan? Gambar ini tidak berisi data pemandangan. Sudah ka Anda aktifkan ini ketika ekspor?", "imageDoesNotContainScene": "File gambar tidak berisi data pemandangan. Apa Anda sudah aktifkan ini selama ekspor?",
"cannotRestoreFromImage": "Pemandangan tidak dapat dipulihkan dari file gambar ini" "cannotRestoreFromImage": "Pemandangan tidak dapat dipulihkan dari file gambar ini"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Klik dan seret, lepaskan jika Anda selesai", "freeDraw": "Klik dan seret, lepaskan jika Anda selesai",
"text": "Tip: Anda juga dapat menambahkan teks dengan klik ganda di mana saja dengan alat pemilihan", "text": "Tip: Anda juga dapat menambahkan teks dengan klik ganda di mana saja dengan alat pemilihan",
"linearElementMulti": "Klik pada titik akhir atau tekan Escape atau Enter untuk menyelesaikan", "linearElementMulti": "Klik pada titik akhir atau tekan Escape atau Enter untuk menyelesaikan",
"lockAngle": "Anda dapat menjaga sudut dengan menahan SHIFT",
"resize": "Anda dapat menjaga proposi dengan menekan SHIFT sambil mengubah ukuran,\ntekan AlT untuk mengubah ukuran dari tengah", "resize": "Anda dapat menjaga proposi dengan menekan SHIFT sambil mengubah ukuran,\ntekan AlT untuk mengubah ukuran dari tengah",
"rotate": "Anda dapat menjaga sudut dengan menahan SHIFT sambil memutar", "rotate": "Anda dapat menjaga sudut dengan menahan SHIFT sambil memutar",
"lineEditor_info": "Klik ganda atau tekan Enter untuk mengedit titik", "lineEditor_info": "Klik ganda atau tekan Enter untuk mengedit titik",
@@ -214,7 +213,7 @@
"textNewLine": "Tambahkan baris baru (teks)", "textNewLine": "Tambahkan baris baru (teks)",
"textFinish": "Selesai mengedit (teks)", "textFinish": "Selesai mengedit (teks)",
"zoomToFit": "Perbesar agar sesuai dengan semua elemen", "zoomToFit": "Perbesar agar sesuai dengan semua elemen",
"zoomToSelection": "Perbesar ke seleksi", "zoomToSelection": "",
"preventBinding": "Cegah pengikatan panah" "preventBinding": "Cegah pengikatan panah"
}, },
"encrypted": { "encrypted": {
+7 -8
View File
@@ -37,7 +37,7 @@
"fontSize": "Dimensione carattere", "fontSize": "Dimensione carattere",
"fontFamily": "Carattere", "fontFamily": "Carattere",
"onlySelected": "Solo selezionati", "onlySelected": "Solo selezionati",
"withBackground": "Con sfondo", "withBackground": "Con Sfondo",
"exportEmbedScene": "Incorpora la scena nel file esportato", "exportEmbedScene": "Incorpora la scena nel file esportato",
"exportEmbedScene_details": "I dati della scena saranno salvati nel file PNG/SVG esportato in modo che la scena possa essere ripristinata da esso.\nQuesto aumenterà la dimensione del file esportato.", "exportEmbedScene_details": "I dati della scena saranno salvati nel file PNG/SVG esportato in modo che la scena possa essere ripristinata da esso.\nQuesto aumenterà la dimensione del file esportato.",
"addWatermark": "Aggiungi \"Creato con Excalidraw\"", "addWatermark": "Aggiungi \"Creato con Excalidraw\"",
@@ -76,7 +76,8 @@
"group": "Crea gruppo da selezione", "group": "Crea gruppo da selezione",
"ungroup": "Dividi gruppo da selezione", "ungroup": "Dividi gruppo da selezione",
"collaborators": "Collaboratori", "collaborators": "Collaboratori",
"gridMode": "Modalità griglia", "toggleGridMode": "Attiva/disattiva modalità griglia",
"toggleStats": "Attiva/disattiva statistiche per nerd",
"addToLibrary": "Aggiungi alla biblioteca", "addToLibrary": "Aggiungi alla biblioteca",
"removeFromLibrary": "Rimuovi dalla biblioteca", "removeFromLibrary": "Rimuovi dalla biblioteca",
"libraryLoadingMessage": "Caricamento della biblioteca...", "libraryLoadingMessage": "Caricamento della biblioteca...",
@@ -117,10 +118,9 @@
"redo": "Ripeti", "redo": "Ripeti",
"roomDialog": "Inizia collaborazione in diretta", "roomDialog": "Inizia collaborazione in diretta",
"createNewRoom": "Crea nuova stanza", "createNewRoom": "Crea nuova stanza",
"fullScreen": "Schermo intero", "toggleFullScreen": "Attiva/Disattiva schermo intero",
"darkMode": "Tema scuro", "toggleDarkMode": "Attiva tema scuro",
"lightMode": "Tema chiaro", "toggleZenMode": "Attiva/Disattiva modalità zen",
"zenMode": "Modalità Zen",
"exitZenMode": "Uscire dalla modalità zen" "exitZenMode": "Uscire dalla modalità zen"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Se carichi questo disegno esterno, sostituirà quello che hai. Vuoi continuare?", "loadSceneOverridePrompt": "Se carichi questo disegno esterno, sostituirà quello che hai. Vuoi continuare?",
"errorLoadingLibrary": "Si è verificato un errore nel caricamento della libreria di terze parti.", "errorLoadingLibrary": "Si è verificato un errore nel caricamento della libreria di terze parti.",
"confirmAddLibrary": "Questo aggiungerà {{numShapes}} forma(e) alla tua biblioteca. Sei sicuro?", "confirmAddLibrary": "Questo aggiungerà {{numShapes}} forma(e) alla tua biblioteca. Sei sicuro?",
"imageDoesNotContainScene": "L'importazione di immagini al momento non è supportata.\n\nVuoi importare una scena? Questa immagine non sembra contenere alcun dato di scena. Hai abilitato questa opzione durante l'esportazione?", "imageDoesNotContainScene": "Il file immagine non contiene dati di scena. È stato abilitato durante l'esportazione?",
"cannotRestoreFromImage": "Impossibile ripristinare la scena da questo file immagine" "cannotRestoreFromImage": "Impossibile ripristinare la scena da questo file immagine"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Clicca e trascina, rilascia quando avrai finito", "freeDraw": "Clicca e trascina, rilascia quando avrai finito",
"text": "Suggerimento: puoi anche aggiungere del testo facendo doppio clic ovunque con lo strumento di selezione", "text": "Suggerimento: puoi anche aggiungere del testo facendo doppio clic ovunque con lo strumento di selezione",
"linearElementMulti": "Clicca sull'ultimo punto o premi Esc o Invio per finire", "linearElementMulti": "Clicca sull'ultimo punto o premi Esc o Invio per finire",
"lockAngle": "Puoi limitare l'angolo tenendo premuto SHIFT",
"resize": "Per vincolare le proporzioni, tenir premuto MAIUSC durante il ridimensionamento;\nper ridimensionare dal centro, tenir premuto ALT", "resize": "Per vincolare le proporzioni, tenir premuto MAIUSC durante il ridimensionamento;\nper ridimensionare dal centro, tenir premuto ALT",
"rotate": "Puoi mantenere gli angoli tenendo premuto SHIFT durante la rotazione", "rotate": "Puoi mantenere gli angoli tenendo premuto SHIFT durante la rotazione",
"lineEditor_info": "Fai doppio click o premi invio per modificare i punti", "lineEditor_info": "Fai doppio click o premi invio per modificare i punti",
+7 -8
View File
@@ -37,7 +37,7 @@
"fontSize": "フォントの大きさ", "fontSize": "フォントの大きさ",
"fontFamily": "フォントの種類", "fontFamily": "フォントの種類",
"onlySelected": "選択中のみ", "onlySelected": "選択中のみ",
"withBackground": "", "withBackground": "背景を含める",
"exportEmbedScene": "エクスポートされたファイルにシーンを埋め込みます", "exportEmbedScene": "エクスポートされたファイルにシーンを埋め込みます",
"exportEmbedScene_details": "シーンデータはエクスポートされたPNG/SVGファイルに保存され、シーンを復元することができます。\nエクスポートされたファイルのサイズは増加します。", "exportEmbedScene_details": "シーンデータはエクスポートされたPNG/SVGファイルに保存され、シーンを復元することができます。\nエクスポートされたファイルのサイズは増加します。",
"addWatermark": "\"Made with Excalidraw\"と表示", "addWatermark": "\"Made with Excalidraw\"と表示",
@@ -76,7 +76,8 @@
"group": "図形のグループ化", "group": "図形のグループ化",
"ungroup": "グループ化を解除", "ungroup": "グループ化を解除",
"collaborators": "共同編集者", "collaborators": "共同編集者",
"gridMode": "", "toggleGridMode": "グリッドモードに切り替える",
"toggleStats": "",
"addToLibrary": "ライブラリに追加", "addToLibrary": "ライブラリに追加",
"removeFromLibrary": "ライブラリから削除", "removeFromLibrary": "ライブラリから削除",
"libraryLoadingMessage": "ライブラリを読み込み中...", "libraryLoadingMessage": "ライブラリを読み込み中...",
@@ -117,10 +118,9 @@
"redo": "やり直し", "redo": "やり直し",
"roomDialog": "共同編集を開始する", "roomDialog": "共同編集を開始する",
"createNewRoom": "新しい部屋を作成する", "createNewRoom": "新しい部屋を作成する",
"fullScreen": "", "toggleFullScreen": "全画面表示に切り替える",
"darkMode": "", "toggleDarkMode": "ダークモードに切り替える",
"lightMode": "", "toggleZenMode": "集中モードに切り替える",
"zenMode": "",
"exitZenMode": "集中モードをやめる" "exitZenMode": "集中モードをやめる"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "外部図面を読み込むと、既存のコンテンツが置き換わります。続行しますか?", "loadSceneOverridePrompt": "外部図面を読み込むと、既存のコンテンツが置き換わります。続行しますか?",
"errorLoadingLibrary": "サードパーティライブラリの読み込み中にエラーが発生しました。", "errorLoadingLibrary": "サードパーティライブラリの読み込み中にエラーが発生しました。",
"confirmAddLibrary": "{{numShapes}} 個の図形をライブラリに追加します。よろしいですか?", "confirmAddLibrary": "{{numShapes}} 個の図形をライブラリに追加します。よろしいですか?",
"imageDoesNotContainScene": "", "imageDoesNotContainScene": "画像ファイルにシーンデータが含まれていません。エクスポート中にこれを有効にしましたか?",
"cannotRestoreFromImage": "このイメージファイルからシーンを復元できませんでした" "cannotRestoreFromImage": "このイメージファイルからシーンを復元できませんでした"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "クリックしてドラッグします。離すと終了します", "freeDraw": "クリックしてドラッグします。離すと終了します",
"text": "ヒント: 選択ツールを使用して任意の場所をダブルクリックしてテキストを追加することもできます", "text": "ヒント: 選択ツールを使用して任意の場所をダブルクリックしてテキストを追加することもできます",
"linearElementMulti": "最後のポイントをクリックするか、エスケープまたはEnterを押して終了します", "linearElementMulti": "最後のポイントをクリックするか、エスケープまたはEnterを押して終了します",
"lockAngle": "",
"resize": "サイズを変更中にSHIFTを押しすと比率を制御できます。Altを押すと中央からサイズを変更できます。", "resize": "サイズを変更中にSHIFTを押しすと比率を制御できます。Altを押すと中央からサイズを変更できます。",
"rotate": "回転中にSHIFT キーを押すと角度を制限することができます", "rotate": "回転中にSHIFT キーを押すと角度を制限することができます",
"lineEditor_info": "ポイントを編集するには、ダブルクリックまたはEnterキーを押します", "lineEditor_info": "ポイントを編集するには、ダブルクリックまたはEnterキーを押します",
+10 -11
View File
@@ -4,7 +4,7 @@
"selectAll": "전체 선택", "selectAll": "전체 선택",
"multiSelect": "선택 영역에 추가하기", "multiSelect": "선택 영역에 추가하기",
"moveCanvas": "캔버스 이동", "moveCanvas": "캔버스 이동",
"cut": "잘라내기", "cut": "",
"copy": "복사하기", "copy": "복사하기",
"copyAsPng": "클립보드로 PNG 이미지 복사", "copyAsPng": "클립보드로 PNG 이미지 복사",
"copyAsSvg": "클립보드로 SVG 이미지 복사", "copyAsSvg": "클립보드로 SVG 이미지 복사",
@@ -29,15 +29,15 @@
"edges": "가장자리", "edges": "가장자리",
"sharp": "선명하게", "sharp": "선명하게",
"round": "둥글게", "round": "둥글게",
"arrowheads": "화살표 모양", "arrowheads": "",
"arrowhead_none": "없음", "arrowhead_none": "",
"arrowhead_arrow": "화살표", "arrowhead_arrow": "",
"arrowhead_bar": "", "arrowhead_bar": "",
"arrowhead_dot": "", "arrowhead_dot": "",
"fontSize": "폰트 크기", "fontSize": "폰트 크기",
"fontFamily": "폰트 스타일", "fontFamily": "폰트 스타일",
"onlySelected": "선택한 항목만", "onlySelected": "선택한 항목만",
"withBackground": "", "withBackground": "배경 포함",
"exportEmbedScene": "", "exportEmbedScene": "",
"exportEmbedScene_details": "", "exportEmbedScene_details": "",
"addWatermark": "\"Made with Excalidraw\" 추가", "addWatermark": "\"Made with Excalidraw\" 추가",
@@ -76,7 +76,8 @@
"group": "그룹 생성", "group": "그룹 생성",
"ungroup": "그룹 해제", "ungroup": "그룹 해제",
"collaborators": "공동 작업자", "collaborators": "공동 작업자",
"gridMode": "", "toggleGridMode": "격자 모드 켜기/끄기",
"toggleStats": "",
"addToLibrary": "라이브러리에 추가", "addToLibrary": "라이브러리에 추가",
"removeFromLibrary": "라이브러리에서 제거", "removeFromLibrary": "라이브러리에서 제거",
"libraryLoadingMessage": "라이브러리 불러오는 중...", "libraryLoadingMessage": "라이브러리 불러오는 중...",
@@ -117,10 +118,9 @@
"redo": "다시 실행", "redo": "다시 실행",
"roomDialog": "실시간 협업 시작하기", "roomDialog": "실시간 협업 시작하기",
"createNewRoom": "방 만들기", "createNewRoom": "방 만들기",
"fullScreen": "", "toggleFullScreen": "전체화면",
"darkMode": "", "toggleDarkMode": "다크 모드 켜기/끄기",
"lightMode": "", "toggleZenMode": "젠 모드 켜기/끄기",
"zenMode": "",
"exitZenMode": "젠 모드 종료하기" "exitZenMode": "젠 모드 종료하기"
}, },
"alerts": { "alerts": {
@@ -161,7 +161,6 @@
"freeDraw": "클릭 후 드래그하세요. 완료되면 놓으세요.", "freeDraw": "클릭 후 드래그하세요. 완료되면 놓으세요.",
"text": "", "text": "",
"linearElementMulti": "마지막 지점을 클릭하거나 Esc 또는 Enter 키를 눌러 완료하세요.", "linearElementMulti": "마지막 지점을 클릭하거나 Esc 또는 Enter 키를 눌러 완료하세요.",
"lockAngle": "",
"resize": "", "resize": "",
"rotate": "SHIFT 키를 누르면서 회전하면 각도를 제한할 수 있습니다.", "rotate": "SHIFT 키를 누르면서 회전하면 각도를 제한할 수 있습니다.",
"lineEditor_info": "포인트를 수정하려면 두 번 클릭하거나 엔터 키를 누르세요.", "lineEditor_info": "포인트를 수정하려면 두 번 클릭하거나 엔터 키를 누르세요.",
+7 -8
View File
@@ -37,7 +37,7 @@
"fontSize": "စာလုံးအရွယ်", "fontSize": "စာလုံးအရွယ်",
"fontFamily": "စာလုံးပုံစံ", "fontFamily": "စာလုံးပုံစံ",
"onlySelected": "ရွေးထားသလောက်", "onlySelected": "ရွေးထားသလောက်",
"withBackground": "", "withBackground": "နောက်ခံပါထည့်",
"exportEmbedScene": "မြင်ကွင်းပါမြှုပ်နှံ၍ထုတ်ပါ", "exportEmbedScene": "မြင်ကွင်းပါမြှုပ်နှံ၍ထုတ်ပါ",
"exportEmbedScene_details": "ထုတ်ယူလိုက်သော PNG/SVG ထဲမြင်ကွင်းအချက်အလက်များပါဝင်သဖြင့် ပြန်လည်ရယူနိုင်သော်လည်း ဖိုင်အရွယ်အစားကြီးပါမည်။", "exportEmbedScene_details": "ထုတ်ယူလိုက်သော PNG/SVG ထဲမြင်ကွင်းအချက်အလက်များပါဝင်သဖြင့် ပြန်လည်ရယူနိုင်သော်လည်း ဖိုင်အရွယ်အစားကြီးပါမည်။",
"addWatermark": "\"Excalidraw ဖြင့်ဖန်တီးသည်။\" စာသားထည့်", "addWatermark": "\"Excalidraw ဖြင့်ဖန်တီးသည်။\" စာသားထည့်",
@@ -76,7 +76,8 @@
"group": "အုပ်စုဖွဲ့", "group": "အုပ်စုဖွဲ့",
"ungroup": "အုပ်စုဖျက်သိမ်း", "ungroup": "အုပ်စုဖျက်သိမ်း",
"collaborators": "ပူးပေါင်းပါဝင်သူများ", "collaborators": "ပူးပေါင်းပါဝင်သူများ",
"gridMode": "", "toggleGridMode": "ဇယားကွက်ဖော်/ဖျောက်",
"toggleStats": "",
"addToLibrary": "မှတ်တမ်းတင်", "addToLibrary": "မှတ်တမ်းတင်",
"removeFromLibrary": "မှတ်တမ်းမှထုတ်", "removeFromLibrary": "မှတ်တမ်းမှထုတ်",
"libraryLoadingMessage": "မှတ်တမ်းအား တင်သွင်းနေသည်...", "libraryLoadingMessage": "မှတ်တမ်းအား တင်သွင်းနေသည်...",
@@ -117,10 +118,9 @@
"redo": "ထပ်လုပ်", "redo": "ထပ်လုပ်",
"roomDialog": "တိုက်ရိုက်ပူးပေါင်းမှုစတင်", "roomDialog": "တိုက်ရိုက်ပူးပေါင်းမှုစတင်",
"createNewRoom": "အခန်းသစ်ဖွဲ့", "createNewRoom": "အခန်းသစ်ဖွဲ့",
"fullScreen": "", "toggleFullScreen": "မြင်ကွင်းကျယ်ဖွင့်/ပိတ်",
"darkMode": "", "toggleDarkMode": "အလင်း/အမှောင်",
"lightMode": "", "toggleZenMode": "ဇင်မြင်ကွင်းဖွင့်/ပိတ်",
"zenMode": "",
"exitZenMode": "ဇင်မြင်ကွင်းမှထွက်" "exitZenMode": "ဇင်မြင်ကွင်းမှထွက်"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "လက်ရှိရေးဆွဲထားသမျှအား ပြင်ပမှတင်သွင်းသောပုံနှင့်အစားထိုးပါမည်။ ဆက်လက်ဆောင်ရွက်လိုပါသလား။", "loadSceneOverridePrompt": "လက်ရှိရေးဆွဲထားသမျှအား ပြင်ပမှတင်သွင်းသောပုံနှင့်အစားထိုးပါမည်။ ဆက်လက်ဆောင်ရွက်လိုပါသလား။",
"errorLoadingLibrary": "ပြင်ပမှမှတ်တမ်းအားတင်သွင်းရာတွင်အမှားအယွင်းရှိနေသည်။", "errorLoadingLibrary": "ပြင်ပမှမှတ်တမ်းအားတင်သွင်းရာတွင်အမှားအယွင်းရှိနေသည်။",
"confirmAddLibrary": "{{numShapes}} ခုသောပုံသဏ္ဌာန်အားမှတ်တမ်းတင်ပါမည်။ အတည်ပြုပါ။", "confirmAddLibrary": "{{numShapes}} ခုသောပုံသဏ္ဌာန်အားမှတ်တမ်းတင်ပါမည်။ အတည်ပြုပါ။",
"imageDoesNotContainScene": "", "imageDoesNotContainScene": "ပုံတွင် မြင်ကွင်းအချက်အလက်များမပါဝင်ပါ။ ပုံထုတ်ယူချိန်တွင်ထည့်သွင်းခဲ့ပါသလား။",
"cannotRestoreFromImage": "ဤပုံဖြင့်မြင်ကွင်းပြန်လည်မရယူနိုင်ပါ။" "cannotRestoreFromImage": "ဤပုံဖြင့်မြင်ကွင်းပြန်လည်မရယူနိုင်ပါ။"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "ကလစ်နှိပ်၍ တရွတ်ဆွဲပါ၊ ပြီးလျှင်လွှတ်ပါ။", "freeDraw": "ကလစ်နှိပ်၍ တရွတ်ဆွဲပါ၊ ပြီးလျှင်လွှတ်ပါ။",
"text": "မှတ်ချက်။ ။မည်သည့်ကိရိယာရွေးထားသည်ဖြစ်စေ ကလစ်နှစ်ချက်နှိပ်၍စာသားထည့်နိုင်သည်", "text": "မှတ်ချက်။ ။မည်သည့်ကိရိယာရွေးထားသည်ဖြစ်စေ ကလစ်နှစ်ချက်နှိပ်၍စာသားထည့်နိုင်သည်",
"linearElementMulti": "နောက်ဆုံးအမှတ်ပေါ်တွင်ကလစ်နှိပ်ခြင်း၊ Escape (သို့) Enter နှိပ်ခြင်းတို့ဖြင့်အဆုံးသတ်နိုင်", "linearElementMulti": "နောက်ဆုံးအမှတ်ပေါ်တွင်ကလစ်နှိပ်ခြင်း၊ Escape (သို့) Enter နှိပ်ခြင်းတို့ဖြင့်အဆုံးသတ်နိုင်",
"lockAngle": "",
"resize": "အချိုးအစားကန့်သတ်ရန် Shift နှင့် ဗဟိုမှချိန်ညှိရန် Alt တို့ကိုနှိပ်ထားနိုင်သည်", "resize": "အချိုးအစားကန့်သတ်ရန် Shift နှင့် ဗဟိုမှချိန်ညှိရန် Alt တို့ကိုနှိပ်ထားနိုင်သည်",
"rotate": "Shift ကိုနှိပ်ထားခြင်းဖြင့် ထောင့်အလိုက်လှည့်နိုင်သည်", "rotate": "Shift ကိုနှိပ်ထားခြင်းဖြင့် ထောင့်အလိုက်လှည့်နိုင်သည်",
"lineEditor_info": "အမှတ်များပြင်ဆင်သတ်မှတ်ရင် ကလစ်နှစ်ချက် (သို့) Enter ကိုနှိပ်ပါ", "lineEditor_info": "အမှတ်များပြင်ဆင်သတ်မှတ်ရင် ကလစ်နှစ်ချက် (သို့) Enter ကိုနှိပ်ပါ",
+7 -8
View File
@@ -37,7 +37,7 @@
"fontSize": "Skriftstørrelse", "fontSize": "Skriftstørrelse",
"fontFamily": "Fontfamilie", "fontFamily": "Fontfamilie",
"onlySelected": "Kun valgte", "onlySelected": "Kun valgte",
"withBackground": "Med bakgrunn", "withBackground": "Inkluder bakgrunn",
"exportEmbedScene": "Bygg inn scenen i den eksporterte filen", "exportEmbedScene": "Bygg inn scenen i den eksporterte filen",
"exportEmbedScene_details": "Scenedata vil bli lagret i den eksporterte PNG/SVG-filen, slik at scenen kan gjenopprettes fra den.\nDet vil øke den eksporterte filstørrelsen.", "exportEmbedScene_details": "Scenedata vil bli lagret i den eksporterte PNG/SVG-filen, slik at scenen kan gjenopprettes fra den.\nDet vil øke den eksporterte filstørrelsen.",
"addWatermark": "Legg til \"Laget med Excalidraw\"", "addWatermark": "Legg til \"Laget med Excalidraw\"",
@@ -76,7 +76,8 @@
"group": "Gruppér utvalg", "group": "Gruppér utvalg",
"ungroup": "Avgruppér utvalg", "ungroup": "Avgruppér utvalg",
"collaborators": "Samarbeidspartnere", "collaborators": "Samarbeidspartnere",
"gridMode": "Rutevisning", "toggleGridMode": "Slå av/på rutenett",
"toggleStats": "Skru av/på statistikk for nerder",
"addToLibrary": "Legg til i bibliotek", "addToLibrary": "Legg til i bibliotek",
"removeFromLibrary": "Fjern fra bibliotek", "removeFromLibrary": "Fjern fra bibliotek",
"libraryLoadingMessage": "Laster bibliotek...", "libraryLoadingMessage": "Laster bibliotek...",
@@ -117,10 +118,9 @@
"redo": "Gjør om", "redo": "Gjør om",
"roomDialog": "Start sanntids-samarbeid", "roomDialog": "Start sanntids-samarbeid",
"createNewRoom": "Opprett et nytt rom", "createNewRoom": "Opprett et nytt rom",
"fullScreen": "Fullskjerm", "toggleFullScreen": "Skru fullskjerm av/på",
"darkMode": "Mørk modus", "toggleDarkMode": "Skru mørk modus av/på",
"lightMode": "Lys modus", "toggleZenMode": "Slå av/på zen-modus",
"zenMode": "Zen-modus",
"exitZenMode": "Avslutt zen-modus" "exitZenMode": "Avslutt zen-modus"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Å laste inn ekstern tegning vil erstatte det eksisterende innholdet. Ønsker du å fortsette?", "loadSceneOverridePrompt": "Å laste inn ekstern tegning vil erstatte det eksisterende innholdet. Ønsker du å fortsette?",
"errorLoadingLibrary": "Det oppstod en feil under lasting av tredjepartsbiblioteket.", "errorLoadingLibrary": "Det oppstod en feil under lasting av tredjepartsbiblioteket.",
"confirmAddLibrary": "Dette vil legge til {{numShapes}} figur(er) i biblioteket ditt. Er du sikker?", "confirmAddLibrary": "Dette vil legge til {{numShapes}} figur(er) i biblioteket ditt. Er du sikker?",
"imageDoesNotContainScene": "Importering av bilder støttes ikke for øyeblikket.\n\nVil du importere en scene? Dette bildet ser ikke ut til å inneholde noen scene-data. Har du aktivert dette under eksporten?", "imageDoesNotContainScene": "Bildefilen inneholder ikke scenedata. Har du aktivert dette under eksport?",
"cannotRestoreFromImage": "Scenen kunne ikke gjenopprettes fra denne bildefilen" "cannotRestoreFromImage": "Scenen kunne ikke gjenopprettes fra denne bildefilen"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Klikk og dra, slipp når du er ferdig", "freeDraw": "Klikk og dra, slipp når du er ferdig",
"text": "Tips: du kan også legge til tekst ved å dobbeltklikke hvor som helst med utvalgsverktøyet", "text": "Tips: du kan også legge til tekst ved å dobbeltklikke hvor som helst med utvalgsverktøyet",
"linearElementMulti": "Klikk på siste punkt eller trykk Escape eller Enter for å fullføre", "linearElementMulti": "Klikk på siste punkt eller trykk Escape eller Enter for å fullføre",
"lockAngle": "Du kan låse vinkelen ved å holde nede SHIFT",
"resize": "Du kan beholde forholdet ved å trykke SHIFT mens du endrer størrelse,\ntrykk ALT for å endre størrelsen fra midten", "resize": "Du kan beholde forholdet ved å trykke SHIFT mens du endrer størrelse,\ntrykk ALT for å endre størrelsen fra midten",
"rotate": "Du kan låse vinklene ved å holde SHIFT mens du roterer", "rotate": "Du kan låse vinklene ved å holde SHIFT mens du roterer",
"lineEditor_info": "Dobbeltklikk eller trykk Enter for å redigere punkter", "lineEditor_info": "Dobbeltklikk eller trykk Enter for å redigere punkter",
+46 -47
View File
@@ -4,12 +4,12 @@
"selectAll": "Alles selecteren", "selectAll": "Alles selecteren",
"multiSelect": "Voeg element toe aan selectie", "multiSelect": "Voeg element toe aan selectie",
"moveCanvas": "Canvas verplaatsen", "moveCanvas": "Canvas verplaatsen",
"cut": "Knip", "cut": "",
"copy": "Kopiëren", "copy": "Kopiëren",
"copyAsPng": "Kopieer als PNG", "copyAsPng": "Kopieer als PNG",
"copyAsSvg": "Kopieer naar klembord als SVG", "copyAsSvg": "Kopieer als SVG",
"bringForward": "Breng naar voren", "bringForward": "Breng naar voren",
"sendToBack": "Stuur naar achtergrond", "sendToBack": "Breng naar achtergrond",
"bringToFront": "Breng naar voorgrond", "bringToFront": "Breng naar voorgrond",
"sendBackward": "Breng naar achter", "sendBackward": "Breng naar achter",
"delete": "Verwijderen", "delete": "Verwijderen",
@@ -29,17 +29,17 @@
"edges": "Randen", "edges": "Randen",
"sharp": "Hoekig", "sharp": "Hoekig",
"round": "Rond", "round": "Rond",
"arrowheads": "Pijlpunten", "arrowheads": "",
"arrowhead_none": "Geen", "arrowhead_none": "",
"arrowhead_arrow": "Pijl", "arrowhead_arrow": "",
"arrowhead_bar": "Balk", "arrowhead_bar": "",
"arrowhead_dot": "Punt", "arrowhead_dot": "",
"fontSize": "Tekstgrootte", "fontSize": "Tekstgrootte",
"fontFamily": "Lettertype", "fontFamily": "Lettertype",
"onlySelected": "Enkel geselecteerde", "onlySelected": "Enkel geselecteerde",
"withBackground": "Met achtergrond", "withBackground": "Met achtergrond",
"exportEmbedScene": "Scène in geëxporteerd bestand invoegen", "exportEmbedScene": "",
"exportEmbedScene_details": "Scènegegevens worden in het geëxporteerde PNG/SVG-bestand opgeslagen zodat de scène kan worden hersteld.\nDe grootte van de geëxporteerde bestanden zal toenemen.", "exportEmbedScene_details": "",
"addWatermark": "Voeg \"Gemaakt met Excalidraw\" toe", "addWatermark": "Voeg \"Gemaakt met Excalidraw\" toe",
"handDrawn": "Handgetekend", "handDrawn": "Handgetekend",
"normal": "Normaal", "normal": "Normaal",
@@ -60,7 +60,7 @@
"architect": "Architect", "architect": "Architect",
"artist": "Artiest", "artist": "Artiest",
"cartoonist": "Cartoonist", "cartoonist": "Cartoonist",
"fileTitle": "Bestandsnaam", "fileTitle": "",
"colorPicker": "Kleurenkiezer", "colorPicker": "Kleurenkiezer",
"canvasBackground": "Canvas achtergrond", "canvasBackground": "Canvas achtergrond",
"drawingCanvas": "Canvas", "drawingCanvas": "Canvas",
@@ -69,28 +69,29 @@
"language": "Taal", "language": "Taal",
"createRoom": "Deel een live-samenwerkingssessie", "createRoom": "Deel een live-samenwerkingssessie",
"duplicateSelection": "Dupliceer", "duplicateSelection": "Dupliceer",
"untitled": "Naamloos", "untitled": "",
"name": "Naam", "name": "Naam",
"yourName": "Jouw naam", "yourName": "Jouw naam",
"madeWithExcalidraw": "Gemaakt met Excalidraw", "madeWithExcalidraw": "Gemaakt met Excalidraw",
"group": "Groeperen", "group": "Groeperen",
"ungroup": "Groep opheffen", "ungroup": "Groep opheffen",
"collaborators": "Deelnemers", "collaborators": "Deelnemers",
"gridMode": "Rasterweergave", "toggleGridMode": "Rasterlijnen in-/uitschakelen",
"toggleStats": "",
"addToLibrary": "Voeg toe aan bibliotheek", "addToLibrary": "Voeg toe aan bibliotheek",
"removeFromLibrary": "Verwijder uit bibliotheek", "removeFromLibrary": "Verwijder uit bibliotheek",
"libraryLoadingMessage": "Bibliotheek laden...", "libraryLoadingMessage": "Bibliotheek laden...",
"libraries": "Blader door bibliotheken", "libraries": "",
"loadingScene": "Scène laden...", "loadingScene": "Scène laden...",
"align": "Uitlijnen", "align": "",
"alignTop": "Boven uitlijnen", "alignTop": "",
"alignBottom": "Onder uitlijnen", "alignBottom": "",
"alignLeft": "Links uitlijnen", "alignLeft": "",
"alignRight": "Rechts uitlijnen", "alignRight": "",
"centerVertically": "Verticaal Centreren", "centerVertically": "",
"centerHorizontally": "Horizontaal Centreren", "centerHorizontally": "",
"distributeHorizontally": "Horizontaal verspreiden", "distributeHorizontally": "",
"distributeVertically": "Verticaal distribueren" "distributeVertically": ""
}, },
"buttons": { "buttons": {
"clearReset": "Canvas opnieuw instellen", "clearReset": "Canvas opnieuw instellen",
@@ -117,16 +118,15 @@
"redo": "Herstel ongedaan maken", "redo": "Herstel ongedaan maken",
"roomDialog": "Live-samenwerkingssessie starten", "roomDialog": "Live-samenwerkingssessie starten",
"createNewRoom": "Creëer live-samenwerkingssessie", "createNewRoom": "Creëer live-samenwerkingssessie",
"fullScreen": "Volledig scherm", "toggleFullScreen": "Volledig scherm in-/uitschakelen",
"darkMode": "Donkere modus", "toggleDarkMode": "Donkere modus in-/uitschakelen",
"lightMode": "Lichte modus", "toggleZenMode": "Zen modus in-/uitschakelen",
"zenMode": "Zen modus",
"exitZenMode": "Verlaat zen modus" "exitZenMode": "Verlaat zen modus"
}, },
"alerts": { "alerts": {
"clearReset": "Dit zal het hele canvas verwijderen. Weet je het zeker?", "clearReset": "Dit zal het hele canvas verwijderen. Weet je het zeker?",
"couldNotCreateShareableLink": "Kon geen deelbare link aanmaken.", "couldNotCreateShareableLink": "Kon geen deelbare link aanmaken.",
"couldNotCreateShareableLinkTooBig": "Kan geen deelbare link aanmaken: de scène is te groot", "couldNotCreateShareableLinkTooBig": "",
"couldNotLoadInvalidFile": "Kan ongeldig bestand niet laden", "couldNotLoadInvalidFile": "Kan ongeldig bestand niet laden",
"importBackendFailed": "Importeren vanuit backend mislukt.", "importBackendFailed": "Importeren vanuit backend mislukt.",
"cannotExportEmptyCanvas": "Kan geen leeg canvas exporteren.", "cannotExportEmptyCanvas": "Kan geen leeg canvas exporteren.",
@@ -136,8 +136,8 @@
"loadSceneOverridePrompt": "Het laden van externe tekening zal uw bestaande inhoud vervangen. Wil je doorgaan?", "loadSceneOverridePrompt": "Het laden van externe tekening zal uw bestaande inhoud vervangen. Wil je doorgaan?",
"errorLoadingLibrary": "Bij het laden van de externe bibliotheek is een fout opgetreden.", "errorLoadingLibrary": "Bij het laden van de externe bibliotheek is een fout opgetreden.",
"confirmAddLibrary": "Hiermee worden {{numShapes}} vorm(n) aan uw bibliotheek toegevoegd. Ben je het zeker?", "confirmAddLibrary": "Hiermee worden {{numShapes}} vorm(n) aan uw bibliotheek toegevoegd. Ben je het zeker?",
"imageDoesNotContainScene": "Afbeeldingen importeren wordt op dit moment niet ondersteund.\n\nWil je een scène importeren? Deze afbeelding lijkt geen scène gegevens te bevatten. Heb je dit geactiveerd tijdens het exporteren?", "imageDoesNotContainScene": "",
"cannotRestoreFromImage": "Scène kan niet worden hersteld vanuit dit afbeeldingsbestand" "cannotRestoreFromImage": ""
}, },
"toolBar": { "toolBar": {
"selection": "Selectie", "selection": "Selectie",
@@ -161,7 +161,6 @@
"freeDraw": "Klik en sleep, laat los als je klaar bent", "freeDraw": "Klik en sleep, laat los als je klaar bent",
"text": "Tip: je kunt tekst toevoegen door ergens dubbel te klikken met de selectietool", "text": "Tip: je kunt tekst toevoegen door ergens dubbel te klikken met de selectietool",
"linearElementMulti": "Klik op het laatste punt of druk op Escape of Enter om te stoppen", "linearElementMulti": "Klik op het laatste punt of druk op Escape of Enter om te stoppen",
"lockAngle": "Je kunt de hoek beperken door SHIFT ingedrukt te houden",
"resize": "Houd tijdens het vergroten SHIFT ingedrukt om verhoudingen te behouden,\ngebruik ALT om vanuit het midden te vergroten/verkleinen", "resize": "Houd tijdens het vergroten SHIFT ingedrukt om verhoudingen te behouden,\ngebruik ALT om vanuit het midden te vergroten/verkleinen",
"rotate": "Je kan hoeken beperken door SHIFT ingedrukt te houden wanneer je draait", "rotate": "Je kan hoeken beperken door SHIFT ingedrukt te houden wanneer je draait",
"lineEditor_info": "Dubbelklik of druk op Enter om punten te bewerken", "lineEditor_info": "Dubbelklik of druk op Enter om punten te bewerken",
@@ -169,9 +168,9 @@
"lineEditor_nothingSelected": "Selecteer een punt om te verplaatsen of te verwijderen, of houd Alt ingedrukt en klik om nieuwe punten toe te voegen" "lineEditor_nothingSelected": "Selecteer een punt om te verplaatsen of te verwijderen, of houd Alt ingedrukt en klik om nieuwe punten toe te voegen"
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "Kan voorbeeld niet tonen", "cannotShowPreview": "",
"canvasTooBig": "Het canvas is mogelijk te groot.", "canvasTooBig": "",
"canvasTooBigTip": "Tip: beweeg de verste elementen iets dichter bij elkaar." "canvasTooBigTip": ""
}, },
"errorSplash": { "errorSplash": {
"headingMain_pre": "Fout opgetreden. Probeer ", "headingMain_pre": "Fout opgetreden. Probeer ",
@@ -193,7 +192,7 @@
"button_stopSession": "Sessie afbreken", "button_stopSession": "Sessie afbreken",
"desc_inProgressIntro": "De live-samenwerkingssessie is nu gestart.", "desc_inProgressIntro": "De live-samenwerkingssessie is nu gestart.",
"desc_shareLink": "Deel deze link met iedereen waarmee je wil samenwerken:", "desc_shareLink": "Deel deze link met iedereen waarmee je wil samenwerken:",
"desc_exitSession": "Het stoppen van de sessie zal je loskoppelen van de kamer, maar je kunt lokaal doorwerken met de scène.\nPas op: dit heeft geen invloed op andere mensen en dat zij nog steeds in staat zullen zijn om samen te werken aan hun versie." "desc_exitSession": ""
}, },
"errorDialog": { "errorDialog": {
"title": "Fout" "title": "Fout"
@@ -214,22 +213,22 @@
"textNewLine": "Nieuwe regel toevoegen (tekst)", "textNewLine": "Nieuwe regel toevoegen (tekst)",
"textFinish": "Voltooi bewerken (tekst)", "textFinish": "Voltooi bewerken (tekst)",
"zoomToFit": "Zoom in op alle elementen", "zoomToFit": "Zoom in op alle elementen",
"zoomToSelection": "Inzoomen op selectie", "zoomToSelection": "",
"preventBinding": "Pijlbinding voorkomen" "preventBinding": ""
}, },
"encrypted": { "encrypted": {
"tooltip": "Je tekeningen zijn beveiligd met end-to-end encryptie, dus Excalidraw's servers zullen nooit zien wat je tekent." "tooltip": "Je tekeningen zijn beveiligd met end-to-end encryptie, dus Excalidraw's servers zullen nooit zien wat je tekent."
}, },
"stats": { "stats": {
"angle": "Hoek", "angle": "",
"element": "Element", "element": "",
"elements": "Elementen", "elements": "",
"height": "Hoogte", "height": "",
"scene": "Scene", "scene": "",
"selected": "Geselecteerd", "selected": "",
"storage": "Opslag", "storage": "",
"title": "Statistieken voor nerds", "title": "",
"total": "Totaal", "total": "",
"width": "Breedte" "width": ""
} }
} }
+43 -44
View File
@@ -4,7 +4,7 @@
"selectAll": "Vel alt", "selectAll": "Vel alt",
"multiSelect": "Legg til element i utval", "multiSelect": "Legg til element i utval",
"moveCanvas": "Flytt lerretet", "moveCanvas": "Flytt lerretet",
"cut": "Klipp ut", "cut": "",
"copy": "Kopier", "copy": "Kopier",
"copyAsPng": "Kopier til utklippstavla som PNG", "copyAsPng": "Kopier til utklippstavla som PNG",
"copyAsSvg": "Kopier til utklippstavla som SVG", "copyAsSvg": "Kopier til utklippstavla som SVG",
@@ -29,17 +29,17 @@
"edges": "Kanter", "edges": "Kanter",
"sharp": "Skarp", "sharp": "Skarp",
"round": "Rund", "round": "Rund",
"arrowheads": "Pilhovud", "arrowheads": "",
"arrowhead_none": "Ingen", "arrowhead_none": "",
"arrowhead_arrow": "Pil", "arrowhead_arrow": "",
"arrowhead_bar": "Stolpe", "arrowhead_bar": "",
"arrowhead_dot": "Prikk", "arrowhead_dot": "",
"fontSize": "Skriftstorleik", "fontSize": "Skriftstorleik",
"fontFamily": "Skrifttype", "fontFamily": "Skrifttype",
"onlySelected": "Kun valde", "onlySelected": "Kun valde",
"withBackground": "Med bakgrunn", "withBackground": "Inkluder bakgrunn",
"exportEmbedScene": "Bygg scena inn i eksportert fil", "exportEmbedScene": "",
"exportEmbedScene_details": "Scenedataa vert lagra i den eksporterte PNG- eller SVG-fila slik at scena kan bli gjenopprettast frå den. Dette vil auke eksportert filstorleik.", "exportEmbedScene_details": "",
"addWatermark": "Legg til «Laga med Excalidraw»", "addWatermark": "Legg til «Laga med Excalidraw»",
"handDrawn": "Handteikna", "handDrawn": "Handteikna",
"normal": "Normal", "normal": "Normal",
@@ -60,7 +60,7 @@
"architect": "Arkitekt", "architect": "Arkitekt",
"artist": "Kunstnar", "artist": "Kunstnar",
"cartoonist": "Teiknar", "cartoonist": "Teiknar",
"fileTitle": "Filnamn", "fileTitle": "",
"colorPicker": "Fargeveljar", "colorPicker": "Fargeveljar",
"canvasBackground": "Lerretsbakgrunn", "canvasBackground": "Lerretsbakgrunn",
"drawingCanvas": "Lerret", "drawingCanvas": "Lerret",
@@ -69,28 +69,29 @@
"language": "Språk", "language": "Språk",
"createRoom": "Del ei sanntids-samarbeidsøkt", "createRoom": "Del ei sanntids-samarbeidsøkt",
"duplicateSelection": "Dupliser", "duplicateSelection": "Dupliser",
"untitled": "Utan namn", "untitled": "",
"name": "Namn", "name": "Namn",
"yourName": "Namnet ditt", "yourName": "Namnet ditt",
"madeWithExcalidraw": "Laga med Excalidraw", "madeWithExcalidraw": "Laga med Excalidraw",
"group": "Grupper utval", "group": "Grupper utval",
"ungroup": "Avgrupper utval", "ungroup": "Avgrupper utval",
"collaborators": "Samarbeidarar", "collaborators": "Samarbeidarar",
"gridMode": "", "toggleGridMode": "Sla på/av rutenett",
"toggleStats": "",
"addToLibrary": "Legg til i bibliotek", "addToLibrary": "Legg til i bibliotek",
"removeFromLibrary": "Fjern frå bibliotek", "removeFromLibrary": "Fjern frå bibliotek",
"libraryLoadingMessage": "Laster bibliotek...", "libraryLoadingMessage": "Laster bibliotek...",
"libraries": "Blad gjennom bibliotek", "libraries": "",
"loadingScene": "Laster scene...", "loadingScene": "Laster scene...",
"align": "Juster", "align": "",
"alignTop": "Juster til topp", "alignTop": "",
"alignBottom": "Juster til botn", "alignBottom": "",
"alignLeft": "Juster til venstre", "alignLeft": "",
"alignRight": "Juster til høgre", "alignRight": "",
"centerVertically": "Midtstill vertikalt", "centerVertically": "",
"centerHorizontally": "Midtstill horisontalt", "centerHorizontally": "",
"distributeHorizontally": "Sprei horisontalt", "distributeHorizontally": "",
"distributeVertically": "Sprei vertikalt" "distributeVertically": ""
}, },
"buttons": { "buttons": {
"clearReset": "Tilbakestill lerretet", "clearReset": "Tilbakestill lerretet",
@@ -99,7 +100,7 @@
"exportToSvg": "Eksporter til SVG", "exportToSvg": "Eksporter til SVG",
"copyToClipboard": "Kopier til utklippstavla", "copyToClipboard": "Kopier til utklippstavla",
"copyPngToClipboard": "Kopier PNG til utklippstavla", "copyPngToClipboard": "Kopier PNG til utklippstavla",
"scale": "Skaler", "scale": "",
"save": "Lagre", "save": "Lagre",
"saveAs": "Lagre som", "saveAs": "Lagre som",
"load": "Opne", "load": "Opne",
@@ -117,16 +118,15 @@
"redo": "Gjer om", "redo": "Gjer om",
"roomDialog": "Start sanntids-samarbeid", "roomDialog": "Start sanntids-samarbeid",
"createNewRoom": "Lag nytt rom", "createNewRoom": "Lag nytt rom",
"fullScreen": "", "toggleFullScreen": "Slå på/av fullskjerm",
"darkMode": "", "toggleDarkMode": "Skru av/på skumringsmodus",
"lightMode": "", "toggleZenMode": "Slå på/av zen-modus",
"zenMode": "",
"exitZenMode": "Avslutt zen-modus" "exitZenMode": "Avslutt zen-modus"
}, },
"alerts": { "alerts": {
"clearReset": "Dette vil tømme lerretet. Er du sikker?", "clearReset": "Dette vil tømme lerretet. Er du sikker?",
"couldNotCreateShareableLink": "Kunne ikkje lage delingslenke.", "couldNotCreateShareableLink": "Kunne ikkje lage delingslenke.",
"couldNotCreateShareableLinkTooBig": "Kunne ikkje opprette deleleg lenke: scena er for stor", "couldNotCreateShareableLinkTooBig": "",
"couldNotLoadInvalidFile": "Kunne ikkje laste inn ugyldig fil", "couldNotLoadInvalidFile": "Kunne ikkje laste inn ugyldig fil",
"importBackendFailed": "Importering av backend feila.", "importBackendFailed": "Importering av backend feila.",
"cannotExportEmptyCanvas": "Kan ikkje eksportere eit tomt lerret.", "cannotExportEmptyCanvas": "Kan ikkje eksportere eit tomt lerret.",
@@ -137,7 +137,7 @@
"errorLoadingLibrary": "Det oppstod ein feil under lastinga av tredjepartsbibliotek.", "errorLoadingLibrary": "Det oppstod ein feil under lastinga av tredjepartsbibliotek.",
"confirmAddLibrary": "Dette vil legge til {{numShapes}} form(er) i biblioteket ditt. Er du sikker?", "confirmAddLibrary": "Dette vil legge til {{numShapes}} form(er) i biblioteket ditt. Er du sikker?",
"imageDoesNotContainScene": "", "imageDoesNotContainScene": "",
"cannotRestoreFromImage": "Scena kunne ikkje gjenopprettast frå denne biletfila" "cannotRestoreFromImage": ""
}, },
"toolBar": { "toolBar": {
"selection": "Vel", "selection": "Vel",
@@ -161,7 +161,6 @@
"freeDraw": "Klikk og drag, slepp når du er ferdig", "freeDraw": "Klikk og drag, slepp når du er ferdig",
"text": "Tips: du kan òg leggje til tekst ved å dobbeltklikke kor som helst med utvalgsverktyet", "text": "Tips: du kan òg leggje til tekst ved å dobbeltklikke kor som helst med utvalgsverktyet",
"linearElementMulti": "Klikk på siste punkt eller trykk Escape eller Enter for å fullføre", "linearElementMulti": "Klikk på siste punkt eller trykk Escape eller Enter for å fullføre",
"lockAngle": "",
"resize": "Du kan halde fram med forholdet ved å trykke SHIFT medan du endrar storleik,\ntrykk ALT for å endre storleiken frå midten", "resize": "Du kan halde fram med forholdet ved å trykke SHIFT medan du endrar storleik,\ntrykk ALT for å endre storleiken frå midten",
"rotate": "Du kan låse vinklane ved å halde SHIFT medan du roterer", "rotate": "Du kan låse vinklane ved å halde SHIFT medan du roterer",
"lineEditor_info": "Dobbeltklikk eller trykk Enter for å redigere punkt", "lineEditor_info": "Dobbeltklikk eller trykk Enter for å redigere punkt",
@@ -169,9 +168,9 @@
"lineEditor_nothingSelected": "Vel eit punkt å flytte eller fjerne, eller hald Alt og klikk for å legge til nye punkt" "lineEditor_nothingSelected": "Vel eit punkt å flytte eller fjerne, eller hald Alt og klikk for å legge til nye punkt"
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "Kan ikkje vise førehandsvising", "cannotShowPreview": "",
"canvasTooBig": "Lerretet er mogleg for stort.", "canvasTooBig": "",
"canvasTooBigTip": "Tips: prøv å flytte elementa som er lengst frå kvarandre, litt nærare kvarandre." "canvasTooBigTip": ""
}, },
"errorSplash": { "errorSplash": {
"headingMain_pre": "Ein feil oppstod. Prøv ", "headingMain_pre": "Ein feil oppstod. Prøv ",
@@ -214,22 +213,22 @@
"textNewLine": "Legg til ny linje (tekst)", "textNewLine": "Legg til ny linje (tekst)",
"textFinish": "Fullfør redigering (tekst)", "textFinish": "Fullfør redigering (tekst)",
"zoomToFit": "Zoom for å sjå alle elementa", "zoomToFit": "Zoom for å sjå alle elementa",
"zoomToSelection": "Zoom til utval", "zoomToSelection": "",
"preventBinding": "Hindre pilkobling" "preventBinding": "Hindre pilkobling"
}, },
"encrypted": { "encrypted": {
"tooltip": "Teikningane dine er ende-til-ende-krypterte slik at Excalidraw sine serverar aldri får sjå dei." "tooltip": "Teikningane dine er ende-til-ende-krypterte slik at Excalidraw sine serverar aldri får sjå dei."
}, },
"stats": { "stats": {
"angle": "Vinkel", "angle": "",
"element": "Element", "element": "",
"elements": "Element", "elements": "",
"height": "Høgde", "height": "",
"scene": "Scene", "scene": "",
"selected": "Valde", "selected": "",
"storage": "Lagring", "storage": "",
"title": "Statistikk for nerdar", "title": "",
"total": "Totalt", "total": "",
"width": "Breidde" "width": ""
} }
} }
+21 -22
View File
@@ -1,34 +1,33 @@
{ {
"ar-SA": 86, "ar-SA": 89,
"bg-BG": 60, "bg-BG": 61,
"ca-ES": 78, "ca-ES": 81,
"de-DE": 100, "de-DE": 99,
"el-GR": 96, "el-GR": 95,
"en": 100, "en": 100,
"es-ES": 99, "es-ES": 81,
"fa-IR": 86, "fa-IR": 89,
"fi-FI": 100, "fi-FI": 100,
"fr-FR": 100, "fr-FR": 100,
"he-IL": 96, "he-IL": 69,
"hi-IN": 82, "hi-IN": 82,
"hu-HU": 92, "hu-HU": 44,
"id-ID": 100, "id-ID": 99,
"it-IT": 100, "it-IT": 100,
"ja-JP": 85, "ja-JP": 89,
"ko-KR": 67, "ko-KR": 68,
"my-MM": 93, "my-MM": 96,
"nb-NO": 100, "nb-NO": 100,
"nl-NL": 100, "nl-NL": 80,
"nn-NO": 96, "nn-NO": 80,
"pl-PL": 95, "pl-PL": 79,
"pt-BR": 100, "pt-PT": 83,
"pt-PT": 100,
"ro-RO": 100, "ro-RO": 100,
"ru-RU": 97, "ru-RU": 81,
"sk-SK": 100, "sk-SK": 100,
"sv-SE": 100, "sv-SE": 100,
"tr-TR": 87, "tr-TR": 81,
"uk-UA": 99, "uk-UA": 98,
"zh-CN": 100, "zh-CN": 95,
"zh-TW": 99 "zh-TW": 99
} }
+43 -44
View File
@@ -4,7 +4,7 @@
"selectAll": "Zaznacz wszystko", "selectAll": "Zaznacz wszystko",
"multiSelect": "Dodaj element do zaznaczenia", "multiSelect": "Dodaj element do zaznaczenia",
"moveCanvas": "Przesuń obszar roboczy", "moveCanvas": "Przesuń obszar roboczy",
"cut": "Wytnij", "cut": "",
"copy": "Kopiuj", "copy": "Kopiuj",
"copyAsPng": "Skopiuj do schowka jako plik PNG", "copyAsPng": "Skopiuj do schowka jako plik PNG",
"copyAsSvg": "Skopiuj do schowka jako plik SVG", "copyAsSvg": "Skopiuj do schowka jako plik SVG",
@@ -29,17 +29,17 @@
"edges": "Krawędzie", "edges": "Krawędzie",
"sharp": "Ostry", "sharp": "Ostry",
"round": "Zaokrąglij", "round": "Zaokrąglij",
"arrowheads": "Groty", "arrowheads": "",
"arrowhead_none": "Brak", "arrowhead_none": "",
"arrowhead_arrow": "Strzałka", "arrowhead_arrow": "",
"arrowhead_bar": "", "arrowhead_bar": "",
"arrowhead_dot": "Kropka", "arrowhead_dot": "",
"fontSize": "Rozmiar tekstu", "fontSize": "Rozmiar tekstu",
"fontFamily": "Krój pisma", "fontFamily": "Krój pisma",
"onlySelected": "Tylko wybrane", "onlySelected": "Tylko wybrane",
"withBackground": "", "withBackground": "Z tłem dokumentu",
"exportEmbedScene": "Osadź scenę w eksportowanym pliku", "exportEmbedScene": "",
"exportEmbedScene_details": "Dane sceny zostaną zapisane w eksportowanym pliku PNG/SVG tak, aby scena mogła zostać z niego przywrócona.\nZwiększy to rozmiar eksportowanego pliku.", "exportEmbedScene_details": "",
"addWatermark": "Dodaj \"Zrobione w Excalidraw\"", "addWatermark": "Dodaj \"Zrobione w Excalidraw\"",
"handDrawn": "Odręczny", "handDrawn": "Odręczny",
"normal": "Normalny", "normal": "Normalny",
@@ -60,7 +60,7 @@
"architect": "Dokładny", "architect": "Dokładny",
"artist": "Artystyczny", "artist": "Artystyczny",
"cartoonist": "Rysunkowy", "cartoonist": "Rysunkowy",
"fileTitle": "Tytuł pliku", "fileTitle": "",
"colorPicker": "Paleta kolorów", "colorPicker": "Paleta kolorów",
"canvasBackground": "Kolor dokumentu", "canvasBackground": "Kolor dokumentu",
"drawingCanvas": "Obszar roboczy", "drawingCanvas": "Obszar roboczy",
@@ -69,28 +69,29 @@
"language": "Język", "language": "Język",
"createRoom": "Udostępnij sesję współpracy na żywo", "createRoom": "Udostępnij sesję współpracy na żywo",
"duplicateSelection": "Powiel", "duplicateSelection": "Powiel",
"untitled": "Bez tytułu", "untitled": "",
"name": "Nazwa", "name": "Nazwa",
"yourName": "Twoje imię", "yourName": "Twoje imię",
"madeWithExcalidraw": "Zrobione w Excalidraw", "madeWithExcalidraw": "Zrobione w Excalidraw",
"group": "Zgrupuj wybrane", "group": "Zgrupuj wybrane",
"ungroup": "Rozgrupuj wybrane", "ungroup": "Rozgrupuj wybrane",
"collaborators": "Współtwórcy", "collaborators": "Współtwórcy",
"gridMode": "Tryb siatki", "toggleGridMode": "Włącz siatkę",
"toggleStats": "",
"addToLibrary": "Dodaj do biblioteki", "addToLibrary": "Dodaj do biblioteki",
"removeFromLibrary": "Usuń z biblioteki", "removeFromLibrary": "Usuń z biblioteki",
"libraryLoadingMessage": "Wczytywanie biblioteki...", "libraryLoadingMessage": "Wczytywanie biblioteki...",
"libraries": "Przeglądaj biblioteki", "libraries": "",
"loadingScene": "Ładowanie sceny...", "loadingScene": "Ładowanie sceny...",
"align": "Wyrównaj", "align": "",
"alignTop": "Wyrównaj do góry", "alignTop": "",
"alignBottom": "Wyrównaj do dołu", "alignBottom": "",
"alignLeft": "Wyrównaj do lewej", "alignLeft": "",
"alignRight": "Wyrównaj do prawej", "alignRight": "",
"centerVertically": "Wyśrodkuj w pionie", "centerVertically": "",
"centerHorizontally": "Wyśrodkuj w poziomie", "centerHorizontally": "",
"distributeHorizontally": "Rozłóż poziomo", "distributeHorizontally": "",
"distributeVertically": "Rozłóż pionowo" "distributeVertically": ""
}, },
"buttons": { "buttons": {
"clearReset": "Wyczyść dokument i zresetuj kolor dokumentu", "clearReset": "Wyczyść dokument i zresetuj kolor dokumentu",
@@ -117,16 +118,15 @@
"redo": "Przywróć", "redo": "Przywróć",
"roomDialog": "Utwórz nową sesję współpracy na żywo", "roomDialog": "Utwórz nową sesję współpracy na żywo",
"createNewRoom": "Utwórz nowy pokój", "createNewRoom": "Utwórz nowy pokój",
"fullScreen": "", "toggleFullScreen": "Włącz/wyłącz tryb pełnoekranowy",
"darkMode": "", "toggleDarkMode": "Włącz tryb ciemny",
"lightMode": "", "toggleZenMode": "Włącz tryb Zen",
"zenMode": "",
"exitZenMode": "Wyjdź z trybu Zen" "exitZenMode": "Wyjdź z trybu Zen"
}, },
"alerts": { "alerts": {
"clearReset": "To spowoduje usunięcie wszystkiego z dokumentu. Czy chcesz kontynuować?", "clearReset": "To spowoduje usunięcie wszystkiego z dokumentu. Czy chcesz kontynuować?",
"couldNotCreateShareableLink": "Wystąpił błąd przy generowaniu linka do udostępniania.", "couldNotCreateShareableLink": "Wystąpił błąd przy generowaniu linka do udostępniania.",
"couldNotCreateShareableLinkTooBig": "Nie można utworzyć udostępnialnego linku: scena jest za duża", "couldNotCreateShareableLinkTooBig": "",
"couldNotLoadInvalidFile": "Nie udało się otworzyć pliku. Wybrany plik jest nieprawidłowy.", "couldNotLoadInvalidFile": "Nie udało się otworzyć pliku. Wybrany plik jest nieprawidłowy.",
"importBackendFailed": "Wystąpił błąd podczas importowania pliku.", "importBackendFailed": "Wystąpił błąd podczas importowania pliku.",
"cannotExportEmptyCanvas": "Najpierw musisz coś narysować, aby zapisać dokument.", "cannotExportEmptyCanvas": "Najpierw musisz coś narysować, aby zapisać dokument.",
@@ -134,10 +134,10 @@
"decryptFailed": "Nie udało się odszyfrować danych.", "decryptFailed": "Nie udało się odszyfrować danych.",
"uploadedSecurly": "By zapewnić Ci prywatność, udostępnianie projektu jest zabezpieczone szyfrowaniem end-to-end, co oznacza, że poza tobą i osobą z którą podzielisz się linkiem, nikt nie ma dostępu do tego co udostępniasz.", "uploadedSecurly": "By zapewnić Ci prywatność, udostępnianie projektu jest zabezpieczone szyfrowaniem end-to-end, co oznacza, że poza tobą i osobą z którą podzielisz się linkiem, nikt nie ma dostępu do tego co udostępniasz.",
"loadSceneOverridePrompt": "Wczytanie zewnętrznego rysunku zastąpi istniejącą zawartość. Czy chcesz kontynuować?", "loadSceneOverridePrompt": "Wczytanie zewnętrznego rysunku zastąpi istniejącą zawartość. Czy chcesz kontynuować?",
"errorLoadingLibrary": "Wystąpił błąd podczas ładowania biblioteki stron trzecich.", "errorLoadingLibrary": "",
"confirmAddLibrary": "To doda {{numShapes}} kształtów do twojej biblioteki. Jesteś pewien?", "confirmAddLibrary": "",
"imageDoesNotContainScene": "", "imageDoesNotContainScene": "",
"cannotRestoreFromImage": "Scena nie mogła zostać przywrócona z pliku obrazu" "cannotRestoreFromImage": ""
}, },
"toolBar": { "toolBar": {
"selection": "Zaznaczenie", "selection": "Zaznaczenie",
@@ -161,7 +161,6 @@
"freeDraw": "Naciśnij i przeciągnij by rysować, puść kiedy skończysz", "freeDraw": "Naciśnij i przeciągnij by rysować, puść kiedy skończysz",
"text": "Wskazówka: możesz również dodać tekst klikając dwukrotnie gdziekolwiek za pomocą narzędzia zaznaczania", "text": "Wskazówka: możesz również dodać tekst klikając dwukrotnie gdziekolwiek za pomocą narzędzia zaznaczania",
"linearElementMulti": "Aby zakończyć krzywą, ponownie kliknij w ostatni punkt, bądź naciśnij Esc albo Enter", "linearElementMulti": "Aby zakończyć krzywą, ponownie kliknij w ostatni punkt, bądź naciśnij Esc albo Enter",
"lockAngle": "",
"resize": "Możesz zachować proporcję trzymająć wcisnięty SHIFT, przytrzymaj ALT by zmienić rozmiar względem środka", "resize": "Możesz zachować proporcję trzymająć wcisnięty SHIFT, przytrzymaj ALT by zmienić rozmiar względem środka",
"rotate": "Możesz obracać element w równych odstępach trzymając wciśnięty SHIFT", "rotate": "Możesz obracać element w równych odstępach trzymając wciśnięty SHIFT",
"lineEditor_info": "Kliknij dwukrotnie lub naciśnij Enter, aby edytować punkty", "lineEditor_info": "Kliknij dwukrotnie lub naciśnij Enter, aby edytować punkty",
@@ -169,9 +168,9 @@
"lineEditor_nothingSelected": "Naciśnij w punkt by go edytować, przytrzymaj Alt i naciśnij by dodać nowy punkt" "lineEditor_nothingSelected": "Naciśnij w punkt by go edytować, przytrzymaj Alt i naciśnij by dodać nowy punkt"
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "Nie można pokazać podglądu", "cannotShowPreview": "",
"canvasTooBig": "Płótno może być za duże.", "canvasTooBig": "",
"canvasTooBigTip": "Wskazówka: spróbuj nieco zbliżyć najdalej wysunięte elementy." "canvasTooBigTip": ""
}, },
"errorSplash": { "errorSplash": {
"headingMain_pre": "Wystąpił błąd. Spróbuj ", "headingMain_pre": "Wystąpił błąd. Spróbuj ",
@@ -214,22 +213,22 @@
"textNewLine": "Dodaj nową linię (tekst)", "textNewLine": "Dodaj nową linię (tekst)",
"textFinish": "Zakończ edycję (tekst)", "textFinish": "Zakończ edycję (tekst)",
"zoomToFit": "Powiększ, aby wyświetlić wszystkie elementy", "zoomToFit": "Powiększ, aby wyświetlić wszystkie elementy",
"zoomToSelection": "Przybliż zaznaczenie", "zoomToSelection": "",
"preventBinding": "Zablokuj przywiązanie strzałek do obiektu" "preventBinding": "Zablokuj przywiązanie strzałek do obiektu"
}, },
"encrypted": { "encrypted": {
"tooltip": "Twoje rysunki są zabezpieczone szyfrowaniem end-to-end, tak więc nawet w Excalidraw nie jesteśmy w stanie zobaczyć tego co tworzysz." "tooltip": "Twoje rysunki są zabezpieczone szyfrowaniem end-to-end, tak więc nawet w Excalidraw nie jesteśmy w stanie zobaczyć tego co tworzysz."
}, },
"stats": { "stats": {
"angle": "Kąt", "angle": "",
"element": "Element", "element": "",
"elements": "Elementy", "elements": "",
"height": "Wysokość", "height": "",
"scene": "Scena", "scene": "",
"selected": "Zaznaczenie", "selected": "",
"storage": "Pamięć", "storage": "",
"title": "Statystyki dla nerdów", "title": "",
"total": "Suma", "total": "",
"width": "Szerokość" "width": ""
} }
} }
-235
View File
@@ -1,235 +0,0 @@
{
"labels": {
"paste": "Colar",
"selectAll": "Selecionar tudo",
"multiSelect": "Adicionar elemento à seleção",
"moveCanvas": "Mover tela",
"cut": "Cortar",
"copy": "Copiar",
"copyAsPng": "Copiar para a área de transferência como PNG",
"copyAsSvg": "Copiar para a área de transferência como SVG",
"bringForward": "Trazer para a frente",
"sendToBack": "Enviar para o fundo",
"bringToFront": "Trazer para o primeiro plano",
"sendBackward": "Enviar para trás",
"delete": "Apagar",
"copyStyles": "Copiar os estilos",
"pasteStyles": "Colar os estilos",
"stroke": "Contorno",
"background": "Fundo",
"fill": "Preenchimento",
"strokeWidth": "Espessura do traço",
"strokeStyle": "Estilo de traço",
"strokeStyle_solid": "Sólido",
"strokeStyle_dashed": "Tracejado",
"strokeStyle_dotted": "Pontilhado",
"sloppiness": "Precisão do traço",
"opacity": "Opacidade",
"textAlign": "Alinhamento do texto",
"edges": "Arestas",
"sharp": "Pontudo",
"round": "Arredondado",
"arrowheads": "Pontas",
"arrowhead_none": "Nenhuma",
"arrowhead_arrow": "Flecha",
"arrowhead_bar": "Barra",
"arrowhead_dot": "Ponto",
"fontSize": "Tamanho da fonte",
"fontFamily": "Família da fonte",
"onlySelected": "Somente a seleção",
"withBackground": "Com fundo",
"exportEmbedScene": "Incorporar a cena no arquivo exportado",
"exportEmbedScene_details": "Os dados da cena serão salvos no arquivo PNG/SVG exportado para que a cena possa ser restaurada.\nIrá aumentar o tamanho do arquivo exportado.",
"addWatermark": "Adicionar \"Feito com Excalidraw\"",
"handDrawn": "Manuscrito",
"normal": "Normal",
"code": "Código",
"small": "Pequeno",
"medium": "Médio",
"large": "Grande",
"veryLarge": "Muito grande",
"solid": "Sólido",
"hachure": "Hachura",
"crossHatch": "Hachura cruzada",
"thin": "Fino",
"bold": "Espesso",
"left": "Esquerda",
"center": "Centralizar",
"right": "Direita",
"extraBold": "Muito espesso",
"architect": "Arquiteto",
"artist": "Artista",
"cartoonist": "Cartunista",
"fileTitle": "Título do arquivo",
"colorPicker": "Seletor de cores",
"canvasBackground": "Fundo da tela",
"drawingCanvas": "Tela de desenho",
"layers": "Camadas",
"actions": "Ações",
"language": "Idioma",
"createRoom": "Compartilhar uma sessão de colaboração ao vivo",
"duplicateSelection": "Duplicar",
"untitled": "Sem título",
"name": "Nome",
"yourName": "Seu nome",
"madeWithExcalidraw": "Feito com Excalidraw",
"group": "Agrupar seleção",
"ungroup": "Desagrupar seleção",
"collaborators": "Colaboradores",
"gridMode": "Modo grade",
"addToLibrary": "Adicionar à biblioteca",
"removeFromLibrary": "Remover da biblioteca",
"libraryLoadingMessage": "Carregando biblioteca...",
"libraries": "Procurar bibliotecas",
"loadingScene": "Carregando cena...",
"align": "Alinhamento",
"alignTop": "Alinhar ao topo",
"alignBottom": "Alinhar embaixo",
"alignLeft": "Alinhar à esquerda",
"alignRight": "Alinhar à direita",
"centerVertically": "Centralizar verticalmente",
"centerHorizontally": "Centralizar horizontalmente",
"distributeHorizontally": "Distribuir horizontalmente",
"distributeVertically": "Distribuir verticalmente"
},
"buttons": {
"clearReset": "Limpar o canvas e redefinir a cor de fundo",
"export": "Exportar",
"exportToPng": "Exportar em PNG",
"exportToSvg": "Exportar em SVG",
"copyToClipboard": "Copiar para o clipboard",
"copyPngToClipboard": "Copiar PNG para área de transferência",
"scale": "Escala",
"save": "Salvar",
"saveAs": "Salvar como",
"load": "Carregar",
"getShareableLink": "Obter um link de compartilhamento",
"close": "Fechar",
"selectLanguage": "Selecionar idioma",
"scrollBackToContent": "Voltar para o conteúdo",
"zoomIn": "Aumentar zoom",
"zoomOut": "Diminuir zoom",
"resetZoom": "Redefinir zoom",
"menu": "Menu",
"done": "Concluído",
"edit": "Editar",
"undo": "Desfazer",
"redo": "Refazer",
"roomDialog": "Iniciar colaboração ao vivo",
"createNewRoom": "Criar nova sala",
"fullScreen": "Tela cheia",
"darkMode": "Modo escuro",
"lightMode": "Modo claro",
"zenMode": "Modo Zen",
"exitZenMode": "Sair do modo zen"
},
"alerts": {
"clearReset": "Isto irá limpar toda a tela. Você tem certeza?",
"couldNotCreateShareableLink": "Não foi possível criar um link de compartilhamento.",
"couldNotCreateShareableLinkTooBig": "Não foi possível criar um link compartilhável: a cena é muito grande",
"couldNotLoadInvalidFile": "Não foi possível carregar o arquivo inválido",
"importBackendFailed": "A importação do servidor falhou.",
"cannotExportEmptyCanvas": "Não é possível exportar um canvas vazio.",
"couldNotCopyToClipboard": "Não foi possível copiar para a área de transferência. Experimente usando o navegador Chrome.",
"decryptFailed": "Não foi possível descriptografar os dados.",
"uploadedSecurly": "O upload foi protegido com criptografia de ponta a ponta, o que significa que o servidor do Excalidraw e terceiros não podem ler o conteúdo.",
"loadSceneOverridePrompt": "Carregar um desenho externo substituirá o seu conteúdo existente. Deseja continuar?",
"errorLoadingLibrary": "Houve um erro ao carregar a biblioteca de terceiros.",
"confirmAddLibrary": "Isso adicionará {{numShapes}} forma(s) à sua biblioteca. Tem certeza?",
"imageDoesNotContainScene": "A importação de imagens não é suportada no momento.\n\nVocê deseja importar uma cena? Esta imagem parece não conter dados de cena. Você ativou isto durante a exportação?",
"cannotRestoreFromImage": "Não foi possível restaurar a cena deste arquivo de imagem"
},
"toolBar": {
"selection": "Seleção",
"draw": "Desenho livre",
"rectangle": "Retângulo",
"diamond": "Losango",
"ellipse": "Elipse",
"arrow": "Flecha",
"line": "Linha",
"text": "Texto",
"library": "Biblioteca",
"lock": "Manter ativa a ferramenta selecionada após desenhar"
},
"headings": {
"canvasActions": "Ações da tela",
"selectedShapeActions": "Ações das formas selecionadas",
"shapes": "Formas"
},
"hints": {
"linearElement": "Clique para iniciar vários pontos, arraste para uma única linha",
"freeDraw": "Toque e arraste, solte quando terminar",
"text": "Dica: você também pode adicionar texto clicando duas vezes em qualquer lugar com a ferramenta de seleção",
"linearElementMulti": "Clique no último ponto ou pressione Escape ou Enter para terminar",
"lockAngle": "Você pode restringir o ângulo segurando o SHIFT",
"resize": "Você pode restringir proporções segurando SHIFT enquanto redimensiona,\nsegure ALT para redimensionar do centro",
"rotate": "Você pode restringir os ângulos segurando SHIFT enquanto gira",
"lineEditor_info": "Clique duas vezes ou pressione Enter para editar os pontos",
"lineEditor_pointSelected": "Pressione Deletar para remover o ponto, CtrlOuCmd+D para duplicar ou arraste para mover",
"lineEditor_nothingSelected": "Selecione um ponto para mover ou remover, ou segure Alt e clique para adicionar novos pontos"
},
"canvasError": {
"cannotShowPreview": "Não é possível mostrar pré-visualização",
"canvasTooBig": "A tela pode ser muito grande.",
"canvasTooBigTip": "Dica: tente aproximar um pouco os elementos mais distantes."
},
"errorSplash": {
"headingMain_pre": "Foi encontrado um erro. Tente ",
"headingMain_button": "recarregar a página.",
"clearCanvasMessage": "Se recarregar a página não funcionar, tente ",
"clearCanvasMessage_button": "limpando a tela.",
"clearCanvasCaveat": " Isso resultará em perda de trabalho ",
"trackedToSentry_pre": "O erro com o identificador ",
"trackedToSentry_post": " foi rastreado no nosso sistema.",
"openIssueMessage_pre": "Fomos muito cautelosos para não incluir suas informações de cena no erro. Se sua cena não for privada, por favor, considere seguir nosso ",
"openIssueMessage_button": "rastreador de bugs.",
"openIssueMessage_post": " Por favor, inclua informações abaixo, copiando e colando para a issue do GitHub.",
"sceneContent": "Conteúdo da cena:"
},
"roomDialog": {
"desc_intro": "Você pode convidar pessoas para sua cena atual para colaborar com você.",
"desc_privacy": "Não se preocupe, a sessão usa criptografia de ponta a ponta; portanto, o que você desenhar permanecerá privado. Nem mesmo nosso servidor poderá ver o que você cria.",
"button_startSession": "Iniciar sessão",
"button_stopSession": "Parar sessão",
"desc_inProgressIntro": "A sessão de colaboração ao vivo está agora em andamento.",
"desc_shareLink": "Compartilhe este link com qualquer pessoa com quem você queira colaborar:",
"desc_exitSession": "Interrompendo a sessão você irá se desconectar da sala, mas você poderá continuar trabalhando com a cena localmente. Observe que isso não afetará outras pessoas, e elas ainda poderão colaborar em suas versões."
},
"errorDialog": {
"title": "Erro"
},
"shortcutsDialog": {
"title": "Atalhos de teclado",
"shapes": "Formas",
"or": "ou",
"click": "clicar",
"drag": "arrastar",
"curvedArrow": "Seta curva",
"curvedLine": "Linha curva",
"editor": "Editor",
"view": "Visualizar",
"blog": "Leia o nosso blog",
"howto": "Siga os nossos guias",
"github": "Encontrou algum problema? Nos informe",
"textNewLine": "Adicionar nova linha (texto)",
"textFinish": "Finalizar edição (texto)",
"zoomToFit": "Ajustar para caber todos os elementos",
"zoomToSelection": "Ampliar a seleção",
"preventBinding": "Prevenir fixação de seta"
},
"encrypted": {
"tooltip": "Seus desenhos são criptografados de ponta a ponta, então os servidores do Excalidraw nunca os verão."
},
"stats": {
"angle": "Ângulo",
"element": "Elemento",
"elements": "Elementos",
"height": "Altura",
"scene": "Cena",
"selected": "Selecionado",
"storage": "Armazenamento",
"title": "Estatísticas para nerds",
"total": "Total",
"width": "Largura"
}
}
+38 -39
View File
@@ -4,7 +4,7 @@
"selectAll": "Selecionar tudo", "selectAll": "Selecionar tudo",
"multiSelect": "Adicionar elemento à seleção", "multiSelect": "Adicionar elemento à seleção",
"moveCanvas": "Mover tela", "moveCanvas": "Mover tela",
"cut": "Cortar", "cut": "",
"copy": "Copiar", "copy": "Copiar",
"copyAsPng": "Copiar para a área de transferência como PNG", "copyAsPng": "Copiar para a área de transferência como PNG",
"copyAsSvg": "Copiar para a área de transferência como SVG", "copyAsSvg": "Copiar para a área de transferência como SVG",
@@ -29,11 +29,11 @@
"edges": "Arestas", "edges": "Arestas",
"sharp": "Aguçado", "sharp": "Aguçado",
"round": "Redondo", "round": "Redondo",
"arrowheads": "Pontas", "arrowheads": "",
"arrowhead_none": "Nenhuma", "arrowhead_none": "",
"arrowhead_arrow": "Seta", "arrowhead_arrow": "",
"arrowhead_bar": "Barra", "arrowhead_bar": "",
"arrowhead_dot": "Ponto", "arrowhead_dot": "",
"fontSize": "Tamanho da fonte", "fontSize": "Tamanho da fonte",
"fontFamily": "Família da fontes", "fontFamily": "Família da fontes",
"onlySelected": "Somente a seleção", "onlySelected": "Somente a seleção",
@@ -60,7 +60,7 @@
"architect": "Arquitecto", "architect": "Arquitecto",
"artist": "Artista", "artist": "Artista",
"cartoonist": "Caricaturista", "cartoonist": "Caricaturista",
"fileTitle": "Título do ficheiro", "fileTitle": "",
"colorPicker": "Seletor de cores", "colorPicker": "Seletor de cores",
"canvasBackground": "Fundo da tela", "canvasBackground": "Fundo da tela",
"drawingCanvas": "Tela de desenho", "drawingCanvas": "Tela de desenho",
@@ -69,28 +69,29 @@
"language": "Idioma", "language": "Idioma",
"createRoom": "Compartilhar uma sessão de colaboração ao vivo", "createRoom": "Compartilhar uma sessão de colaboração ao vivo",
"duplicateSelection": "Duplicar", "duplicateSelection": "Duplicar",
"untitled": "Sem título", "untitled": "",
"name": "Nome", "name": "Nome",
"yourName": "Seu nome", "yourName": "Seu nome",
"madeWithExcalidraw": "Feito com Excalidraw", "madeWithExcalidraw": "Feito com Excalidraw",
"group": "Agrupar seleção", "group": "Agrupar seleção",
"ungroup": "Desagrupar seleção", "ungroup": "Desagrupar seleção",
"collaborators": "Colaboradores", "collaborators": "Colaboradores",
"gridMode": "Modo grade", "toggleGridMode": "Alternar modo de grade",
"toggleStats": "",
"addToLibrary": "Adicionar à biblioteca", "addToLibrary": "Adicionar à biblioteca",
"removeFromLibrary": "Remover da biblioteca", "removeFromLibrary": "Remover da biblioteca",
"libraryLoadingMessage": "Carregando biblioteca...", "libraryLoadingMessage": "Carregando biblioteca...",
"libraries": "Procurar bibliotecas", "libraries": "",
"loadingScene": "Carregando cena...", "loadingScene": "Carregando cena...",
"align": "Alinhamento", "align": "",
"alignTop": "Alinhar ao topo", "alignTop": "",
"alignBottom": "Alinhar ao fundo", "alignBottom": "",
"alignLeft": "Alinhar à esquerda", "alignLeft": "",
"alignRight": "Alinhar à direita", "alignRight": "",
"centerVertically": "Centralizar verticalmente", "centerVertically": "",
"centerHorizontally": "Centralizar horizontalmente", "centerHorizontally": "",
"distributeHorizontally": "Distribuir horizontalmente", "distributeHorizontally": "",
"distributeVertically": "Distribuir verticalmente" "distributeVertically": ""
}, },
"buttons": { "buttons": {
"clearReset": "Limpar o canvas e redefinir a cor de fundo", "clearReset": "Limpar o canvas e redefinir a cor de fundo",
@@ -117,10 +118,9 @@
"redo": "Refazer", "redo": "Refazer",
"roomDialog": "Iniciar colaboração ao vivo", "roomDialog": "Iniciar colaboração ao vivo",
"createNewRoom": "Criar nova sala", "createNewRoom": "Criar nova sala",
"fullScreen": "Tela cheia", "toggleFullScreen": "Alternar tela cheia",
"darkMode": "Modo escuro", "toggleDarkMode": "Alternar modo escuro",
"lightMode": "Modo claro", "toggleZenMode": "Alternar modo zen",
"zenMode": "Modo Zen",
"exitZenMode": "Sair do modo zen" "exitZenMode": "Sair do modo zen"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Carregar um desenho externo substituirá o seu conteúdo existente. Deseja continuar?", "loadSceneOverridePrompt": "Carregar um desenho externo substituirá o seu conteúdo existente. Deseja continuar?",
"errorLoadingLibrary": "Houve um erro ao carregar a biblioteca de terceiros.", "errorLoadingLibrary": "Houve um erro ao carregar a biblioteca de terceiros.",
"confirmAddLibrary": "Isso adicionará {{numShapes}} forma(s) à sua biblioteca. Tem certeza?", "confirmAddLibrary": "Isso adicionará {{numShapes}} forma(s) à sua biblioteca. Tem certeza?",
"imageDoesNotContainScene": "A importação de imagens não é suportada no momento.\n\nVocê deseja importar uma cena? Esta imagem parece não conter dados de cena. Você ativou isto durante a exportação?", "imageDoesNotContainScene": "O arquivo de imagem não contém dados de cena. Você ativou durante a exportação?",
"cannotRestoreFromImage": "Não foi possível restaurar a cena deste arquivo de imagem" "cannotRestoreFromImage": "Não foi possível restaurar a cena deste arquivo de imagem"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Toque e arraste, solte quando terminar", "freeDraw": "Toque e arraste, solte quando terminar",
"text": "Dica: você também pode adicionar texto clicando duas vezes em qualquer lugar com a ferramenta de seleção", "text": "Dica: você também pode adicionar texto clicando duas vezes em qualquer lugar com a ferramenta de seleção",
"linearElementMulti": "Clique no último ponto ou pressione Escape ou Enter para terminar", "linearElementMulti": "Clique no último ponto ou pressione Escape ou Enter para terminar",
"lockAngle": "Você pode restringir o ângulo segurando SHIFT",
"resize": "Você pode restringir proporções segurando SHIFT enquanto redimensiona,\nsegure ALT para redimensionar do centro", "resize": "Você pode restringir proporções segurando SHIFT enquanto redimensiona,\nsegure ALT para redimensionar do centro",
"rotate": "Você pode restringir os ângulos segurando SHIFT enquanto gira", "rotate": "Você pode restringir os ângulos segurando SHIFT enquanto gira",
"lineEditor_info": "Clique duas vezes ou pressione Enter para editar os pontos", "lineEditor_info": "Clique duas vezes ou pressione Enter para editar os pontos",
@@ -169,9 +168,9 @@
"lineEditor_nothingSelected": "Selecione um ponto para mover ou remover, ou segure Alt e clique para adicionar novos pontos" "lineEditor_nothingSelected": "Selecione um ponto para mover ou remover, ou segure Alt e clique para adicionar novos pontos"
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "Não é possível mostrar pré-visualização", "cannotShowPreview": "",
"canvasTooBig": "A tela pode ser muito grande.", "canvasTooBig": "",
"canvasTooBigTip": "Dica: tente aproximar um pouco os elementos mais distantes." "canvasTooBigTip": ""
}, },
"errorSplash": { "errorSplash": {
"headingMain_pre": "Foi encontrado um erro. Tente ", "headingMain_pre": "Foi encontrado um erro. Tente ",
@@ -214,22 +213,22 @@
"textNewLine": "Adicionar nova linha (texto)", "textNewLine": "Adicionar nova linha (texto)",
"textFinish": "Finalizar edição (texto)", "textFinish": "Finalizar edição (texto)",
"zoomToFit": "Ajustar para caber todos os elementos", "zoomToFit": "Ajustar para caber todos os elementos",
"zoomToSelection": "Ampliar a seleção", "zoomToSelection": "",
"preventBinding": "Prevenir fixação de seta" "preventBinding": "Prevenir fixação de seta"
}, },
"encrypted": { "encrypted": {
"tooltip": "Seus desenhos são criptografados de ponta a ponta, então os servidores do Excalidraw nunca os verão." "tooltip": "Seus desenhos são criptografados de ponta a ponta, então os servidores do Excalidraw nunca os verão."
}, },
"stats": { "stats": {
"angle": "Ângulo", "angle": "",
"element": "Elemento", "element": "",
"elements": "Elementos", "elements": "",
"height": "Altura", "height": "",
"scene": "Cena", "scene": "",
"selected": "Selecionado", "selected": "",
"storage": "Armazenamento", "storage": "",
"title": "Estatísticas para nerds", "title": "",
"total": "Total", "total": "",
"width": "Largura" "width": ""
} }
} }
+6 -7
View File
@@ -76,7 +76,8 @@
"group": "Grupare selecție", "group": "Grupare selecție",
"ungroup": "Degrupare selecție", "ungroup": "Degrupare selecție",
"collaborators": "Colaboratori", "collaborators": "Colaboratori",
"gridMode": "Mod grilă", "toggleGridMode": "Comută modul grilă",
"toggleStats": "Comută statisticile pentru pasionați",
"addToLibrary": "Adăugare la bibliotecă", "addToLibrary": "Adăugare la bibliotecă",
"removeFromLibrary": "Eliminare din bibliotecă", "removeFromLibrary": "Eliminare din bibliotecă",
"libraryLoadingMessage": "Se încarcă biblioteca...", "libraryLoadingMessage": "Se încarcă biblioteca...",
@@ -117,10 +118,9 @@
"redo": "Refacere", "redo": "Refacere",
"roomDialog": "Colaborare în direct", "roomDialog": "Colaborare în direct",
"createNewRoom": "Creare cameră nouă", "createNewRoom": "Creare cameră nouă",
"fullScreen": "Ecran complet", "toggleFullScreen": "Comută modul ecran complet",
"darkMode": "Mod întunecat", "toggleDarkMode": "Comută modul întunecat",
"lightMode": "Mod luminos", "toggleZenMode": "Comută modul zen",
"zenMode": "Mod zen",
"exitZenMode": "Ieșire din modul zen" "exitZenMode": "Ieșire din modul zen"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Încărcarea desenului extern va înlocui conținutul existent. Dorești să continui?", "loadSceneOverridePrompt": "Încărcarea desenului extern va înlocui conținutul existent. Dorești să continui?",
"errorLoadingLibrary": "A apărut o eroare la încărcarea bibliotecii terțe.", "errorLoadingLibrary": "A apărut o eroare la încărcarea bibliotecii terțe.",
"confirmAddLibrary": "Această acțiune va adăuga {{numShapes}} formă(e) la biblioteca ta. Confirmi?", "confirmAddLibrary": "Această acțiune va adăuga {{numShapes}} formă(e) la biblioteca ta. Confirmi?",
"imageDoesNotContainScene": "Importarea imaginilor nu este acceptată în acest moment.\n\nVoiai să imporți o scenă? Această imagine nu pare să conțină date de scenă. Ai activat această opțiune pe durata exportării?", "imageDoesNotContainScene": "Fișierul de imagine nu conține date de scenă. Ai activat această opțiune pe durata exportării?",
"cannotRestoreFromImage": "Scena nu a putut fi restaurată din acest fișier de imagine" "cannotRestoreFromImage": "Scena nu a putut fi restaurată din acest fișier de imagine"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Dă clic pe pânză și glisează cursorul, apoi eliberează-l când ai terminat", "freeDraw": "Dă clic pe pânză și glisează cursorul, apoi eliberează-l când ai terminat",
"text": "Sfat: poți adăuga text și dând dublu clic oriunde cu instrumentul de selecție", "text": "Sfat: poți adăuga text și dând dublu clic oriunde cu instrumentul de selecție",
"linearElementMulti": "Dă clic pe ultimul punct sau apasă tasta Escape sau tasta Enter pentru a termina", "linearElementMulti": "Dă clic pe ultimul punct sau apasă tasta Escape sau tasta Enter pentru a termina",
"lockAngle": "Poți constrânge unghiul prin ținerea apăsată a tastei SHIFT",
"resize": "Poți constrânge proporțiile, ținând apăsată tasta SHIFT în timp ce redimensionezi,\nține apăsată tasta ALT pentru a redimensiona de la centru", "resize": "Poți constrânge proporțiile, ținând apăsată tasta SHIFT în timp ce redimensionezi,\nține apăsată tasta ALT pentru a redimensiona de la centru",
"rotate": "Poți constrânge unghiurile, ținând apăsată tasta SHIFT în timp ce rotești", "rotate": "Poți constrânge unghiurile, ținând apăsată tasta SHIFT în timp ce rotești",
"lineEditor_info": "Dă dublu clic sau apasă tasta Enter pentru a edita punctele", "lineEditor_info": "Dă dublu clic sau apasă tasta Enter pentru a edita punctele",
+47 -48
View File
@@ -2,9 +2,9 @@
"labels": { "labels": {
"paste": "Вставить", "paste": "Вставить",
"selectAll": "Выбрать все", "selectAll": "Выбрать все",
"multiSelect": "Добавить элемент в выделенный фрагмент", "multiSelect": "Добавить элемент к выбору",
"moveCanvas": "Переместить холст", "moveCanvas": "Переместить холст",
"cut": "Вырезать", "cut": "",
"copy": "Копировать", "copy": "Копировать",
"copyAsPng": "Скопировать в буфер обмена как PNG", "copyAsPng": "Скопировать в буфер обмена как PNG",
"copyAsSvg": "Скопировать в буфер обмена как SVG", "copyAsSvg": "Скопировать в буфер обмена как SVG",
@@ -29,17 +29,17 @@
"edges": "Края", "edges": "Края",
"sharp": "Острые", "sharp": "Острые",
"round": "Скругленные", "round": "Скругленные",
"arrowheads": "Стрелка", "arrowheads": "",
"arrowhead_none": "Без стрелки", "arrowhead_none": "",
"arrowhead_arrow": "Cтрелка", "arrowhead_arrow": "Cтрелка",
"arrowhead_bar": "Столбец", "arrowhead_bar": "",
"arrowhead_dot": "Точка", "arrowhead_dot": "Точка",
"fontSize": "Размер шрифта", "fontSize": "Размер шрифта",
"fontFamily": "Семейство шрифтов", "fontFamily": "Семейство шрифтов",
"onlySelected": "Только выбранные", "onlySelected": "Только выбранные",
"withBackground": "С фоном", "withBackground": "С фоном",
"exportEmbedScene": "Встроить информацию о сцене в экспортируемый файл", "exportEmbedScene": "",
"exportEmbedScene_details": "Сцена будет сохранена в PNG/SVG файл так, чтобы всю сцену можно будет восстановить из этого файла. Это увеличит размер файла.", "exportEmbedScene_details": "",
"addWatermark": "Добавить \"Сделано с Excalidraw\"", "addWatermark": "Добавить \"Сделано с Excalidraw\"",
"handDrawn": "Нарисованный от руки", "handDrawn": "Нарисованный от руки",
"normal": "Обычный", "normal": "Обычный",
@@ -75,22 +75,23 @@
"madeWithExcalidraw": "Сделано в Excalidraw", "madeWithExcalidraw": "Сделано в Excalidraw",
"group": "Сгруппировать выделение", "group": "Сгруппировать выделение",
"ungroup": "Разделить выделение", "ungroup": "Разделить выделение",
"collaborators": "Участники", "collaborators": "Сотрудники",
"gridMode": "", "toggleGridMode": "Переключить режим сетки",
"toggleStats": "",
"addToLibrary": "Добавить в библиотеку", "addToLibrary": "Добавить в библиотеку",
"removeFromLibrary": "Удалить из библиотеки", "removeFromLibrary": "Удалить из библиотеки",
"libraryLoadingMessage": "Загрузка библиотеки...", "libraryLoadingMessage": "Загрузка библиотеки...",
"libraries": "Просмотреть библиотеки", "libraries": "",
"loadingScene": "Загрузка сцены...", "loadingScene": "Загрузка сцены...",
"align": "Выровнять", "align": "",
"alignTop": "Выровнять по верхнему краю", "alignTop": "",
"alignBottom": "Выровнять по нижнему краю", "alignBottom": "",
"alignLeft": "Выровнять по левому краю", "alignLeft": "",
"alignRight": "Выровнять по правому краю", "alignRight": "",
"centerVertically": "Центрировать по вертикали", "centerVertically": "",
"centerHorizontally": "Центрировать по горизонтали", "centerHorizontally": "",
"distributeHorizontally": "Распределить по горизонтали", "distributeHorizontally": "",
"distributeVertically": "Распределить по вертикали" "distributeVertically": ""
}, },
"buttons": { "buttons": {
"clearReset": "Очистить холст и сбросить цвет фона", "clearReset": "Очистить холст и сбросить цвет фона",
@@ -99,7 +100,7 @@
"exportToSvg": "Экспорт в SVG", "exportToSvg": "Экспорт в SVG",
"copyToClipboard": "Скопировать в буфер обмена", "copyToClipboard": "Скопировать в буфер обмена",
"copyPngToClipboard": "Скопировать PNG в буфер обмена", "copyPngToClipboard": "Скопировать PNG в буфер обмена",
"scale": "Масштаб", "scale": "Шкала",
"save": "Сохранить", "save": "Сохранить",
"saveAs": "Сохранить как", "saveAs": "Сохранить как",
"load": "Загрузить", "load": "Загрузить",
@@ -117,27 +118,26 @@
"redo": "Шаг вперед", "redo": "Шаг вперед",
"roomDialog": "Начать совместную работу", "roomDialog": "Начать совместную работу",
"createNewRoom": "Создать новую комнату", "createNewRoom": "Создать новую комнату",
"fullScreen": олный экран", "toggleFullScreen": ереключить полноэкранный режим",
"darkMode": "", "toggleDarkMode": "Переключить тёмную тему",
"lightMode": "", "toggleZenMode": "Переключить режим концентрации внимания",
"zenMode": "",
"exitZenMode": "Выключить режим концентрации внимания" "exitZenMode": "Выключить режим концентрации внимания"
}, },
"alerts": { "alerts": {
"clearReset": "Это очистит весь холст. Вы уверены?", "clearReset": "Это очистит весь холст. Вы уверены?",
"couldNotCreateShareableLink": "Не удалось создать общедоступную ссылку.", "couldNotCreateShareableLink": "Не удалось создать общедоступную ссылку.",
"couldNotCreateShareableLinkTooBig": "Нельзя создать ссылку, чтобы поделиться. Сцена слишком большая", "couldNotCreateShareableLinkTooBig": "",
"couldNotLoadInvalidFile": "Не удалось загрузить недопустимый файл", "couldNotLoadInvalidFile": "Не удалось загрузить недопустимый файл",
"importBackendFailed": "Не удалось импортировать из бэкэнда.", "importBackendFailed": "Не удалось импортировать из бэкэнда.",
"cannotExportEmptyCanvas": "Не может экспортировать пустой холст.", "cannotExportEmptyCanvas": "Не может экспортировать пустой холст.",
"couldNotCopyToClipboard": "Не удалось скопировать в буфер обмена. Попробуйте использовать веб-браузер Chrome.", "couldNotCopyToClipboard": "Не удалось скопировать в буфер обмена. Попробуйте использовать веб-браузер Chrome.",
"decryptFailed": "Не удалось расшифровать данные.", "decryptFailed": "Не удалось декодировать данные.",
"uploadedSecurly": "Загружаемые данные защищена сквозным шифрованием, что означает, что сервер Excalidraw и третьи стороны не могут прочитать содержимое.", "uploadedSecurly": "Загружаемые данные защищена сквозным шифрованием, что означает, что сервер Excalidraw и третьи стороны не могут прочитать содержимое.",
"loadSceneOverridePrompt": "Загрузка рисунка приведёт к замене имеющегося содержимого. Вы хотите продолжить?", "loadSceneOverridePrompt": "",
"errorLoadingLibrary": "Произошла ошибка при загрузке сторонней библиотеки.", "errorLoadingLibrary": "",
"confirmAddLibrary": "Будет добавлено {{numShapes}} фигур в вашу библиотеку. Продолжить?", "confirmAddLibrary": "",
"imageDoesNotContainScene": "", "imageDoesNotContainScene": "",
"cannotRestoreFromImage": "Сцена не может быть восстановлена из этого изображения" "cannotRestoreFromImage": ""
}, },
"toolBar": { "toolBar": {
"selection": "Выделение области", "selection": "Выделение области",
@@ -159,19 +159,18 @@
"hints": { "hints": {
"linearElement": "Нажмите, чтобы начать несколько точек, перетащите для одной линии", "linearElement": "Нажмите, чтобы начать несколько точек, перетащите для одной линии",
"freeDraw": "Нажмите и перетаскивайте, отпустите по завершении", "freeDraw": "Нажмите и перетаскивайте, отпустите по завершении",
"text": "Совет: при выбранном инструменте выделения дважды щёлкните в любом месте, чтобы добавить текст", "text": "",
"linearElementMulti": "Кликните на последней точке или нажмите Escape или Enter чтобы закончить", "linearElementMulti": "Кликните на последней точке или нажмите Escape или Enter чтобы закончить",
"lockAngle": "",
"resize": "Вы можете ограничить пропорции, удерживая SHIFT во время изменения размеров,\nудерживайте ALT чтобы изменить размер из центра", "resize": "Вы можете ограничить пропорции, удерживая SHIFT во время изменения размеров,\nудерживайте ALT чтобы изменить размер из центра",
"rotate": "Вы можете ограничить углы, удерживая SHIFT во время вращения", "rotate": "Вы можете ограничить углы, удерживая SHIFT во время вращения",
"lineEditor_info": "Дважды кликните или нажмите Enter, чтобы редактировать точки", "lineEditor_info": "Дважды кликните или нажмите Enter, чтобы редактировать точки",
"lineEditor_pointSelected": "Нажмите Delete для удаления точки, Ctrl или Cmd + D для дублирования, перетащите для перемещения", "lineEditor_pointSelected": "",
"lineEditor_nothingSelected": "Выберите точку для перемещения или удаления. Alt + клик чтобы добавить новые точки" "lineEditor_nothingSelected": ""
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "Не удается отобразить предпросмотр", "cannotShowPreview": "",
"canvasTooBig": "Сцена слишком большая.", "canvasTooBig": "",
"canvasTooBigTip": "Совет: попробуйте сблизить элементы рисунка." "canvasTooBigTip": ""
}, },
"errorSplash": { "errorSplash": {
"headingMain_pre": "Возникла ошибка. Попробуйте ", "headingMain_pre": "Возникла ошибка. Попробуйте ",
@@ -189,11 +188,11 @@
"roomDialog": { "roomDialog": {
"desc_intro": "Вы можете пригласить людей в текущую сцену для совместной работы.", "desc_intro": "Вы можете пригласить людей в текущую сцену для совместной работы.",
"desc_privacy": "Не беспокойтесь, сессия использует сквозное шифрование, поэтому всё что вы нарисуете останется приватным. Ваша информация не будет доступна даже на наших серверах.", "desc_privacy": "Не беспокойтесь, сессия использует сквозное шифрование, поэтому всё что вы нарисуете останется приватным. Ваша информация не будет доступна даже на наших серверах.",
"button_startSession": "Начать сеанс", "button_startSession": "Начать сессию",
"button_stopSession": "Завершить сеанс", "button_stopSession": "Закончить сессию",
"desc_inProgressIntro": "Совместная сессия теперь активна.", "desc_inProgressIntro": "Совместная сессия теперь активна.",
"desc_shareLink": "Поделитесь этой ссылкой со всеми участниками:", "desc_shareLink": "Поделитесь этой ссылкой со всеми участниками:",
"desc_exitSession": "Завершив сеанс, вы выйдете из комнаты, но сможете продолжить работать с документом локально. Это не повлияет на работу других пользователей — они смогут продолжить совместную работу с их версией документа." "desc_exitSession": ""
}, },
"errorDialog": { "errorDialog": {
"title": "Ошибка" "title": "Ошибка"
@@ -213,23 +212,23 @@
"github": "Нашли проблему? Отправьте", "github": "Нашли проблему? Отправьте",
"textNewLine": "Добавить новую строку (текст)", "textNewLine": "Добавить новую строку (текст)",
"textFinish": "Закончить редактирование (текст)", "textFinish": "Закончить редактирование (текст)",
"zoomToFit": "Отмастштабировать, чтобы поместились все элементы", "zoomToFit": "",
"zoomToSelection": "Перейти к выделенному", "zoomToSelection": "",
"preventBinding": "Предотвратить привязку стрелок" "preventBinding": "Предотвратить привязку стрелок"
}, },
"encrypted": { "encrypted": {
"tooltip": "Ваши данные защищены сквозным (End-to-end) шифрованием. Серверы Excalidraw никогда не получат доступ к ним." "tooltip": ""
}, },
"stats": { "stats": {
"angle": "Угол", "angle": "Угол",
"element": "Элемент", "element": "Элемент",
"elements": "Элементы", "elements": "Элементы",
"height": "Высота", "height": "Высота",
"scene": "Сцены", "scene": "",
"selected": "Выбран", "selected": "",
"storage": "Хранилище", "storage": "",
"title": "Статистика для ботаников", "title": "",
"total": "Всего", "total": "",
"width": "Ширина" "width": "Ширина"
} }
} }
+6 -7
View File
@@ -76,7 +76,8 @@
"group": "Zoskupiť", "group": "Zoskupiť",
"ungroup": "Zrušiť zoskupenie", "ungroup": "Zrušiť zoskupenie",
"collaborators": "Spolupracovníci", "collaborators": "Spolupracovníci",
"gridMode": "Režim mriežky", "toggleGridMode": "Prepnúť mriežku",
"toggleStats": "Prepnúť štatistiky",
"addToLibrary": "Pridať do knižnice", "addToLibrary": "Pridať do knižnice",
"removeFromLibrary": "Odstrániť z knižnice", "removeFromLibrary": "Odstrániť z knižnice",
"libraryLoadingMessage": "Načítavanie knižnice...", "libraryLoadingMessage": "Načítavanie knižnice...",
@@ -117,10 +118,9 @@
"redo": "Znova", "redo": "Znova",
"roomDialog": "Začať živú spoluprácu", "roomDialog": "Začať živú spoluprácu",
"createNewRoom": "Vytvoriť novú miestnosť", "createNewRoom": "Vytvoriť novú miestnosť",
"fullScreen": "Celá obrazovka", "toggleFullScreen": "Prepnúť režim celej obrazovky",
"darkMode": "Tmavý režim", "toggleDarkMode": "Prepnúť tmavý režim",
"lightMode": "Svetlý režim", "toggleZenMode": "Prepnúť režim zen",
"zenMode": "Režim zen",
"exitZenMode": "Zrušiť režim zen" "exitZenMode": "Zrušiť režim zen"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Nahratie externej kresby nahradí existujúci obsah. Prajete si pokračovať?", "loadSceneOverridePrompt": "Nahratie externej kresby nahradí existujúci obsah. Prajete si pokračovať?",
"errorLoadingLibrary": "Nepodarilo sa načítať externú knižnicu.", "errorLoadingLibrary": "Nepodarilo sa načítať externú knižnicu.",
"confirmAddLibrary": "Týmto sa pridá {{numShapes}} tvar(ov) do vašej knižnice. Ste si istí?", "confirmAddLibrary": "Týmto sa pridá {{numShapes}} tvar(ov) do vašej knižnice. Ste si istí?",
"imageDoesNotContainScene": "Importovanie obrázku v tomto momente nie je možné.\n\nChceli ste importovať scénu? Tento obrázok neobsahuje žiadne údaje scény. Povolili ste túto možnosť počas exportovania?", "imageDoesNotContainScene": "Obrázkový súbor neobsahuje údaje scény. Povolili ste ich pri exportovaní?",
"cannotRestoreFromImage": "Nepodarilo sa obnoviť scénu z tohto obrázkového súboru" "cannotRestoreFromImage": "Nepodarilo sa obnoviť scénu z tohto obrázkového súboru"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Kliknite a ťahajte, pustite na ukončenie", "freeDraw": "Kliknite a ťahajte, pustite na ukončenie",
"text": "Tip: text môžete pridať aj dvojklikom kdekoľvek, ak je zvolený nástroj výber", "text": "Tip: text môžete pridať aj dvojklikom kdekoľvek, ak je zvolený nástroj výber",
"linearElementMulti": "Kliknite na počiatočný bod alebo stlačte Escape alebo Enter na ukončenie", "linearElementMulti": "Kliknite na počiatočný bod alebo stlačte Escape alebo Enter na ukončenie",
"lockAngle": "Počas rotácie obmedzíte uhol podržaním SHIFT",
"resize": "Počas zmeny veľkosti zachováte proporcie podržaním SHIFT,\\npodržaním ALT meníte veľkosť so zachovaním stredu", "resize": "Počas zmeny veľkosti zachováte proporcie podržaním SHIFT,\\npodržaním ALT meníte veľkosť so zachovaním stredu",
"rotate": "Počas rotácie obmedzíte uhol podržaním SHIFT", "rotate": "Počas rotácie obmedzíte uhol podržaním SHIFT",
"lineEditor_info": "Použite dvojklik alebo stlačte Enter na editáciu bodov", "lineEditor_info": "Použite dvojklik alebo stlačte Enter na editáciu bodov",
+6 -7
View File
@@ -76,7 +76,8 @@
"group": "Gruppera markering", "group": "Gruppera markering",
"ungroup": "Avgruppera markering", "ungroup": "Avgruppera markering",
"collaborators": "Medarbetare", "collaborators": "Medarbetare",
"gridMode": "Rutnätsläge", "toggleGridMode": "Växla rutnätsläge",
"toggleStats": "Visa/dölj statistik för nördar",
"addToLibrary": "Lägg till i biblioteket", "addToLibrary": "Lägg till i biblioteket",
"removeFromLibrary": "Ta bort från bibliotek", "removeFromLibrary": "Ta bort från bibliotek",
"libraryLoadingMessage": "Laddar bibliotek...", "libraryLoadingMessage": "Laddar bibliotek...",
@@ -117,10 +118,9 @@
"redo": "Gör om", "redo": "Gör om",
"roomDialog": "Starta live-samarbete", "roomDialog": "Starta live-samarbete",
"createNewRoom": "Skapa ett nytt rum", "createNewRoom": "Skapa ett nytt rum",
"fullScreen": "Helskärm", "toggleFullScreen": "Växla fullskärmsläge",
"darkMode": "Mörkt läge", "toggleDarkMode": "Växla mörkt läge",
"lightMode": "Ljust läge", "toggleZenMode": "Växla zen-läge",
"zenMode": "Zen-läge",
"exitZenMode": "Gå ur zen-läge" "exitZenMode": "Gå ur zen-läge"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Laddning av extern skiss kommer att ersätta ditt befintliga innehåll. Vill du fortsätta?", "loadSceneOverridePrompt": "Laddning av extern skiss kommer att ersätta ditt befintliga innehåll. Vill du fortsätta?",
"errorLoadingLibrary": "Fel vid inläsning av tredjeparts bibliotek.", "errorLoadingLibrary": "Fel vid inläsning av tredjeparts bibliotek.",
"confirmAddLibrary": "Detta kommer att lägga till {{numShapes}} form(er) till ditt bibliotek. Är du säker?", "confirmAddLibrary": "Detta kommer att lägga till {{numShapes}} form(er) till ditt bibliotek. Är du säker?",
"imageDoesNotContainScene": "Importering av bilder stöds inte just nu.\n\nVill du importera en skiss? Den här bilden verkar inte innehålla någon skissdata. Har du aktiverat detta under export?", "imageDoesNotContainScene": "Bildfilen innehåller inte skissdata. Har du aktiverat detta under export?",
"cannotRestoreFromImage": "Skiss kunde inte återställas från denna bildfil" "cannotRestoreFromImage": "Skiss kunde inte återställas från denna bildfil"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Klicka och dra, släpp när du är klar", "freeDraw": "Klicka och dra, släpp när du är klar",
"text": "Tips: du kan också lägga till text genom att dubbelklicka var som helst med markeringsverktyget", "text": "Tips: du kan också lägga till text genom att dubbelklicka var som helst med markeringsverktyget",
"linearElementMulti": "Klicka på sista punkten eller tryck Escape eller Enter för att avsluta", "linearElementMulti": "Klicka på sista punkten eller tryck Escape eller Enter för att avsluta",
"lockAngle": "Du kan begränsa vinkeln genom att hålla SKIFT",
"resize": "Du kan behålla proportioner genom att hålla SHIFT medan du ändrar storlek,\nhåller du ALT ändras storlek relativt mitten", "resize": "Du kan behålla proportioner genom att hålla SHIFT medan du ändrar storlek,\nhåller du ALT ändras storlek relativt mitten",
"rotate": "Du kan begränsa vinklar genom att hålla SHIFT medan du roterar", "rotate": "Du kan begränsa vinklar genom att hålla SHIFT medan du roterar",
"lineEditor_info": "Dubbelklicka eller tryck på Enter för att redigera punkter", "lineEditor_info": "Dubbelklicka eller tryck på Enter för att redigera punkter",
+25 -26
View File
@@ -4,7 +4,7 @@
"selectAll": "Tümünü seç", "selectAll": "Tümünü seç",
"multiSelect": "Seçime öge ekle", "multiSelect": "Seçime öge ekle",
"moveCanvas": "Tuvali taşı", "moveCanvas": "Tuvali taşı",
"cut": "Kes", "cut": "",
"copy": "Kopyala", "copy": "Kopyala",
"copyAsPng": "Panoya PNG olarak kopyala", "copyAsPng": "Panoya PNG olarak kopyala",
"copyAsSvg": "Panoya SVG olarak kopyala", "copyAsSvg": "Panoya SVG olarak kopyala",
@@ -37,7 +37,7 @@
"fontSize": "Yazı tipi boyutu", "fontSize": "Yazı tipi boyutu",
"fontFamily": "Yazı tipi ailesi", "fontFamily": "Yazı tipi ailesi",
"onlySelected": "Sadece seçilen", "onlySelected": "Sadece seçilen",
"withBackground": "", "withBackground": "Arka Plan İle Beraber",
"exportEmbedScene": "", "exportEmbedScene": "",
"exportEmbedScene_details": "", "exportEmbedScene_details": "",
"addWatermark": "\"Excalidraw ile yapıldı\" yazısını ekle", "addWatermark": "\"Excalidraw ile yapıldı\" yazısını ekle",
@@ -60,7 +60,7 @@
"architect": "Mimar", "architect": "Mimar",
"artist": "Sanatçı", "artist": "Sanatçı",
"cartoonist": "Karikatürist", "cartoonist": "Karikatürist",
"fileTitle": "Dosya adı", "fileTitle": "",
"colorPicker": "Renk seçici", "colorPicker": "Renk seçici",
"canvasBackground": "Tuval arka planı", "canvasBackground": "Tuval arka planı",
"drawingCanvas": "Çizim tuvali", "drawingCanvas": "Çizim tuvali",
@@ -69,26 +69,27 @@
"language": "Dil", "language": "Dil",
"createRoom": "Ortak çalışma ortamını paylaş", "createRoom": "Ortak çalışma ortamını paylaş",
"duplicateSelection": "Çoğalt", "duplicateSelection": "Çoğalt",
"untitled": "Adsız", "untitled": "",
"name": "İsim", "name": "İsim",
"yourName": "İsminiz", "yourName": "İsminiz",
"madeWithExcalidraw": "Excalidraw ile yapıldı", "madeWithExcalidraw": "Excalidraw ile yapıldı",
"group": "Seçimi grup yap", "group": "Seçimi grup yap",
"ungroup": "Seçilen grubu dağıt", "ungroup": "Seçilen grubu dağıt",
"collaborators": "Ortaklar", "collaborators": "Ortaklar",
"gridMode": "", "toggleGridMode": "Izgara modunu aç",
"toggleStats": "",
"addToLibrary": "Kütüphaneye ekle", "addToLibrary": "Kütüphaneye ekle",
"removeFromLibrary": "Kütüphaneden kaldır", "removeFromLibrary": "Kütüphaneden kaldır",
"libraryLoadingMessage": "Kütüphane yükleniyor...", "libraryLoadingMessage": "Kütüphane yükleniyor...",
"libraries": "", "libraries": "",
"loadingScene": "Çalışma alanı yükleniyor...", "loadingScene": "Çalışma alanı yükleniyor...",
"align": "Hizala", "align": "",
"alignTop": "Yukarı hizala", "alignTop": "",
"alignBottom": "Aşağı hizala", "alignBottom": "",
"alignLeft": "Sola yasla", "alignLeft": "",
"alignRight": "Sağa yasla", "alignRight": "",
"centerVertically": "Dikeyde ortala", "centerVertically": "",
"centerHorizontally": "Yatayda ortala", "centerHorizontally": "",
"distributeHorizontally": "", "distributeHorizontally": "",
"distributeVertically": "" "distributeVertically": ""
}, },
@@ -117,10 +118,9 @@
"redo": "Yeniden yap", "redo": "Yeniden yap",
"roomDialog": "Ortak çalışma ortamı yarat", "roomDialog": "Ortak çalışma ortamı yarat",
"createNewRoom": "Yeni oda oluştur", "createNewRoom": "Yeni oda oluştur",
"fullScreen": "", "toggleFullScreen": "Tam ekranı aç/kapa",
"darkMode": "", "toggleDarkMode": "Karanlık modu aç/kapa",
"lightMode": "", "toggleZenMode": "Zen modunu aç/kapa",
"zenMode": "",
"exitZenMode": "Zen modundan çık" "exitZenMode": "Zen modundan çık"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Harici çizimler yüklemek mevcut olan içeriği değiştirecektir. Devam etmek istiyor musunuz?", "loadSceneOverridePrompt": "Harici çizimler yüklemek mevcut olan içeriği değiştirecektir. Devam etmek istiyor musunuz?",
"errorLoadingLibrary": "Üçüncü taraf kitaplığı yüklerken bir hata oluştu.", "errorLoadingLibrary": "Üçüncü taraf kitaplığı yüklerken bir hata oluştu.",
"confirmAddLibrary": "Bu, kitaplığınıza {{numShapes}} tane şekil ekleyecek. Emin misiniz?", "confirmAddLibrary": "Bu, kitaplığınıza {{numShapes}} tane şekil ekleyecek. Emin misiniz?",
"imageDoesNotContainScene": "", "imageDoesNotContainScene": "Görsel dosyası herhangi bir sahne verisi bulundurmuyor. Dışa aktarırken bunu etkinleştirdiniz mi?",
"cannotRestoreFromImage": "Bu görsel dosyasından sahne onarılamıyor" "cannotRestoreFromImage": "Bu görsel dosyasından sahne onarılamıyor"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Tıkla ve sürükle, bitirdiğinde serbest bırak", "freeDraw": "Tıkla ve sürükle, bitirdiğinde serbest bırak",
"text": "İpucu: seçme aracıyla herhangi bir yere çift tıklayarak da yazı ekleyebilirsin", "text": "İpucu: seçme aracıyla herhangi bir yere çift tıklayarak da yazı ekleyebilirsin",
"linearElementMulti": "Tamamlamak için son noktayı seçin veya Escape ve Enter'dan birine basın", "linearElementMulti": "Tamamlamak için son noktayı seçin veya Escape ve Enter'dan birine basın",
"lockAngle": "",
"resize": "Yeniden boyutlandırırken SHIFT'e basılı tutarak oranları kısıtlayabilirsiniz, merkezden yeniden boyutlandırmak için ALT'a basılı tutun", "resize": "Yeniden boyutlandırırken SHIFT'e basılı tutarak oranları kısıtlayabilirsiniz, merkezden yeniden boyutlandırmak için ALT'a basılı tutun",
"rotate": "Döndürürken SHIFT tuşuna basılı tutarak açıları koruyabilirsiniz", "rotate": "Döndürürken SHIFT tuşuna basılı tutarak açıları koruyabilirsiniz",
"lineEditor_info": "Noktaları düzenlemek için çift-tıklayın veya Enter'a basın", "lineEditor_info": "Noktaları düzenlemek için çift-tıklayın veya Enter'a basın",
@@ -169,7 +168,7 @@
"lineEditor_nothingSelected": "Kaldırmak veya oynatmak için bir nokta seç, veya yeni noktalar eklemek için Alt'a basılı tut" "lineEditor_nothingSelected": "Kaldırmak veya oynatmak için bir nokta seç, veya yeni noktalar eklemek için Alt'a basılı tut"
}, },
"canvasError": { "canvasError": {
"cannotShowPreview": "Önizleme gösterilemiyor", "cannotShowPreview": "",
"canvasTooBig": "", "canvasTooBig": "",
"canvasTooBigTip": "" "canvasTooBigTip": ""
}, },
@@ -221,15 +220,15 @@
"tooltip": "Çizimleriniz uçtan-uca şifrelenmiştir, Excalidraw'ın sunucuları bile onları göremez." "tooltip": "Çizimleriniz uçtan-uca şifrelenmiştir, Excalidraw'ın sunucuları bile onları göremez."
}, },
"stats": { "stats": {
"angle": "Açı", "angle": "",
"element": "Bileşen", "element": "",
"elements": "Bileşenler", "elements": "",
"height": "Yükseklik", "height": "",
"scene": "", "scene": "",
"selected": "Seçili", "selected": "",
"storage": "Depolama", "storage": "",
"title": "", "title": "",
"total": "Toplam", "total": "",
"width": "" "width": ""
} }
} }
+9 -10
View File
@@ -29,7 +29,7 @@
"edges": "Краї", "edges": "Краї",
"sharp": "Гострі", "sharp": "Гострі",
"round": "Круглі", "round": "Круглі",
"arrowheads": "Закінчення стрілки", "arrowheads": "",
"arrowhead_none": "Жоден", "arrowhead_none": "Жоден",
"arrowhead_arrow": "Стрілка", "arrowhead_arrow": "Стрілка",
"arrowhead_bar": "Колона", "arrowhead_bar": "Колона",
@@ -37,7 +37,7 @@
"fontSize": "Розмір шрифту", "fontSize": "Розмір шрифту",
"fontFamily": "Шрифт", "fontFamily": "Шрифт",
"onlySelected": "Тільки вибране", "onlySelected": "Тільки вибране",
"withBackground": "З фоном", "withBackground": "З тлом",
"exportEmbedScene": "Вставити сцену в експортований файл", "exportEmbedScene": "Вставити сцену в експортований файл",
"exportEmbedScene_details": "Дані сцени будуть збережені в експортований файл PNG/SVG. Ця сцена може бути відновленна з нього, однак це збільшить розмір експортованого файлу.", "exportEmbedScene_details": "Дані сцени будуть збережені в експортований файл PNG/SVG. Ця сцена може бути відновленна з нього, однак це збільшить розмір експортованого файлу.",
"addWatermark": "Додати «Накреслене в Excalidraw»", "addWatermark": "Додати «Накреслене в Excalidraw»",
@@ -76,7 +76,8 @@
"group": "Групувати виділене", "group": "Групувати виділене",
"ungroup": "Розгрупувати виділене", "ungroup": "Розгрупувати виділене",
"collaborators": "Співавтори", "collaborators": "Співавтори",
"gridMode": "Режим сітки", "toggleGridMode": "Режим сітки",
"toggleStats": "",
"addToLibrary": "Додати до бібліотеки", "addToLibrary": "Додати до бібліотеки",
"removeFromLibrary": "Видалити з бібліотеки", "removeFromLibrary": "Видалити з бібліотеки",
"libraryLoadingMessage": "Завантажити бібліотеку...", "libraryLoadingMessage": "Завантажити бібліотеку...",
@@ -117,10 +118,9 @@
"redo": "Повторити", "redo": "Повторити",
"roomDialog": "Відкрити сесію спільної роботи", "roomDialog": "Відкрити сесію спільної роботи",
"createNewRoom": "Створити нову кімнату", "createNewRoom": "Створити нову кімнату",
"fullScreen": "Повноекранний режим", "toggleFullScreen": "Повноекранний режим",
"darkMode": "Темний режим", "toggleDarkMode": "Переключити темний режим",
"lightMode": "Світлий режим", "toggleZenMode": "Дзен-режим",
"zenMode": "Режим Дзен",
"exitZenMode": "Вийти з дзен-режиму" "exitZenMode": "Вийти з дзен-режиму"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "Завантаження зовнішнього креслення замінить ваш наявний контент. Продовжити?", "loadSceneOverridePrompt": "Завантаження зовнішнього креслення замінить ваш наявний контент. Продовжити?",
"errorLoadingLibrary": "Помилка при завантаженні сторонньої бібліотеки.", "errorLoadingLibrary": "Помилка при завантаженні сторонньої бібліотеки.",
"confirmAddLibrary": "Це призведе до додавання {{numShapes}} фігур до вашої бібліотеки. Ви впевнені?", "confirmAddLibrary": "Це призведе до додавання {{numShapes}} фігур до вашої бібліотеки. Ви впевнені?",
"imageDoesNotContainScene": "Імпортування зображень на даний момент не підтримується.\n\nЧи хочете ви імпортувати сцену? Це зображення не містить ніяких даних сцен. Ви увімкнули це під час експорту?", "imageDoesNotContainScene": "Файл зображення не містить даних сцени. Ви увімкнули це під час експорту?",
"cannotRestoreFromImage": "Сцена не може бути відновлена з цього файлу зображення" "cannotRestoreFromImage": "Сцена не може бути відновлена з цього файлу зображення"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "Натисніть і потягніть, відпустіть коли завершите", "freeDraw": "Натисніть і потягніть, відпустіть коли завершите",
"text": "Порада: можна також додати текст, двічі клацнувши по будь-якому місці інструментом вибору", "text": "Порада: можна також додати текст, двічі клацнувши по будь-якому місці інструментом вибору",
"linearElementMulti": "Натисніть на останню точку, клацніть Esc або Enter щоб завершити", "linearElementMulti": "Натисніть на останню точку, клацніть Esc або Enter щоб завершити",
"lockAngle": "",
"resize": "Ви можете зберегти пропорції, утримуючи SHIFT під час зміни розміру,\nутримуйте ALT для змінення розміру від центру", "resize": "Ви можете зберегти пропорції, утримуючи SHIFT під час зміни розміру,\nутримуйте ALT для змінення розміру від центру",
"rotate": "Ви можете обмежити кути, утримуючи SHIFT під час обертання", "rotate": "Ви можете обмежити кути, утримуючи SHIFT під час обертання",
"lineEditor_info": "Двічі клацніть або натисніть Enter щоб редагувати точки", "lineEditor_info": "Двічі клацніть або натисніть Enter щоб редагувати точки",
@@ -228,7 +227,7 @@
"scene": "Сцена", "scene": "Сцена",
"selected": "Вибраний", "selected": "Вибраний",
"storage": "Сховище", "storage": "Сховище",
"title": "Статистика", "title": "",
"total": "Всього", "total": "Всього",
"width": "Ширина" "width": "Ширина"
} }
+15 -16
View File
@@ -4,7 +4,7 @@
"selectAll": "全部选中", "selectAll": "全部选中",
"multiSelect": "添加元素到选区", "multiSelect": "添加元素到选区",
"moveCanvas": "移动画布", "moveCanvas": "移动画布",
"cut": "剪切", "cut": "",
"copy": "复制", "copy": "复制",
"copyAsPng": "复制为 PNG 到剪贴板", "copyAsPng": "复制为 PNG 到剪贴板",
"copyAsSvg": "复制为 SVG 到剪贴板", "copyAsSvg": "复制为 SVG 到剪贴板",
@@ -29,15 +29,15 @@
"edges": "边角", "edges": "边角",
"sharp": "尖锐", "sharp": "尖锐",
"round": "圆润", "round": "圆润",
"arrowheads": "箭头", "arrowheads": "",
"arrowhead_none": "", "arrowhead_none": "",
"arrowhead_arrow": "箭头", "arrowhead_arrow": "",
"arrowhead_bar": "", "arrowhead_bar": "",
"arrowhead_dot": "圆点", "arrowhead_dot": "",
"fontSize": "字体大小", "fontSize": "字体大小",
"fontFamily": "字体", "fontFamily": "字体",
"onlySelected": "仅被选中", "onlySelected": "仅被选中",
"withBackground": "使用背景", "withBackground": "添加背景",
"exportEmbedScene": "将场景嵌入到导出的文件", "exportEmbedScene": "将场景嵌入到导出的文件",
"exportEmbedScene_details": "场景数据将被保存到导出的 PNG/SVG 文件,以便恢复。\n将会增加导出的文件大小。", "exportEmbedScene_details": "场景数据将被保存到导出的 PNG/SVG 文件,以便恢复。\n将会增加导出的文件大小。",
"addWatermark": "添加 “使用 Excalidraw 创建” 水印", "addWatermark": "添加 “使用 Excalidraw 创建” 水印",
@@ -76,11 +76,12 @@
"group": "组选", "group": "组选",
"ungroup": "取消组选", "ungroup": "取消组选",
"collaborators": "协作者", "collaborators": "协作者",
"gridMode": "网格模式", "toggleGridMode": "切换网格模式",
"toggleStats": "",
"addToLibrary": "添加到库中", "addToLibrary": "添加到库中",
"removeFromLibrary": "从库中移除", "removeFromLibrary": "从库中移除",
"libraryLoadingMessage": "正在加载库...", "libraryLoadingMessage": "正在加载库...",
"libraries": "浏览库", "libraries": "",
"loadingScene": "正在加载绘图...", "loadingScene": "正在加载绘图...",
"align": "对齐", "align": "对齐",
"alignTop": "顶部对齐", "alignTop": "顶部对齐",
@@ -117,10 +118,9 @@
"redo": "重做", "redo": "重做",
"roomDialog": "开始实时协作", "roomDialog": "开始实时协作",
"createNewRoom": "新建会议室", "createNewRoom": "新建会议室",
"fullScreen": "全屏", "toggleFullScreen": "切换全屏显示",
"darkMode": "暗色主题", "toggleDarkMode": "切换暗黑模式",
"lightMode": "浅色模式", "toggleZenMode": "切换禅模式",
"zenMode": "禅意模式",
"exitZenMode": "退出禅模式" "exitZenMode": "退出禅模式"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "加载外部绘图将取代您现有的内容。您想要继续吗?", "loadSceneOverridePrompt": "加载外部绘图将取代您现有的内容。您想要继续吗?",
"errorLoadingLibrary": "加载第三方库时出错。", "errorLoadingLibrary": "加载第三方库时出错。",
"confirmAddLibrary": "这将添加 {{numShapes}} 个形状到您的库。您确定吗?", "confirmAddLibrary": "这将添加 {{numShapes}} 个形状到您的库。您确定吗?",
"imageDoesNotContainScene": "当前不支持导入图片。\n\n您想要导入场景吗?此图像似乎不包含任何场景数据。您是否在导出过程中启用了这个数据", "imageDoesNotContainScene": "图像文件不包含场景数据。您是否在导出过程中启用了此选项",
"cannotRestoreFromImage": "无法从此图像文件恢复场景" "cannotRestoreFromImage": "无法从此图像文件恢复场景"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "点击并拖动,完成后发布", "freeDraw": "点击并拖动,完成后发布",
"text": "提示:您也可以使用选择工具双击任意位置来添加文字", "text": "提示:您也可以使用选择工具双击任意位置来添加文字",
"linearElementMulti": "点击最后一个点或按下 Esc/Enter 来完成", "linearElementMulti": "点击最后一个点或按下 Esc/Enter 来完成",
"lockAngle": "可以按住 Shift 来约束角度",
"resize": "您可以按住SHIFT来限制比例大小,\n按住ALT来调整中心大小", "resize": "您可以按住SHIFT来限制比例大小,\n按住ALT来调整中心大小",
"rotate": "旋转时可以按住 Shift 来约束角度", "rotate": "旋转时可以按住 Shift 来约束角度",
"lineEditor_info": "双击或按回车键编辑", "lineEditor_info": "双击或按回车键编辑",
@@ -228,7 +227,7 @@
"scene": "场景", "scene": "场景",
"selected": "选中", "selected": "选中",
"storage": "存储", "storage": "存储",
"title": "玩家统计", "title": "",
"total": "总计", "total": "总计",
"width": "宽度" "width": "宽度"
} }
+6 -7
View File
@@ -76,7 +76,8 @@
"group": "建立群組", "group": "建立群組",
"ungroup": "取消群組", "ungroup": "取消群組",
"collaborators": "協作者", "collaborators": "協作者",
"gridMode": "網格模式", "toggleGridMode": "切換格線模式",
"toggleStats": "切換詳細統計",
"addToLibrary": "加入資料庫", "addToLibrary": "加入資料庫",
"removeFromLibrary": "從資料庫中移除", "removeFromLibrary": "從資料庫中移除",
"libraryLoadingMessage": "資料庫讀取中…", "libraryLoadingMessage": "資料庫讀取中…",
@@ -117,10 +118,9 @@
"redo": "重做", "redo": "重做",
"roomDialog": "開始即時協作", "roomDialog": "開始即時協作",
"createNewRoom": "建立新協作會議室", "createNewRoom": "建立新協作會議室",
"fullScreen": "全螢幕", "toggleFullScreen": "切換全螢幕",
"darkMode": "深色模式", "toggleDarkMode": "切換深色模式",
"lightMode": "淺色模式", "toggleZenMode": "切換專注模式",
"zenMode": "專注模式",
"exitZenMode": "離開專注模式" "exitZenMode": "離開專注模式"
}, },
"alerts": { "alerts": {
@@ -136,7 +136,7 @@
"loadSceneOverridePrompt": "讀取外部圖樣將取代目前的內容。是否要繼續?", "loadSceneOverridePrompt": "讀取外部圖樣將取代目前的內容。是否要繼續?",
"errorLoadingLibrary": "載入第三方套件時出現錯誤。", "errorLoadingLibrary": "載入第三方套件時出現錯誤。",
"confirmAddLibrary": "這將會將 {{numShapes}} 個圖形加入你的資料庫,你確定嗎?", "confirmAddLibrary": "這將會將 {{numShapes}} 個圖形加入你的資料庫,你確定嗎?",
"imageDoesNotContainScene": "目前尚不支援載入圖片。\n您是否要載入場景?此圖片中並無任何場景資料輸出時是否有選擇包含?", "imageDoesNotContainScene": "圖檔中未包含場景資料輸出檔案時是否有包含此資料",
"cannotRestoreFromImage": "無法由此檔案回復場景。" "cannotRestoreFromImage": "無法由此檔案回復場景。"
}, },
"toolBar": { "toolBar": {
@@ -161,7 +161,6 @@
"freeDraw": "點擊並拖曳來繪圖,放開即結束", "freeDraw": "點擊並拖曳來繪圖,放開即結束",
"text": "提示:亦可使用選取工具在任何地方雙擊來加入文字", "text": "提示:亦可使用選取工具在任何地方雙擊來加入文字",
"linearElementMulti": "按下 Escape 或 Enter 以結束繪製", "linearElementMulti": "按下 Escape 或 Enter 以結束繪製",
"lockAngle": "按住 SHIFT 可限制旋轉角度",
"resize": "縮放時按住 Shift 可保持原比例縮放;\\n按住 Alt 可由中心點進行縮放", "resize": "縮放時按住 Shift 可保持原比例縮放;\\n按住 Alt 可由中心點進行縮放",
"rotate": "旋轉時按住 Shift 可限制旋轉角度", "rotate": "旋轉時按住 Shift 可限制旋轉角度",
"lineEditor_info": "雙擊滑鼠左鍵或按 Enter 來編輯控制點", "lineEditor_info": "雙擊滑鼠左鍵或按 Enter 來編輯控制點",
+5 -5
View File
@@ -1,5 +1,5 @@
import { Point } from "./types"; import { Point } from "./types";
import { LINE_CONFIRM_THRESHOLD } from "./constants"; import { GRID_SIZE, LINE_CONFIRM_THRESHOLD } from "./constants";
import { ExcalidrawLinearElement } from "./element/types"; import { ExcalidrawLinearElement } from "./element/types";
export const rotate = ( export const rotate = (
@@ -307,12 +307,12 @@ const doSegmentsIntersect = (p1: Point, q1: Point, p2: Point, q2: Point) => {
export const getGridPoint = ( export const getGridPoint = (
x: number, x: number,
y: number, y: number,
gridSize: number | null, isGridOn: boolean,
): [number, number] => { ): [number, number] => {
if (gridSize) { if (isGridOn) {
return [ return [
Math.round(x / gridSize) * gridSize, Math.round(x / GRID_SIZE) * GRID_SIZE,
Math.round(y / gridSize) * gridSize, Math.round(y / GRID_SIZE) * GRID_SIZE,
]; ];
} }
return [x, y]; return [x, y];
-8
View File
@@ -16,9 +16,6 @@ Please add the latest change on the top under the correct section.
### Features ### Features
- Remove language picker, and add `langCode`, `renderFooter` [#2644](https://github.com/excalidraw/excalidraw/pull/2644):
- BREAKING: removed the language picker from UI. It is now the host app's responsibility to implement a language picker if desirable, using the newly added [`renderFooter`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#renderFooter) prop. The reasoning is that the i18n should be controlled by the app itself, not by the nested Excalidraw component.
- Added [`langCode`](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#langCode) prop to control the UI language.
- Add support for `exportToBackend` prop to allow host apps to implement shareable links [#2612](https://github.com/excalidraw/excalidraw/pull/2612/files) - Add support for `exportToBackend` prop to allow host apps to implement shareable links [#2612](https://github.com/excalidraw/excalidraw/pull/2612/files)
- Add zoom to selection [#2522](https://github.com/excalidraw/excalidraw/pull/2522) - Add zoom to selection [#2522](https://github.com/excalidraw/excalidraw/pull/2522)
- Insert Library items in the middle of the screen [#2527](https://github.com/excalidraw/excalidraw/pull/2527) - Insert Library items in the middle of the screen [#2527](https://github.com/excalidraw/excalidraw/pull/2527)
@@ -30,7 +27,6 @@ Please add the latest change on the top under the correct section.
### Fixes ### Fixes
- Fix initialization when browser tab not focused [#2677](https://github.com/excalidraw/excalidraw/pull/2677)
- Consistent case for export locale strings [#2622](https://github.com/excalidraw/excalidraw/pull/2622) - Consistent case for export locale strings [#2622](https://github.com/excalidraw/excalidraw/pull/2622)
- Remove unnecessary console.error as it was polluting Sentry [#2637](https://github.com/excalidraw/excalidraw/pull/2637) - Remove unnecessary console.error as it was polluting Sentry [#2637](https://github.com/excalidraw/excalidraw/pull/2637)
- Fix scroll-to-center on init for non-zero canvas offsets [#2445](https://github.com/excalidraw/excalidraw/pull/2445) - Fix scroll-to-center on init for non-zero canvas offsets [#2445](https://github.com/excalidraw/excalidraw/pull/2445)
@@ -55,10 +51,6 @@ Please add the latest change on the top under the correct section.
- Bump ini from 1.3.5 to 1.3.7 in /src/packages/excalidraw [#2500](https://github.com/excalidraw/excalidraw/pull/2500) - Bump ini from 1.3.5 to 1.3.7 in /src/packages/excalidraw [#2500](https://github.com/excalidraw/excalidraw/pull/2500)
### Docs
- Document some of the more exotic element props [#2673](https://github.com/excalidraw/excalidraw/pull/2673)
## 0.1.1 ## 0.1.1
#### Fix #### Fix
-20
View File
@@ -139,8 +139,6 @@ export default function App() {
| [`isCollaborating`](#isCollaborating) | `boolean` | | This implies if the app is in collaboration mode | | [`isCollaborating`](#isCollaborating) | `boolean` | | This implies if the app is in collaboration mode |
| [`onPointerUpdate`](#onPointerUpdate) | Function | | Callback triggered when mouse pointer is updated. | | [`onPointerUpdate`](#onPointerUpdate) | Function | | Callback triggered when mouse pointer is updated. |
| [`onExportToBackend`](#onExportToBackend) | Function | | Callback triggered when link button is clicked on export dialog | | [`onExportToBackend`](#onExportToBackend) | Function | | Callback triggered when link button is clicked on export dialog |
| [`langCode`](#langCode) | string | `en` | Language code string |
| [`renderFooter `](#renderFooter) | Function | | Function that renders custom UI footer |
#### `width` #### `width`
@@ -272,21 +270,3 @@ This callback is triggered when the shareable-link button is clicked in the expo
1. `exportedElements`: An array of [non deleted elements](https://github.com/excalidraw/excalidraw/blob/6e45cb95dbd7a8be1859c7055b06957298e3097c/src/element/types.ts#L76) which needs to be exported. 1. `exportedElements`: An array of [non deleted elements](https://github.com/excalidraw/excalidraw/blob/6e45cb95dbd7a8be1859c7055b06957298e3097c/src/element/types.ts#L76) which needs to be exported.
2. `appState`: [AppState](https://github.com/excalidraw/excalidraw/blob/4c90ea5667d29effe8ec4a115e49efc7c340cdb3/src/types.ts#L33) of the scene. 2. `appState`: [AppState](https://github.com/excalidraw/excalidraw/blob/4c90ea5667d29effe8ec4a115e49efc7c340cdb3/src/types.ts#L33) of the scene.
3. `canvas`: The `HTMLCanvasElement` of the scene. 3. `canvas`: The `HTMLCanvasElement` of the scene.
#### `langCode`
Determines the language of the UI. It should be one of the [available language codes](https://github.com/excalidraw/excalidraw/blob/d337c8b15f6c1085287b12ecbe59c96e2c4e0ff4/src/i18n.ts#L14). Defaults to `en` (English).
We also export default language and supported languages which you can import as shown below.
```js
import { defaultLang, languages } from "@excalidraw/excalidraw";
```
| name | type |
| ----------- | -------------------------------------------------------------------------------------------------------------------- |
| defaultLang | string |
| languages | [Language []](https://github.com/excalidraw/excalidraw/blob/c35d983fef8a83ba842dd892c0f461111a3e8589/src/i18n.ts#L9) |
#### `renderFooter`
A function that renders (returns JSX) custom UI footer. For example, you can use this to render a language picker that was previously being rendered by Excalidraw itself (for now, you'll need to implement your own language picker).
+1 -7
View File
@@ -8,7 +8,6 @@ import "../../css/styles.scss";
import { ExcalidrawAPIRefValue, ExcalidrawProps } from "../../types"; import { ExcalidrawAPIRefValue, ExcalidrawProps } from "../../types";
import { IsMobileProvider } from "../../is-mobile"; import { IsMobileProvider } from "../../is-mobile";
import { defaultLang } from "../../i18n";
const Excalidraw = (props: ExcalidrawProps) => { const Excalidraw = (props: ExcalidrawProps) => {
const { const {
@@ -24,8 +23,6 @@ const Excalidraw = (props: ExcalidrawProps) => {
isCollaborating, isCollaborating,
onPointerUpdate, onPointerUpdate,
onExportToBackend, onExportToBackend,
renderFooter,
langCode = defaultLang.code,
} = props; } = props;
useEffect(() => { useEffect(() => {
@@ -47,7 +44,7 @@ const Excalidraw = (props: ExcalidrawProps) => {
}, []); }, []);
return ( return (
<InitializeApp langCode={langCode}> <InitializeApp>
<IsMobileProvider> <IsMobileProvider>
<App <App
width={width} width={width}
@@ -62,8 +59,6 @@ const Excalidraw = (props: ExcalidrawProps) => {
isCollaborating={isCollaborating} isCollaborating={isCollaborating}
onPointerUpdate={onPointerUpdate} onPointerUpdate={onPointerUpdate}
onExportToBackend={onExportToBackend} onExportToBackend={onExportToBackend}
renderFooter={renderFooter}
langCode={langCode}
/> />
</IsMobileProvider> </IsMobileProvider>
</InitializeApp> </InitializeApp>
@@ -99,4 +94,3 @@ export {
getSyncableElements, getSyncableElements,
getElementMap, getElementMap,
} from "../../element"; } from "../../element";
export { defaultLang, languages } from "../../i18n";
+199 -75
View File
@@ -1149,12 +1149,6 @@
"to-fast-properties": "^2.0.0" "to-fast-properties": "^2.0.0"
} }
}, },
"@discoveryjs/json-ext": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz",
"integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==",
"dev": true
},
"@polka/url": { "@polka/url": {
"version": "1.0.0-next.11", "version": "1.0.0-next.11",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.11.tgz", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.11.tgz",
@@ -1375,18 +1369,18 @@
} }
}, },
"@webpack-cli/info": { "@webpack-cli/info": {
"version": "1.2.1", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.1.tgz", "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.1.0.tgz",
"integrity": "sha512-fLnDML5HZ5AEKzHul8xLAksoKN2cibu6MgonkUj8R9V7bbeVRkd1XbGEGWrAUNYHbX1jcqCsDEpBviE5StPMzQ==", "integrity": "sha512-uNWSdaYHc+f3LdIZNwhdhkjjLDDl3jP2+XBqAq9H8DjrJUvlOKdP8TNruy1yEaDfgpAIgbSAN7pye4FEHg9tYQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"envinfo": "^7.7.3" "envinfo": "^7.7.3"
} }
}, },
"@webpack-cli/serve": { "@webpack-cli/serve": {
"version": "1.2.1", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.2.1.tgz", "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.1.0.tgz",
"integrity": "sha512-Zj1z6AyS+vqV6Hfi7ngCjFGdHV5EwZNIHo6QfFTNe9PyW+zBU1zJ9BiOW1pmUEq950RC4+Dym6flyA/61/vhyw==", "integrity": "sha512-7RfnMXCpJ/NThrhq4gYQYILB18xWyoQcBey81oIyVbmgbc6m5ZHHyFK+DyH7pLHJf0p14MxL4mTsoPAgBSTpIg==",
"dev": true "dev": true
}, },
"@xtuc/ieee754": { "@xtuc/ieee754": {
@@ -1452,6 +1446,12 @@
"color-convert": "^1.9.0" "color-convert": "^1.9.0"
} }
}, },
"array-back": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.1.tgz",
"integrity": "sha512-Z/JnaVEXv+A9xabHzN43FiiiWEE7gPCRXMrVmRm00tWbjZRul1iHm7ECzlyNq1p4a4ATXz+G9FJ3GqGOkOV3fg==",
"dev": true
},
"babel-code-frame": { "babel-code-frame": {
"version": "6.26.0", "version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@@ -1761,6 +1761,18 @@
"integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==",
"dev": true "dev": true
}, },
"command-line-usage": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.1.tgz",
"integrity": "sha512-F59pEuAR9o1SF/bD0dQBDluhpT4jJQNWUHEuVBqpDmCUo6gPjCi+m9fCWnWZVR/oG6cMTUms4h+3NPl74wGXvA==",
"dev": true,
"requires": {
"array-back": "^4.0.1",
"chalk": "^2.4.2",
"table-layout": "^1.0.1",
"typical": "^5.2.0"
}
},
"commander": { "commander": {
"version": "2.20.3", "version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -1900,6 +1912,12 @@
"ms": "2.1.2" "ms": "2.1.2"
} }
}, },
"deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"dev": true
},
"define-properties": { "define-properties": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -1927,6 +1945,15 @@
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true "dev": true
}, },
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"requires": {
"once": "^1.4.0"
}
},
"enhanced-resolve": { "enhanced-resolve": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz",
@@ -1954,9 +1981,9 @@
"dev": true "dev": true
}, },
"errno": { "errno": {
"version": "0.1.8", "version": "0.1.7",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
"integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
"dev": true, "dev": true,
"requires": { "requires": {
"prr": "~1.0.1" "prr": "~1.0.1"
@@ -2020,19 +2047,19 @@
"dev": true "dev": true
}, },
"execa": { "execa": {
"version": "5.0.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
"integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
"dev": true, "dev": true,
"requires": { "requires": {
"cross-spawn": "^7.0.3", "cross-spawn": "^7.0.0",
"get-stream": "^6.0.0", "get-stream": "^5.0.0",
"human-signals": "^2.1.0", "human-signals": "^1.1.1",
"is-stream": "^2.0.0", "is-stream": "^2.0.0",
"merge-stream": "^2.0.0", "merge-stream": "^2.0.0",
"npm-run-path": "^4.0.1", "npm-run-path": "^4.0.0",
"onetime": "^5.1.2", "onetime": "^5.1.0",
"signal-exit": "^3.0.3", "signal-exit": "^3.0.2",
"strip-final-newline": "^2.0.0" "strip-final-newline": "^2.0.0"
} }
}, },
@@ -2048,12 +2075,6 @@
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true "dev": true
}, },
"fastest-levenshtein": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
"integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==",
"dev": true
},
"file-loader": { "file-loader": {
"version": "6.2.0", "version": "6.2.0",
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz",
@@ -2142,10 +2163,13 @@
} }
}, },
"get-stream": { "get-stream": {
"version": "6.0.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true "dev": true,
"requires": {
"pump": "^3.0.0"
}
}, },
"glob-to-regexp": { "glob-to-regexp": {
"version": "0.4.1", "version": "0.4.1",
@@ -2205,9 +2229,9 @@
"dev": true "dev": true
}, },
"human-signals": { "human-signals": {
"version": "2.1.0", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
"dev": true "dev": true
}, },
"icss-utils": { "icss-utils": {
@@ -2224,6 +2248,51 @@
"requires": { "requires": {
"pkg-dir": "^4.2.0", "pkg-dir": "^4.2.0",
"resolve-cwd": "^3.0.0" "resolve-cwd": "^3.0.0"
},
"dependencies": {
"find-up": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
"integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
"dev": true,
"requires": {
"locate-path": "^5.0.0",
"path-exists": "^4.0.0"
}
},
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
"integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
"dev": true,
"requires": {
"p-locate": "^4.1.0"
}
},
"p-locate": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
"integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
"dev": true,
"requires": {
"p-limit": "^2.2.0"
}
},
"path-exists": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
"integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
},
"pkg-dir": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz",
"integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==",
"dev": true,
"requires": {
"find-up": "^4.0.0"
}
}
} }
}, },
"indexes-of": { "indexes-of": {
@@ -2253,15 +2322,6 @@
"loose-envify": "^1.0.0" "loose-envify": "^1.0.0"
} }
}, },
"is-core-module": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.2.0.tgz",
"integrity": "sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==",
"dev": true,
"requires": {
"has": "^1.0.3"
}
},
"is-number": { "is-number": {
"version": "7.0.0", "version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
@@ -2353,6 +2413,12 @@
"integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==", "integrity": "sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==",
"dev": true "dev": true
}, },
"leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
"integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
"dev": true
},
"loader-runner": { "loader-runner": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.1.0.tgz", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.1.0.tgz",
@@ -2464,18 +2530,18 @@
"dev": true "dev": true
}, },
"mime-db": { "mime-db": {
"version": "1.45.0", "version": "1.44.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
"integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
"dev": true "dev": true
}, },
"mime-types": { "mime-types": {
"version": "2.1.28", "version": "2.1.27",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
"integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
"dev": true, "dev": true,
"requires": { "requires": {
"mime-db": "1.45.0" "mime-db": "1.44.0"
} }
}, },
"mimic-fn": { "mimic-fn": {
@@ -2576,6 +2642,15 @@
"object-keys": "^1.1.1" "object-keys": "^1.1.1"
} }
}, },
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"onetime": { "onetime": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -2732,6 +2807,16 @@
"integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
"dev": true "dev": true
}, },
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"punycode": { "punycode": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
@@ -2771,6 +2856,12 @@
"resolve": "^1.9.0" "resolve": "^1.9.0"
} }
}, },
"reduce-flatten": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz",
"integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==",
"dev": true
},
"regenerate": { "regenerate": {
"version": "1.4.2", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@@ -2839,12 +2930,11 @@
} }
}, },
"resolve": { "resolve": {
"version": "1.19.0", "version": "1.17.0",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz",
"integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==",
"dev": true, "dev": true,
"requires": { "requires": {
"is-core-module": "^2.1.0",
"path-parse": "^1.0.6" "path-parse": "^1.0.6"
} }
}, },
@@ -3036,6 +3126,18 @@
"has-flag": "^3.0.0" "has-flag": "^3.0.0"
} }
}, },
"table-layout": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.1.tgz",
"integrity": "sha512-dEquqYNJiGwY7iPfZ3wbXDI944iqanTSchrACLL2nOB+1r+h1Nzu2eH+DuPPvWvm5Ry7iAPeFlgEtP5bIp5U7Q==",
"dev": true,
"requires": {
"array-back": "^4.0.1",
"deep-extend": "~0.6.0",
"typical": "^5.2.0",
"wordwrapjs": "^4.0.0"
}
},
"tapable": { "tapable": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
@@ -3125,9 +3227,9 @@
"dev": true "dev": true
}, },
"ts-loader": { "ts-loader": {
"version": "8.0.13", "version": "8.0.12",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.13.tgz", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.12.tgz",
"integrity": "sha512-1o1nO6aqouA23d2nlcMSEyPMAWRhnYUU0EQUJSc60E0TUyBNX792RHFYUN1ZM29vhMUNayrsbj2UVdZwKhXCDA==", "integrity": "sha512-UIivVfGVJDdwwjgSrbtcL9Nf10c1BWnL1mxAQUVcnhNIn/P9W3nP5v60Z0aBMtc7ZrE11lMmU6+5jSgAXmGaYw==",
"dev": true, "dev": true,
"requires": { "requires": {
"chalk": "^2.3.0", "chalk": "^2.3.0",
@@ -3151,6 +3253,12 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true "dev": true
}, },
"typical": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
"integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==",
"dev": true
},
"unicode-canonical-property-names-ecmascript": { "unicode-canonical-property-names-ecmascript": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
@@ -3217,9 +3325,9 @@
} }
}, },
"webpack": { "webpack": {
"version": "5.11.1", "version": "5.11.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.11.1.tgz", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.11.0.tgz",
"integrity": "sha512-tNUIdAmYJv+nupRs/U/gqmADm6fgrf5xE+rSlSsf2PgsGO7j2WG7ccU6AWNlOJlHFl+HnmXlBmHIkiLf+XA9mQ==", "integrity": "sha512-ubWv7iP54RqAC/VjixgpnLLogCFbAfSOREcSWnnOlZEU8GICC5eKmJSu6YEnph2N2amKqY9rvxSwgyHxVqpaRw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/eslint-scope": "^3.7.0", "@types/eslint-scope": "^3.7.0",
@@ -3249,13 +3357,13 @@
}, },
"dependencies": { "dependencies": {
"enhanced-resolve": { "enhanced-resolve": {
"version": "5.4.1", "version": "5.4.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.4.1.tgz", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.4.0.tgz",
"integrity": "sha512-4GbyIMzYktTFoRSmkbgZ1LU+RXwf4AQ8Z+rSuuh1dC8plp0PPeaWvx6+G4hh4KnUJ48VoxKbNyA1QQQIUpXjYA==", "integrity": "sha512-ZmqfWURB2lConOBM1JdCVfPyMRv5RdKWktLXO6123p97ovVm2CLBgw9t5MBj3jJWA6eHyOeIws9iJQoGFR4euQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"graceful-fs": "^4.2.4", "graceful-fs": "^4.2.4",
"tapable": "^2.2.0" "tapable": "^2.0.0"
} }
}, },
"find-up": { "find-up": {
@@ -3414,21 +3522,21 @@
} }
}, },
"webpack-cli": { "webpack-cli": {
"version": "4.3.1", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.3.1.tgz", "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.2.0.tgz",
"integrity": "sha512-/F4+9QNZM/qKzzL9/06Am8NXIkGV+/NqQ62Dx7DSqudxxpAgBqYn6V7+zp+0Y7JuWksKUbczRY3wMTd+7Uj6OA==", "integrity": "sha512-EIl3k88vaF4fSxWSgtAQR+VwicfLMTZ9amQtqS4o+TDPW9HGaEpbFBbAZ4A3ZOT5SOnMxNOzROsSTPiE8tBJPA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/info": "^1.1.0",
"@webpack-cli/info": "^1.2.1", "@webpack-cli/serve": "^1.1.0",
"@webpack-cli/serve": "^1.2.1",
"colorette": "^1.2.1", "colorette": "^1.2.1",
"command-line-usage": "^6.1.0",
"commander": "^6.2.0", "commander": "^6.2.0",
"enquirer": "^2.3.6", "enquirer": "^2.3.6",
"execa": "^5.0.0", "execa": "^4.1.0",
"fastest-levenshtein": "^1.0.12",
"import-local": "^3.0.2", "import-local": "^3.0.2",
"interpret": "^2.2.0", "interpret": "^2.2.0",
"leven": "^3.1.0",
"rechoir": "^0.7.0", "rechoir": "^0.7.0",
"v8-compile-cache": "^2.2.0", "v8-compile-cache": "^2.2.0",
"webpack-merge": "^4.2.2" "webpack-merge": "^4.2.2"
@@ -3478,6 +3586,22 @@
"isexe": "^2.0.0" "isexe": "^2.0.0"
} }
}, },
"wordwrapjs": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.0.tgz",
"integrity": "sha512-Svqw723a3R34KvsMgpjFBYCgNOSdcW3mQFK4wIfhGQhtaFVOJmdYoXgi63ne3dTlWgatVcUc7t4HtQ/+bUVIzQ==",
"dev": true,
"requires": {
"reduce-flatten": "^2.0.0",
"typical": "^5.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"ws": { "ws": {
"version": "7.4.1", "version": "7.4.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz",
+3 -3
View File
@@ -57,10 +57,10 @@
"mini-css-extract-plugin": "1.3.3", "mini-css-extract-plugin": "1.3.3",
"sass-loader": "10.1.0", "sass-loader": "10.1.0",
"terser-webpack-plugin": "5.0.3", "terser-webpack-plugin": "5.0.3",
"ts-loader": "8.0.13", "ts-loader": "8.0.12",
"webpack": "5.11.1", "webpack": "5.11.0",
"webpack-bundle-analyzer": "4.3.0", "webpack-bundle-analyzer": "4.3.0",
"webpack-cli": "4.3.1" "webpack-cli": "4.2.0"
}, },
"bugs": "https://github.com/excalidraw/excalidraw/issues", "bugs": "https://github.com/excalidraw/excalidraw/issues",
"repository": "https://github.com/excalidraw/excalidraw", "repository": "https://github.com/excalidraw/excalidraw",
+2 -3
View File
@@ -6,7 +6,6 @@ import { getDefaultAppState } from "../appState";
import { AppState } from "../types"; import { AppState } from "../types";
import { ExcalidrawElement } from "../element/types"; import { ExcalidrawElement } from "../element/types";
import { getNonDeletedElements } from "../element"; import { getNonDeletedElements } from "../element";
import { SCENE_NAME_FALLBACK } from "../constants";
type ExportOpts = { type ExportOpts = {
elements: readonly ExcalidrawElement[]; elements: readonly ExcalidrawElement[];
@@ -19,7 +18,7 @@ type ExportOpts = {
export const exportToCanvas = ({ export const exportToCanvas = ({
elements, elements,
appState = { ...getDefaultAppState(), name: SCENE_NAME_FALLBACK }, appState = getDefaultAppState(),
getDimensions = (width, height) => ({ width, height, scale: 1 }), getDimensions = (width, height) => ({ width, height, scale: 1 }),
}: ExportOpts) => { }: ExportOpts) => {
return _exportToCanvas( return _exportToCanvas(
@@ -75,7 +74,7 @@ export const exportToBlob = (
export const exportToSvg = ({ export const exportToSvg = ({
elements, elements,
appState = { ...getDefaultAppState(), name: SCENE_NAME_FALLBACK }, appState = getDefaultAppState(),
exportPadding, exportPadding,
metadata, metadata,
}: ExportOpts & { }: ExportOpts & {
-1
View File
@@ -75,7 +75,6 @@ const excalidrawDiagram = {
], ],
appState: { appState: {
viewBackgroundColor: "#ffffff", viewBackgroundColor: "#ffffff",
gridSize: null,
}, },
}; };
+154 -65
View File
@@ -1064,12 +1064,6 @@
"to-fast-properties": "^2.0.0" "to-fast-properties": "^2.0.0"
} }
}, },
"@discoveryjs/json-ext": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.2.tgz",
"integrity": "sha512-HyYEUDeIj5rRQU2Hk5HTB2uHsbRQpF70nvMhVzi+VJR0X+xNEhjPui4/kBf3VeH/wqD28PT4sVOm8qqLjBrSZg==",
"dev": true
},
"@polka/url": { "@polka/url": {
"version": "1.0.0-next.11", "version": "1.0.0-next.11",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.11.tgz", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.11.tgz",
@@ -1109,9 +1103,9 @@
"dev": true "dev": true
}, },
"@types/node": { "@types/node": {
"version": "14.14.19", "version": "14.14.14",
"resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.19.tgz", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.14.tgz",
"integrity": "sha512-4nhBPStMK04rruRVtVc6cDqhu7S9GZai0fpXgPXrFpcPX6Xul8xnrjSdGB4KPBVYG/R5+fXWdCM8qBoiULWGPQ==", "integrity": "sha512-UHnOPWVWV1z+VV8k6L1HhG7UbGBgIdghqF3l9Ny9ApPghbjICXkUJSd/b9gOgQfjM1r+37cipdw/HJ3F6ICEnQ==",
"dev": true "dev": true
}, },
"@webassemblyjs/ast": { "@webassemblyjs/ast": {
@@ -1290,18 +1284,18 @@
} }
}, },
"@webpack-cli/info": { "@webpack-cli/info": {
"version": "1.2.1", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.2.1.tgz", "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.1.0.tgz",
"integrity": "sha512-fLnDML5HZ5AEKzHul8xLAksoKN2cibu6MgonkUj8R9V7bbeVRkd1XbGEGWrAUNYHbX1jcqCsDEpBviE5StPMzQ==", "integrity": "sha512-uNWSdaYHc+f3LdIZNwhdhkjjLDDl3jP2+XBqAq9H8DjrJUvlOKdP8TNruy1yEaDfgpAIgbSAN7pye4FEHg9tYQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"envinfo": "^7.7.3" "envinfo": "^7.7.3"
} }
}, },
"@webpack-cli/serve": { "@webpack-cli/serve": {
"version": "1.2.1", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.2.1.tgz", "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.1.0.tgz",
"integrity": "sha512-Zj1z6AyS+vqV6Hfi7ngCjFGdHV5EwZNIHo6QfFTNe9PyW+zBU1zJ9BiOW1pmUEq950RC4+Dym6flyA/61/vhyw==", "integrity": "sha512-7RfnMXCpJ/NThrhq4gYQYILB18xWyoQcBey81oIyVbmgbc6m5ZHHyFK+DyH7pLHJf0p14MxL4mTsoPAgBSTpIg==",
"dev": true "dev": true
}, },
"@xtuc/ieee754": { "@xtuc/ieee754": {
@@ -1367,6 +1361,12 @@
"color-convert": "^1.9.0" "color-convert": "^1.9.0"
} }
}, },
"array-back": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/array-back/-/array-back-4.0.1.tgz",
"integrity": "sha512-Z/JnaVEXv+A9xabHzN43FiiiWEE7gPCRXMrVmRm00tWbjZRul1iHm7ECzlyNq1p4a4ATXz+G9FJ3GqGOkOV3fg==",
"dev": true
},
"babel-code-frame": { "babel-code-frame": {
"version": "6.26.0", "version": "6.26.0",
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
@@ -1670,6 +1670,18 @@
"integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==",
"dev": true "dev": true
}, },
"command-line-usage": {
"version": "6.1.1",
"resolved": "https://registry.npmjs.org/command-line-usage/-/command-line-usage-6.1.1.tgz",
"integrity": "sha512-F59pEuAR9o1SF/bD0dQBDluhpT4jJQNWUHEuVBqpDmCUo6gPjCi+m9fCWnWZVR/oG6cMTUms4h+3NPl74wGXvA==",
"dev": true,
"requires": {
"array-back": "^4.0.1",
"chalk": "^2.4.2",
"table-layout": "^1.0.1",
"typical": "^5.2.0"
}
},
"commander": { "commander": {
"version": "2.20.3", "version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
@@ -1750,6 +1762,12 @@
"ms": "2.1.2" "ms": "2.1.2"
} }
}, },
"deep-extend": {
"version": "0.6.0",
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
"integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
"dev": true
},
"define-properties": { "define-properties": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
@@ -1777,6 +1795,15 @@
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
"dev": true "dev": true
}, },
"end-of-stream": {
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
"integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
"dev": true,
"requires": {
"once": "^1.4.0"
}
},
"enhanced-resolve": { "enhanced-resolve": {
"version": "4.3.0", "version": "4.3.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.3.0.tgz",
@@ -1804,9 +1831,9 @@
"dev": true "dev": true
}, },
"errno": { "errno": {
"version": "0.1.8", "version": "0.1.7",
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
"integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
"dev": true, "dev": true,
"requires": { "requires": {
"prr": "~1.0.1" "prr": "~1.0.1"
@@ -1870,19 +1897,19 @@
"dev": true "dev": true
}, },
"execa": { "execa": {
"version": "5.0.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.0.0.tgz", "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz",
"integrity": "sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==", "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==",
"dev": true, "dev": true,
"requires": { "requires": {
"cross-spawn": "^7.0.3", "cross-spawn": "^7.0.0",
"get-stream": "^6.0.0", "get-stream": "^5.0.0",
"human-signals": "^2.1.0", "human-signals": "^1.1.1",
"is-stream": "^2.0.0", "is-stream": "^2.0.0",
"merge-stream": "^2.0.0", "merge-stream": "^2.0.0",
"npm-run-path": "^4.0.1", "npm-run-path": "^4.0.0",
"onetime": "^5.1.2", "onetime": "^5.1.0",
"signal-exit": "^3.0.3", "signal-exit": "^3.0.2",
"strip-final-newline": "^2.0.0" "strip-final-newline": "^2.0.0"
} }
}, },
@@ -1898,12 +1925,6 @@
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true "dev": true
}, },
"fastest-levenshtein": {
"version": "1.0.12",
"resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
"integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==",
"dev": true
},
"file-loader": { "file-loader": {
"version": "6.2.0", "version": "6.2.0",
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz",
@@ -1992,10 +2013,13 @@
} }
}, },
"get-stream": { "get-stream": {
"version": "6.0.0", "version": "5.2.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.0.tgz", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
"integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
"dev": true "dev": true,
"requires": {
"pump": "^3.0.0"
}
}, },
"glob-to-regexp": { "glob-to-regexp": {
"version": "0.4.1", "version": "0.4.1",
@@ -2055,9 +2079,9 @@
"dev": true "dev": true
}, },
"human-signals": { "human-signals": {
"version": "2.1.0", "version": "1.1.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz",
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==",
"dev": true "dev": true
}, },
"import-local": { "import-local": {
@@ -2185,6 +2209,12 @@
"minimist": "^1.2.5" "minimist": "^1.2.5"
} }
}, },
"leven": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
"integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
"dev": true
},
"loader-runner": { "loader-runner": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.1.0.tgz", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.1.0.tgz",
@@ -2287,18 +2317,18 @@
"dev": true "dev": true
}, },
"mime-db": { "mime-db": {
"version": "1.45.0", "version": "1.44.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.45.0.tgz", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz",
"integrity": "sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w==", "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==",
"dev": true "dev": true
}, },
"mime-types": { "mime-types": {
"version": "2.1.28", "version": "2.1.27",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.28.tgz", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz",
"integrity": "sha512-0TO2yJ5YHYr7M2zzT7gDU1tbwHxEUWBCLt0lscSNpcdAfFyJOVEpRYNS7EXVcTLNj/25QO8gulHC5JtTzSE2UQ==", "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==",
"dev": true, "dev": true,
"requires": { "requires": {
"mime-db": "1.45.0" "mime-db": "1.44.0"
} }
}, },
"mimic-fn": { "mimic-fn": {
@@ -2358,6 +2388,15 @@
"object-keys": "^1.1.1" "object-keys": "^1.1.1"
} }
}, },
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1"
}
},
"onetime": { "onetime": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
@@ -2442,6 +2481,16 @@
"integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
"dev": true "dev": true
}, },
"pump": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"punycode": { "punycode": {
"version": "2.1.1", "version": "2.1.1",
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
@@ -2481,6 +2530,12 @@
"resolve": "^1.9.0" "resolve": "^1.9.0"
} }
}, },
"reduce-flatten": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz",
"integrity": "sha512-EJ4UNY/U1t2P/2k6oqotuX2Cc3T6nxJwsM0N0asT7dhrtH1ltUxDn4NalSYmPE2rCkVpcf/X6R0wDwcFpzhd4w==",
"dev": true
},
"regenerate": { "regenerate": {
"version": "1.4.2", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz",
@@ -2700,6 +2755,18 @@
"has-flag": "^3.0.0" "has-flag": "^3.0.0"
} }
}, },
"table-layout": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/table-layout/-/table-layout-1.0.1.tgz",
"integrity": "sha512-dEquqYNJiGwY7iPfZ3wbXDI944iqanTSchrACLL2nOB+1r+h1Nzu2eH+DuPPvWvm5Ry7iAPeFlgEtP5bIp5U7Q==",
"dev": true,
"requires": {
"array-back": "^4.0.1",
"deep-extend": "~0.6.0",
"typical": "^5.2.0",
"wordwrapjs": "^4.0.0"
}
},
"tapable": { "tapable": {
"version": "1.1.3", "version": "1.1.3",
"resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz",
@@ -2789,9 +2856,9 @@
"dev": true "dev": true
}, },
"ts-loader": { "ts-loader": {
"version": "8.0.13", "version": "8.0.12",
"resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.13.tgz", "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-8.0.12.tgz",
"integrity": "sha512-1o1nO6aqouA23d2nlcMSEyPMAWRhnYUU0EQUJSc60E0TUyBNX792RHFYUN1ZM29vhMUNayrsbj2UVdZwKhXCDA==", "integrity": "sha512-UIivVfGVJDdwwjgSrbtcL9Nf10c1BWnL1mxAQUVcnhNIn/P9W3nP5v60Z0aBMtc7ZrE11lMmU6+5jSgAXmGaYw==",
"dev": true, "dev": true,
"requires": { "requires": {
"chalk": "^2.3.0", "chalk": "^2.3.0",
@@ -2815,6 +2882,12 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true "dev": true
}, },
"typical": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/typical/-/typical-5.2.0.tgz",
"integrity": "sha512-dvdQgNDNJo+8B2uBQoqdb11eUCE1JQXhvjC/CZtgvZseVd5TYMXnq0+vuUemXbd/Se29cTaUuPX3YIc2xgbvIg==",
"dev": true
},
"unicode-canonical-property-names-ecmascript": { "unicode-canonical-property-names-ecmascript": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz",
@@ -2875,9 +2948,9 @@
} }
}, },
"webpack": { "webpack": {
"version": "5.11.1", "version": "5.11.0",
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.11.1.tgz", "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.11.0.tgz",
"integrity": "sha512-tNUIdAmYJv+nupRs/U/gqmADm6fgrf5xE+rSlSsf2PgsGO7j2WG7ccU6AWNlOJlHFl+HnmXlBmHIkiLf+XA9mQ==", "integrity": "sha512-ubWv7iP54RqAC/VjixgpnLLogCFbAfSOREcSWnnOlZEU8GICC5eKmJSu6YEnph2N2amKqY9rvxSwgyHxVqpaRw==",
"dev": true, "dev": true,
"requires": { "requires": {
"@types/eslint-scope": "^3.7.0", "@types/eslint-scope": "^3.7.0",
@@ -2907,13 +2980,13 @@
}, },
"dependencies": { "dependencies": {
"enhanced-resolve": { "enhanced-resolve": {
"version": "5.4.1", "version": "5.4.0",
"resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.4.1.tgz", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.4.0.tgz",
"integrity": "sha512-4GbyIMzYktTFoRSmkbgZ1LU+RXwf4AQ8Z+rSuuh1dC8plp0PPeaWvx6+G4hh4KnUJ48VoxKbNyA1QQQIUpXjYA==", "integrity": "sha512-ZmqfWURB2lConOBM1JdCVfPyMRv5RdKWktLXO6123p97ovVm2CLBgw9t5MBj3jJWA6eHyOeIws9iJQoGFR4euQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"graceful-fs": "^4.2.4", "graceful-fs": "^4.2.4",
"tapable": "^2.2.0" "tapable": "^2.0.0"
} }
}, },
"find-up": { "find-up": {
@@ -3056,21 +3129,21 @@
} }
}, },
"webpack-cli": { "webpack-cli": {
"version": "4.3.1", "version": "4.2.0",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.3.1.tgz", "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.2.0.tgz",
"integrity": "sha512-/F4+9QNZM/qKzzL9/06Am8NXIkGV+/NqQ62Dx7DSqudxxpAgBqYn6V7+zp+0Y7JuWksKUbczRY3wMTd+7Uj6OA==", "integrity": "sha512-EIl3k88vaF4fSxWSgtAQR+VwicfLMTZ9amQtqS4o+TDPW9HGaEpbFBbAZ4A3ZOT5SOnMxNOzROsSTPiE8tBJPA==",
"dev": true, "dev": true,
"requires": { "requires": {
"@discoveryjs/json-ext": "^0.5.0", "@webpack-cli/info": "^1.1.0",
"@webpack-cli/info": "^1.2.1", "@webpack-cli/serve": "^1.1.0",
"@webpack-cli/serve": "^1.2.1",
"colorette": "^1.2.1", "colorette": "^1.2.1",
"command-line-usage": "^6.1.0",
"commander": "^6.2.0", "commander": "^6.2.0",
"enquirer": "^2.3.6", "enquirer": "^2.3.6",
"execa": "^5.0.0", "execa": "^4.1.0",
"fastest-levenshtein": "^1.0.12",
"import-local": "^3.0.2", "import-local": "^3.0.2",
"interpret": "^2.2.0", "interpret": "^2.2.0",
"leven": "^3.1.0",
"rechoir": "^0.7.0", "rechoir": "^0.7.0",
"v8-compile-cache": "^2.2.0", "v8-compile-cache": "^2.2.0",
"webpack-merge": "^4.2.2" "webpack-merge": "^4.2.2"
@@ -3120,6 +3193,22 @@
"isexe": "^2.0.0" "isexe": "^2.0.0"
} }
}, },
"wordwrapjs": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/wordwrapjs/-/wordwrapjs-4.0.0.tgz",
"integrity": "sha512-Svqw723a3R34KvsMgpjFBYCgNOSdcW3mQFK4wIfhGQhtaFVOJmdYoXgi63ne3dTlWgatVcUc7t4HtQ/+bUVIzQ==",
"dev": true,
"requires": {
"reduce-flatten": "^2.0.0",
"typical": "^5.0.0"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
},
"ws": { "ws": {
"version": "7.4.1", "version": "7.4.1",
"resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz", "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.1.tgz",
+3 -3
View File
@@ -45,10 +45,10 @@
"babel-plugin-transform-class-properties": "6.24.1", "babel-plugin-transform-class-properties": "6.24.1",
"cross-env": "7.0.3", "cross-env": "7.0.3",
"file-loader": "6.2.0", "file-loader": "6.2.0",
"ts-loader": "8.0.13", "ts-loader": "8.0.12",
"webpack": "5.11.1", "webpack": "5.11.0",
"webpack-bundle-analyzer": "4.3.0", "webpack-bundle-analyzer": "4.3.0",
"webpack-cli": "4.3.1" "webpack-cli": "4.2.0"
}, },
"bugs": "https://github.com/excalidraw/excalidraw/issues", "bugs": "https://github.com/excalidraw/excalidraw/issues",
"repository": "https://github.com/excalidraw/excalidraw", "repository": "https://github.com/excalidraw/excalidraw",
+14 -15
View File
@@ -48,6 +48,7 @@ import {
TransformHandleType, TransformHandleType,
} from "../element/transformHandles"; } from "../element/transformHandles";
import { viewportCoordsToSceneCoords } from "../utils"; import { viewportCoordsToSceneCoords } from "../utils";
import { GRID_SIZE } from "../constants";
const strokeRectWithRotation = ( const strokeRectWithRotation = (
context: CanvasRenderingContext2D, context: CanvasRenderingContext2D,
@@ -118,7 +119,6 @@ const fillCircle = (
const strokeGrid = ( const strokeGrid = (
context: CanvasRenderingContext2D, context: CanvasRenderingContext2D,
gridSize: number,
offsetX: number, offsetX: number,
offsetY: number, offsetY: number,
width: number, width: number,
@@ -127,13 +127,13 @@ const strokeGrid = (
const origStrokeStyle = context.strokeStyle; const origStrokeStyle = context.strokeStyle;
context.strokeStyle = "rgba(0,0,0,0.1)"; context.strokeStyle = "rgba(0,0,0,0.1)";
context.beginPath(); context.beginPath();
for (let x = offsetX; x < offsetX + width + gridSize * 2; x += gridSize) { for (let x = offsetX; x < offsetX + width + GRID_SIZE * 2; x += GRID_SIZE) {
context.moveTo(x, offsetY - gridSize); context.moveTo(x, offsetY - GRID_SIZE);
context.lineTo(x, offsetY + height + gridSize * 2); context.lineTo(x, offsetY + height + GRID_SIZE * 2);
} }
for (let y = offsetY; y < offsetY + height + gridSize * 2; y += gridSize) { for (let y = offsetY; y < offsetY + height + GRID_SIZE * 2; y += GRID_SIZE) {
context.moveTo(offsetX - gridSize, y); context.moveTo(offsetX - GRID_SIZE, y);
context.lineTo(offsetX + width + gridSize * 2, y); context.lineTo(offsetX + width + GRID_SIZE * 2, y);
} }
context.stroke(); context.stroke();
context.strokeStyle = origStrokeStyle; context.strokeStyle = origStrokeStyle;
@@ -233,16 +233,15 @@ export const renderScene = (
context.scale(sceneState.zoom.value, sceneState.zoom.value); context.scale(sceneState.zoom.value, sceneState.zoom.value);
// Grid // Grid
if (renderGrid && appState.gridSize) { if (renderGrid && appState.showGrid) {
strokeGrid( strokeGrid(
context, context,
appState.gridSize, -Math.ceil(zoomTranslationX / sceneState.zoom.value / GRID_SIZE) *
-Math.ceil(zoomTranslationX / sceneState.zoom.value / appState.gridSize) * GRID_SIZE +
appState.gridSize + (sceneState.scrollX % GRID_SIZE),
(sceneState.scrollX % appState.gridSize), -Math.ceil(zoomTranslationY / sceneState.zoom.value / GRID_SIZE) *
-Math.ceil(zoomTranslationY / sceneState.zoom.value / appState.gridSize) * GRID_SIZE +
appState.gridSize + (sceneState.scrollY % GRID_SIZE),
(sceneState.scrollY % appState.gridSize),
normalizedCanvasWidth / sceneState.zoom.value, normalizedCanvasWidth / sceneState.zoom.value,
normalizedCanvasHeight / sceneState.zoom.value, normalizedCanvasHeight / sceneState.zoom.value,
); );
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -2,7 +2,7 @@ import React from "react";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import { render } from "./test-utils"; import { render } from "./test-utils";
import ExcalidrawApp from "../excalidraw-app"; import ExcalidrawApp from "../excalidraw-app";
import { defaultLang, setLanguage } from "../i18n"; import { setLanguage } from "../i18n";
import { UI, Pointer, Keyboard } from "./helpers/ui"; import { UI, Pointer, Keyboard } from "./helpers/ui";
import { API } from "./helpers/api"; import { API } from "./helpers/api";
import { KEYS } from "../keys"; import { KEYS } from "../keys";
@@ -60,7 +60,7 @@ describe("aligning", () => {
ReactDOM.unmountComponentAtNode(document.getElementById("root")!); ReactDOM.unmountComponentAtNode(document.getElementById("root")!);
mouse.reset(); mouse.reset();
await setLanguage(defaultLang); await setLanguage("en.json");
await render(<ExcalidrawApp />); await render(<ExcalidrawApp />);
}); });
+5 -51
View File
@@ -169,12 +169,6 @@ export class Pointer {
this.click(element.x, element.y); this.click(element.x, element.y);
this.reset(); this.reset();
} }
doubleClickOn(element: ExcalidrawElement) {
this.reset();
this.doubleClick(element.x, element.y);
this.reset();
}
} }
const mouse = new Pointer("mouse"); const mouse = new Pointer("mouse");
@@ -184,72 +178,32 @@ export class UI {
fireEvent.click(GlobalTestState.renderResult.getByToolName(toolName)); fireEvent.click(GlobalTestState.renderResult.getByToolName(toolName));
}; };
/**
* Creates an Excalidraw element, and returns a proxy that wraps it so that
* accessing props will return the latest ones from the object existing in
* the app's elements array. This is because across the app lifecycle we tend
* to recreate element objects and the returned reference will become stale.
*
* If you need to get the actual element, not the proxy, call `get()` method
* on the proxy object.
*/
static createElement<T extends ToolName>( static createElement<T extends ToolName>(
type: T, type: T,
{ {
position = 0, x = 0,
x = position, y = 0,
y = position,
size = 10, size = 10,
width = size, width = size,
height = width, height = width,
}: { }: {
position?: number;
x?: number; x?: number;
y?: number; y?: number;
size?: number; size?: number;
width?: number; width?: number;
height?: number; height?: number;
} = {}, } = {},
): (T extends "arrow" | "line" | "draw" ): T extends "arrow" | "line" | "draw"
? ExcalidrawLinearElement ? ExcalidrawLinearElement
: T extends "text" : T extends "text"
? ExcalidrawTextElement ? ExcalidrawTextElement
: ExcalidrawElement) & { : ExcalidrawElement {
/** Returns the actual, current element from the elements array, instead
of the proxy */
get(): T extends "arrow" | "line" | "draw"
? ExcalidrawLinearElement
: T extends "text"
? ExcalidrawTextElement
: ExcalidrawElement;
} {
UI.clickTool(type); UI.clickTool(type);
mouse.reset(); mouse.reset();
mouse.down(x, y); mouse.down(x, y);
mouse.reset(); mouse.reset();
mouse.up(x + (width ?? height ?? size), y + (height ?? size)); mouse.up(x + (width ?? height ?? size), y + (height ?? size));
return h.elements[h.elements.length - 1] as any;
const origElement = h.elements[h.elements.length - 1] as any;
return new Proxy(
{},
{
get(target, prop) {
const currentElement = h.elements.find(
(element) => element.id === origElement.id,
) as any;
if (prop === "get") {
if (currentElement.hasOwnProperty("get")) {
throw new Error(
"trying to get `get` test property, but ExcalidrawElement seems to define its own",
);
}
return () => currentElement;
}
return currentElement[prop];
},
},
) as any;
} }
static group(elements: ExcalidrawElement[]) { static group(elements: ExcalidrawElement[]) {
+3 -3
View File
@@ -69,9 +69,9 @@ describe("move element", () => {
// bind line to two rectangles // bind line to two rectangles
bindOrUnbindLinearElement( bindOrUnbindLinearElement(
line.get() as NonDeleted<ExcalidrawLinearElement>, line as NonDeleted<ExcalidrawLinearElement>,
rectA.get() as ExcalidrawRectangleElement, rectA as ExcalidrawRectangleElement,
rectB.get() as ExcalidrawRectangleElement, rectB as ExcalidrawRectangleElement,
); );
// select the second rectangles // select the second rectangles
+41 -22
View File
@@ -4,8 +4,9 @@ import ReactDOM from "react-dom";
import { copiedStyles } from "../actions/actionStyles"; import { copiedStyles } from "../actions/actionStyles";
import { ShortcutName } from "../actions/shortcuts"; import { ShortcutName } from "../actions/shortcuts";
import { ExcalidrawElement } from "../element/types"; import { ExcalidrawElement } from "../element/types";
import { setLanguage } from "../i18n";
import { CODES, KEYS } from "../keys"; import { CODES, KEYS } from "../keys";
import ExcalidrawApp from "../excalidraw-app"; import Excalidraw from "../packages/excalidraw/index";
import { reseed } from "../random"; import { reseed } from "../random";
import * as Renderer from "../renderer/renderScene"; import * as Renderer from "../renderer/renderScene";
import { setDateTimeForTests } from "../utils"; import { setDateTimeForTests } from "../utils";
@@ -18,7 +19,6 @@ import {
screen, screen,
waitFor, waitFor,
} from "./test-utils"; } from "./test-utils";
import { defaultLang } from "../i18n";
const { h } = window; const { h } = window;
@@ -75,7 +75,8 @@ beforeEach(async () => {
finger1.reset(); finger1.reset();
finger2.reset(); finger2.reset();
await render(<ExcalidrawApp />); await setLanguage("en.json");
await render(<Excalidraw offsetLeft={0} offsetTop={0} />);
}); });
afterEach(() => { afterEach(() => {
@@ -438,7 +439,7 @@ describe("regression tests", () => {
await waitFor(() => expect(screen.queryByTitle(/thin/i)).toBeNull()); await waitFor(() => expect(screen.queryByTitle(/thin/i)).toBeNull());
// reset language // reset language
fireEvent.change(document.querySelector(".dropdown-select__language")!, { fireEvent.change(document.querySelector(".dropdown-select__language")!, {
target: { value: defaultLang.code }, target: { value: "en" },
}); });
// switching back to English // switching back to English
await waitFor(() => expect(screen.queryByTitle(/thin/i)).not.toBeNull()); await waitFor(() => expect(screen.queryByTitle(/thin/i)).not.toBeNull());
@@ -557,46 +558,64 @@ describe("regression tests", () => {
}); });
it("supports nested groups", () => { it("supports nested groups", () => {
const rectA = UI.createElement("rectangle", { position: 0, size: 50 }); const positions: number[][] = [];
const rectB = UI.createElement("rectangle", { position: 100, size: 50 });
const rectC = UI.createElement("rectangle", { position: 200, size: 50 }); UI.clickTool("rectangle");
mouse.down(10, 10);
mouse.up(10, 10);
positions.push(mouse.getPosition());
UI.clickTool("rectangle");
mouse.down(10, -10);
mouse.up(10, 10);
positions.push(mouse.getPosition());
UI.clickTool("rectangle");
mouse.down(10, -10);
mouse.up(10, 10);
positions.push(mouse.getPosition());
Keyboard.withModifierKeys({ ctrl: true }, () => { Keyboard.withModifierKeys({ ctrl: true }, () => {
Keyboard.keyPress(KEYS.A); Keyboard.keyPress(KEYS.A);
Keyboard.codePress(CODES.G); Keyboard.codePress(CODES.G);
}); });
mouse.doubleClickOn(rectC); mouse.doubleClick();
Keyboard.withModifierKeys({ shift: true }, () => { Keyboard.withModifierKeys({ shift: true }, () => {
mouse.clickOn(rectA); mouse.restorePosition(...positions[0]);
mouse.click();
}); });
Keyboard.withModifierKeys({ ctrl: true }, () => { Keyboard.withModifierKeys({ ctrl: true }, () => {
Keyboard.codePress(CODES.G); Keyboard.codePress(CODES.G);
}); });
expect(rectC.groupIds.length).toBe(2); const groupIds = h.elements[2].groupIds;
expect(rectA.groupIds).toEqual(rectC.groupIds); expect(groupIds.length).toBe(2);
expect(rectB.groupIds).toEqual(rectA.groupIds.slice(1)); expect(h.elements[1].groupIds).toEqual(groupIds);
expect(h.elements[0].groupIds).toEqual(groupIds.slice(1));
mouse.click(0, 100); mouse.click(50, 50);
expect(API.getSelectedElements().length).toBe(0); expect(API.getSelectedElements().length).toBe(0);
mouse.restorePosition(...positions[0]);
mouse.clickOn(rectA); mouse.click();
expect(API.getSelectedElements().length).toBe(3); expect(API.getSelectedElements().length).toBe(3);
expect(h.state.editingGroupId).toBe(null); expect(h.state.editingGroupId).toBe(null);
mouse.doubleClickOn(rectA); mouse.doubleClick();
expect(API.getSelectedElements().length).toBe(2); expect(API.getSelectedElements().length).toBe(2);
expect(h.state.editingGroupId).toBe(rectA.groupIds[1]); expect(h.state.editingGroupId).toBe(groupIds[1]);
mouse.doubleClickOn(rectA); mouse.doubleClick();
expect(API.getSelectedElements().length).toBe(1); expect(API.getSelectedElements().length).toBe(1);
expect(h.state.editingGroupId).toBe(rectA.groupIds[0]); expect(h.state.editingGroupId).toBe(groupIds[0]);
// click outside current (sub)group // click out of the group
mouse.clickOn(rectB); mouse.restorePosition(...positions[1]);
mouse.click();
expect(API.getSelectedElements().length).toBe(0);
mouse.click();
expect(API.getSelectedElements().length).toBe(3); expect(API.getSelectedElements().length).toBe(3);
mouse.doubleClickOn(rectB); mouse.doubleClick();
expect(API.getSelectedElements().length).toBe(1); expect(API.getSelectedElements().length).toBe(1);
}); });
+3 -16
View File
@@ -9,7 +9,6 @@ import {
GroupId, GroupId,
ExcalidrawBindableElement, ExcalidrawBindableElement,
Arrowhead, Arrowhead,
ChartType,
} from "./element/types"; } from "./element/types";
import { SHAPES } from "./shapes"; import { SHAPES } from "./shapes";
import { Point as RoughPoint } from "roughjs/bin/geometry"; import { Point as RoughPoint } from "roughjs/bin/geometry";
@@ -18,8 +17,6 @@ import { SuggestedBinding } from "./element/binding";
import { ImportedDataState } from "./data/types"; import { ImportedDataState } from "./data/types";
import { ExcalidrawImperativeAPI } from "./components/App"; import { ExcalidrawImperativeAPI } from "./components/App";
import type { ResolvablePromise } from "./utils"; import type { ResolvablePromise } from "./utils";
import { Spreadsheet } from "./charts";
import { Language } from "./i18n";
export type FlooredNumber = number & { _brand: "FlooredNumber" }; export type FlooredNumber = number & { _brand: "FlooredNumber" };
export type Point = Readonly<RoughPoint>; export type Point = Readonly<RoughPoint>;
@@ -70,6 +67,8 @@ export type AppState = {
viewBackgroundColor: string; viewBackgroundColor: string;
scrollX: FlooredNumber; scrollX: FlooredNumber;
scrollY: FlooredNumber; scrollY: FlooredNumber;
cursorX: number;
cursorY: number;
cursorButton: "up" | "down"; cursorButton: "up" | "down";
scrolledOutside: boolean; scrolledOutside: boolean;
name: string; name: string;
@@ -84,7 +83,7 @@ export type AppState = {
showShortcutsDialog: boolean; showShortcutsDialog: boolean;
zenModeEnabled: boolean; zenModeEnabled: boolean;
appearance: "light" | "dark"; appearance: "light" | "dark";
gridSize: number | null; showGrid: boolean;
/** top-most selected groups (i.e. does not include nested groups) */ /** top-most selected groups (i.e. does not include nested groups) */
selectedGroupIds: { [groupId: string]: boolean }; selectedGroupIds: { [groupId: string]: boolean };
@@ -100,16 +99,6 @@ export type AppState = {
fileHandle: import("browser-nativefs").FileSystemHandle | null; fileHandle: import("browser-nativefs").FileSystemHandle | null;
collaborators: Map<string, Collaborator>; collaborators: Map<string, Collaborator>;
showStats: boolean; showStats: boolean;
currentChartType: ChartType;
pasteDialog:
| {
shown: false;
data: null;
}
| {
shown: true;
data: Spreadsheet;
};
}; };
export type NormalizedZoomValue = number & { _brand: "normalizedZoom" }; export type NormalizedZoomValue = number & { _brand: "normalizedZoom" };
@@ -182,8 +171,6 @@ export interface ExcalidrawProps {
appState: AppState, appState: AppState,
canvas: HTMLCanvasElement | null, canvas: HTMLCanvasElement | null,
) => void; ) => void;
renderFooter?: (isMobile: boolean) => JSX.Element;
langCode?: Language["code"];
} }
export type SceneData = { export type SceneData = {
-5
View File
@@ -8,7 +8,6 @@ import { FontFamily, FontString } from "./element/types";
import { Zoom } from "./types"; import { Zoom } from "./types";
import { unstable_batchedUpdates } from "react-dom"; import { unstable_batchedUpdates } from "react-dom";
import { isDarwin } from "./keys"; import { isDarwin } from "./keys";
import { t } from "./i18n";
export const SVG_NS = "http://www.w3.org/2000/svg"; export const SVG_NS = "http://www.w3.org/2000/svg";
@@ -33,10 +32,6 @@ export const getDateTime = () => {
return `${year}-${month}-${day}-${hr}${min}`; return `${year}-${month}-${day}-${hr}${min}`;
}; };
export const getNewSceneName = () => {
return `${t("labels.untitled")}-${getDateTime()}`;
};
export const capitalizeString = (str: string) => export const capitalizeString = (str: string) =>
str.charAt(0).toUpperCase() + str.slice(1); str.charAt(0).toUpperCase() + str.slice(1);