i18n: complete Simplified Chinese catalog, Chinese font fallback and a coverage xtask (#930)

Adds a complete Simplified Chinese (zh) catalog covering every English message, a font fallback for Chinese text, and `cargo xtask i18n --check`, which checks that the complete catalogs (ja, zh) carry every English message and that every command label is translatable.

Co-authored-by: Noly1990 <[email protected]>
This commit is contained in:
NolyandNoly1990 authored and GitHub committed 2026-10-13 23:00:39 -04:00
1 parent 587cf865b8
commit 45f92277cb
17 files changed
+2485 -52

No files matched your search

+99 -13
View File
@@ -10,12 +10,17 @@ use std::sync::Arc;
/// Name of the CJK fallback entry in [`egui::FontDefinitions`].
pub const CJK_FALLBACK: &str = "cjk_fallback";
/// Name of the Hangul fallback entry in [`egui::FontDefinitions`], after [`CJK_FALLBACK`].
/// Name of the Chinese fallback entry in [`egui::FontDefinitions`], after [`CJK_FALLBACK`].
/// A Japanese-only CJK font (Meiryo, Hiragino Gothic) lacks simplified characters, so
/// Chinese falls through to this one per glyph.
pub const CHINESE_FALLBACK: &str = "chinese_fallback";
/// Name of the Hangul fallback entry in [`egui::FontDefinitions`], last.
pub const HANGUL_FALLBACK: &str = "hangul_fallback";
/// UI languages whose text needs the CJK font. The web app's bundled font covers Japanese only;
/// add Chinese or Korean here together with a font that covers them.
pub const CJK_LANGUAGES: &[&str] = &["ja"];
pub const CJK_LANGUAGES: &[&str] = &["ja", "zh", "ko"];
/// Whether the UI language needs a CJK font (the web app fetches one only then).
pub fn needs_cjk_font(language: &str) -> bool {
@@ -113,6 +118,34 @@ pub fn is_cjk_font_name(file_name: &str) -> bool {
CJK_FONT_KEYWORDS.iter().any(|k| name.contains(k))
}
/// Lower-case file-name fragments that identify fonts covering simplified Chinese. Deliberately
/// separate from [`CJK_FONT_KEYWORDS`]: many Japanese fonts (Hiragino Gothic, Meiryo, Yu Gothic)
/// match those but lack simplified characters, so a Chinese fallback searches these instead.
pub const CHINESE_FONT_KEYWORDS: &[&str] = &[
"pingfang",
"hiragino sans gb",
"stheiti",
"songti",
"arial unicode",
"msyh",
"yahei",
"simhei",
"simsun",
"wqy",
"wenquanyi",
"notosanscjk",
"notosanssc",
"droidsansfallback",
"sourcehanss",
"siyuan",
];
/// Whether a font file name looks like a font covering simplified Chinese.
pub fn is_chinese_font_name(file_name: &str) -> bool {
let name = file_name.to_ascii_lowercase();
CHINESE_FONT_KEYWORDS.iter().any(|k| name.contains(k))
}
/// Session state of the web app's on-demand CJK font. Pure state so it can be tested off the web:
/// the shell does the fetch when [`CjkFontLoader::tick`] asks for it.
#[derive(Debug, Default)]
@@ -256,6 +289,30 @@ const HANGUL_FONT_CANDIDATES: &[&str] = &[
"/usr/share/fonts/nanum/NanumGothic.ttf",
];
/// Fonts covering simplified Chinese, appended after the CJK fallback so Chinese renders even
/// when the CJK font found is a Japanese one without simplified characters (Hiragino Gothic,
/// Meiryo, Yu Gothic).
#[cfg(not(target_arch = "wasm32"))]
const CHINESE_FONT_CANDIDATES: &[&str] = &[
// Windows: Microsoft YaHei
"C:\\Windows\\Fonts\\msyh.ttc",
"C:\\Windows\\Fonts\\msyh.ttf",
// macOS: PingFang SC, Hiragino Sans GB, Songti SC, STHeiti, Arial Unicode MS
"/System/Library/Fonts/PingFang.ttc",
"/System/Library/Fonts/Hiragino Sans GB.ttc",
"/System/Library/Fonts/STHeiti Light.ttc",
"/System/Library/Fonts/STHeiti Medium.ttc",
"/System/Library/Fonts/Supplemental/Songti.ttc",
"/System/Library/Fonts/Supplemental/Arial Unicode.ttf",
"/Library/Fonts/Arial Unicode.ttf",
// Linux: Noto Sans CJK SC
"/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
"/usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttc",
"/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc",
"/usr/share/fonts/google-noto-cjk/NotoSansCJK-Regular.ttc",
"/usr/share/fonts/truetype/droid/DroidSansFallbackFull.ttf",
];
#[cfg(not(target_arch = "wasm32"))]
fn try_read_font(path: &std::path::Path) -> Option<Vec<u8>> {
if let Ok(bytes) = std::fs::read(path)
@@ -267,9 +324,9 @@ fn try_read_font(path: &std::path::Path) -> Option<Vec<u8>> {
}
}
/// Recursively search for matching CJK font files up to a bounded depth.
/// Recursively search for matching font files up to a bounded depth, testing names with `matches`.
#[cfg(not(target_arch = "wasm32"))]
fn scan_dir_for_font(dir: &std::path::Path, depth_remaining: usize) -> Option<Vec<u8>> {
fn scan_dir_for_font(dir: &std::path::Path, depth_remaining: usize, matches: fn(&str) -> bool) -> Option<Vec<u8>> {
if depth_remaining == 0 {
return None;
}
@@ -282,7 +339,7 @@ fn scan_dir_for_font(dir: &std::path::Path, depth_remaining: usize) -> Option<Ve
let name = p.file_name().map(|n| n.to_string_lossy().to_ascii_lowercase()).unwrap_or_default();
let is_font = name.ends_with(".ttc") || name.ends_with(".ttf") || name.ends_with(".otf");
if is_font
&& is_cjk_font_name(&name)
&& matches(&name)
&& let Some(bytes) = try_read_font(&p)
{
return Some(bytes);
@@ -293,7 +350,7 @@ fn scan_dir_for_font(dir: &std::path::Path, depth_remaining: usize) -> Option<Ve
}
for sub in subdirs {
if let Some(bytes) = scan_dir_for_font(&sub, depth_remaining.saturating_sub(1)) {
if let Some(bytes) = scan_dir_for_font(&sub, depth_remaining.saturating_sub(1), matches) {
return Some(bytes);
}
}
@@ -336,7 +393,7 @@ fn find_system_cjk_font() -> Option<Vec<u8>> {
}
if let Ok(local) = std::env::var("LOCALAPPDATA") {
let user_fonts = std::path::PathBuf::from(local).join("Microsoft").join("Windows").join("Fonts");
if let Some(bytes) = scan_dir_for_font(&user_fonts, 2) {
if let Some(bytes) = scan_dir_for_font(&user_fonts, 2, is_cjk_font_name) {
return Some(bytes);
}
}
@@ -346,7 +403,7 @@ fn find_system_cjk_font() -> Option<Vec<u8>> {
{
let dirs = ["/System/Library/Fonts", "/System/Library/Fonts/Supplemental", "/Library/Fonts"];
for d in dirs {
if let Some(bytes) = scan_dir_for_font(std::path::Path::new(d), 2) {
if let Some(bytes) = scan_dir_for_font(std::path::Path::new(d), 2, is_cjk_font_name) {
return Some(bytes);
}
}
@@ -356,13 +413,13 @@ fn find_system_cjk_font() -> Option<Vec<u8>> {
{
let search_dirs = [std::path::PathBuf::from("/usr/share/fonts"), std::path::PathBuf::from("/usr/local/share/fonts")];
for dir in &search_dirs {
if let Some(bytes) = scan_dir_for_font(dir, 3) {
if let Some(bytes) = scan_dir_for_font(dir, 3, is_cjk_font_name) {
return Some(bytes);
}
}
if let Ok(home) = std::env::var("HOME") {
let user_fonts = std::path::PathBuf::from(home).join(".local/share/fonts");
if let Some(bytes) = scan_dir_for_font(&user_fonts, 2) {
if let Some(bytes) = scan_dir_for_font(&user_fonts, 2, is_cjk_font_name) {
return Some(bytes);
}
}
@@ -371,13 +428,21 @@ fn find_system_cjk_font() -> Option<Vec<u8>> {
None
}
/// Configure font definitions with system CJK and Hangul fallbacks where available.
/// Configure font definitions with system CJK, Chinese and Hangul fallbacks where available.
#[cfg(not(target_arch = "wasm32"))]
pub fn setup_fonts(ctx: &egui::Context) {
let mut fonts = egui::FontDefinitions::default();
let mut found = false;
if let Some(cjk) = find_system_cjk_font().and_then(|bytes| with_cjk_fallback(fonts.clone(), bytes)) {
fonts = cjk;
let cjk = find_system_cjk_font();
if let Some(bytes) = cjk.clone().and_then(|bytes| with_cjk_fallback(fonts.clone(), bytes)) {
fonts = bytes;
found = true;
}
// Chinese after the CJK fallback: a Japanese-only CJK font lacks simplified characters,
// so Chinese falls through to this one per glyph.
let chinese = find_system_chinese_font().filter(|bytes| cjk.as_ref() != Some(bytes));
if let Some(with_chinese) = chinese.and_then(|bytes| with_fallback(fonts.clone(), CHINESE_FALLBACK, bytes)) {
fonts = with_chinese;
found = true;
}
let hangul = HANGUL_FONT_CANDIDATES.iter().find_map(|path| try_read_font(std::path::Path::new(path)));
@@ -390,6 +455,27 @@ pub fn setup_fonts(ctx: &egui::Context) {
}
}
/// Find a font covering simplified Chinese in the known candidate paths or by scanning the
/// system font directories for [`CHINESE_FONT_KEYWORDS`] names.
#[cfg(not(target_arch = "wasm32"))]
fn find_system_chinese_font() -> Option<Vec<u8>> {
for path in CHINESE_FONT_CANDIDATES {
if let Some(bytes) = try_read_font(std::path::Path::new(path)) {
return Some(bytes);
}
}
#[cfg(target_os = "macos")]
{
let dirs = ["/System/Library/Fonts", "/System/Library/Fonts/Supplemental", "/Library/Fonts"];
for d in dirs {
if let Some(bytes) = scan_dir_for_font(std::path::Path::new(d), 2, is_chinese_font_name) {
return Some(bytes);
}
}
}
None
}
/// On web, setup_fonts does not perform synchronous disk reads.
/// Use asynchronous loading through [`solidcraft_web`] or host scripts.
#[cfg(target_arch = "wasm32")]
+86 -1
View File
@@ -35,7 +35,8 @@ static ENGLISH: Catalog = Catalog::new("en", "English", include_str!("locales/en
static JAPANESE: Catalog = Catalog::new("ja", "日本語", include_str!("locales/ja.json"));
static GERMAN: Catalog = Catalog::new("de", "Deutsch", include_str!("locales/de.json"));
static KOREAN: Catalog = Catalog::new("ko", "한국어", include_str!("locales/ko.json"));
pub const LOCALES: &[&Catalog] = &[&ENGLISH, &JAPANESE, &GERMAN, &KOREAN];
static CHINESE: Catalog = Catalog::new("zh", "中文", include_str!("locales/zh.json"));
pub const LOCALES: &[&Catalog] = &[&ENGLISH, &JAPANESE, &GERMAN, &KOREAN, &CHINESE];
pub fn is_supported(id: &str) -> bool {
LOCALES.iter().any(|catalog| catalog.id == id)
@@ -180,6 +181,90 @@ mod tests {
result
}
/// Every English text `label()` can be asked to translate, read straight from the catalogs.
fn english_texts() -> BTreeSet<&'static str> {
ENGLISH.messages().values().map(String::as_str).collect()
}
/// Catalogs delivered complete. English is the source catalog; Japanese was completed
/// upstream and Chinese lands complete here. German and Korean are still partial (they
/// predate the coverage guards), so their gaps are reported by `cargo xtask i18n`
/// without failing the build, while nothing in the two complete catalogs may regress.
const COMPLETE: &[&str] = &["ja", "zh"];
/// `text()` falls back to English silently, so a message a complete locale never received is
/// shown in English inside an otherwise translated UI, with nothing in the build to say so.
/// This is the guard against that: adding a key to `en.json` and forgetting a complete
/// catalog fails here.
#[test]
fn every_complete_catalog_carries_every_english_message() {
let english: Messages = serde_json::from_str(ENGLISH.source).unwrap();
for catalog in LOCALES.iter().filter(|c| COMPLETE.contains(&c.id)) {
let messages: Messages = serde_json::from_str(catalog.source).unwrap();
let missing: Vec<&str> = english.keys().filter(|id| !messages.contains_key(*id)).map(String::as_str).collect();
assert!(missing.is_empty(), "{} is missing {} English message(s): {}", catalog.id, missing.len(), missing.join(", "));
}
}
/// A toolbar tab or panel reaches the UI as a bare source string (`toolbar::TABS`,
/// `CommandSpec::tab` / `.panel`) and is resolved only by `label()`'s English-text lookup, so
/// a heading missing from `en.json` can never translate in any locale. There are a dozen of
/// them, so all of them are required rather than ratcheted.
#[test]
fn every_toolbar_tab_and_panel_is_in_the_english_catalog() {
let texts = english_texts();
let mut wanted: Vec<&str> = crate::toolbar::TABS.to_vec();
wanted.push(crate::toolbar_custom::WORKSPACE);
for spec in solidcraft_engine::command_specs() {
wanted.push(spec.tab);
wanted.push(spec.panel);
}
let mut missing: Vec<&str> = wanted.into_iter().filter(|t| !t.is_empty() && !texts.contains(t)).collect();
missing.sort_unstable();
missing.dedup();
assert!(missing.is_empty(), "toolbar tabs/panels absent from en.json: {missing:?}");
}
/// Every command label the engine can show must exist as an English catalog message.
///
/// `label()` resolves source text coming from the engine by looking that exact English string
/// up in `en.json`, so a label the catalog does not carry stays English in *every* locale —
/// nothing fails, the row just looks untranslated. The whole registry now has entries (their
/// ids are `cmd.<command id>`), so this is a hard requirement rather than a budget: a new
/// command added without a catalog entry fails here.
#[test]
fn every_command_label_is_in_the_english_catalog() {
let texts = english_texts();
let mut untranslated: Vec<&str> = solidcraft_engine::command_specs().iter().map(|c| c.label).filter(|label| !texts.contains(label)).collect();
untranslated.sort_unstable();
untranslated.dedup();
assert!(
untranslated.is_empty(),
"{} command label(s) have no English catalog entry, so they would stay English in every locale: {untranslated:?}",
untranslated.len()
);
}
/// The whole engine registry now reaches the catalogs. Sample command labels from areas that
/// had no entry at all before (sheet metal, inspect, joints, motion) must resolve to their
/// translation rather than echo the English source text — `label()` returns its argument when
/// it finds no English message, so a dropped entry looks like a working English UI.
#[test]
fn newly_catalogued_command_labels_translate() {
let cases = [
("zh", "法兰", "斑马纹分析", "运动研究"),
("ja", "フランジ", "ゼブラ解析", "モーション スタディ"),
("de", "Flansch", "Zebra-Analyse", "Bewegungsuntersuchung"),
("ko", "플랜지", "얼룩말줄무늬 분석", "운동 연구"),
];
for (lang, flange, zebra, motion) in cases {
let locale = Locale::for_language(lang);
for (source, expected) in [("Flange", flange), ("Zebra Analysis", zebra), ("Motion Study", motion)] {
assert_eq!(locale.label(source), expected, "{lang}: {source}");
}
}
}
#[test]
fn catalogs_have_valid_ids_and_matching_placeholders() {
let english: Messages = serde_json::from_str(ENGLISH.source).unwrap();
+129
View File
@@ -0,0 +1,129 @@
//! The context menu and the browser build `Item`s out of English literals, and
//! `Locale::label()` can only translate a literal that exists as an English
//! message. A label the catalog has never seen comes straight back as English
//! and stays English in every locale, with nothing in the build to say so.
//! This reads every menu the app can open and fails on the ones it cannot
//! translate.
use std::collections::BTreeSet;
use crate::browser;
use crate::context_menu::{self, Item, Target};
use crate::{Services, SolveApp};
use serde_json::json;
use solidcraft_engine::Session;
fn sample_app() -> SolveApp {
let mut s = Session::default();
s.run_script(&solidcraft_engine::sample::script()).expect("sample script");
SolveApp::new(s, Services::default())
}
/// Every English text `label()` can be asked to translate.
fn english_texts() -> BTreeSet<String> {
const EN: &str = include_str!("locales/en.json");
let messages: serde_json::Map<String, serde_json::Value> = serde_json::from_str(EN).expect("en.json is valid JSON");
messages.values().filter_map(|v| v.as_str().map(str::to_string)).collect()
}
/// Separators carry no text; section headings are real text and are checked.
fn translatable(items: &[Item]) -> impl Iterator<Item = &str> {
items.iter().map(|i| i.label.as_str()).filter(|l| !l.is_empty())
}
fn take(app: &SolveApp, out: &mut BTreeSet<String>) {
let state = app.session.model.state();
let bodies: Vec<String> = state.bodies.iter().map(|b| b.name.clone()).collect();
let features: Vec<u64> = app.session.doc.features.iter().map(|f| f.id).collect();
let components: Vec<u64> = app.session.doc.components.iter().map(|c| c.id).collect();
let groups: Vec<u64> = app.session.doc.browser_groups.iter().map(|g| g.id).collect();
for target in [Target::Viewport, Target::Origin, Target::Units, Target::Toolbar, Target::Workspace, Target::NamedViews] {
take_items(out, &context_menu::items(app, &target));
}
for name in &bodies {
take_items(out, &context_menu::items(app, &Target::Body { name: name.clone() }));
}
for name in ["Named View1", "Front detail"] {
take_items(out, &context_menu::items(app, &Target::NamedView { name: name.to_string() }));
}
for id in &features {
take_items(out, &context_menu::items(app, &Target::Sketch { id: *id }));
}
for id in &components {
take_items(out, &context_menu::items(app, &Target::Component { id: *id }));
for folder in ["bodies", "sketches", "construction"] {
take_items(out, &context_menu::items(app, &Target::Folder { component: *id, folder: folder.to_string() }));
take_items(out, &browser::folder_items(app, *id, folder));
}
}
for id in &groups {
take_items(out, &context_menu::items(app, &Target::Group { id: *id }));
take_items(out, &browser::group_items(app, *id));
}
for spec in solidcraft_engine::command_specs().iter() {
let target = Target::ToolbarCommand { id: spec.id.to_string() };
take_items(out, &context_menu::items(app, &target));
}
}
fn take_items(out: &mut BTreeSet<String>, items: &[Item]) {
for label in translatable(items) {
out.insert(label.to_string());
}
}
/// A label the catalog has never seen can never translate, and the item's own
/// text is the only witness. Every menu label the app can draw must therefore
/// exist as an English message. The sample design's names are data, not text,
/// and are left alone.
#[test]
fn every_menu_label_is_in_the_english_catalog() {
let mut app = sample_app();
let mut seen = BTreeSet::new();
take(&app, &mut seen);
// The labels that depend on state, so their other branch is seen too.
let names: Vec<String> = app.session.model.state().bodies.iter().map(|b| b.name.clone()).collect();
app.ui.show_origin = false;
take(&app, &mut seen);
for name in &names {
app.ui.locked_bodies.push(name.clone());
app.session.visibility.hidden_bodies.push(name.clone());
}
take(&app, &mut seen);
app.ui.locked_bodies.clear();
app.session.visibility.hidden_bodies.clear();
take(&app, &mut seen);
// A menu that stops yielding labels would empty `seen` and turn the
// whole test into a tautology, so the sweep has to stay broad.
assert!(seen.len() > 40, "the sweep only reached {} label(s)", seen.len());
let texts = english_texts();
let mut missing: Vec<&str> = seen
.iter()
// Unit symbols are the same word in every language: `mm` is `mm` in
// Chinese and in German, so they are not prose to translate.
.filter(|l| !texts.contains(l.as_str()) && !crate::prefs::UNITS.contains(&l.as_str()))
.map(String::as_str)
.collect();
missing.sort_unstable();
assert!(missing.is_empty(), "{} menu label(s) have no English catalog entry, so they stay English in every locale: {:?}", missing.len(), missing);
}
/// The control channel and scripts call `run()` outside a render language scope, so the
/// "command done" echo must follow the saved preference rather than the thread-local scope
/// (otherwise its template falls back to English: "撤销 done" instead of "撤销 完成").
#[test]
fn command_done_echo_follows_the_language_preference_without_a_render_scope() {
let mut app = SolveApp::new(Session::default(), Services::default());
app.preferences.language = "zh".into();
app.run("solid.box", json!({ "length": 5, "width": 5, "height": 5 })).expect("box");
let echo = app.session.log.last().expect("the echo is logged");
let zh = crate::i18n::Locale::for_language("zh");
let expected = zh.format("ui.command_done", &[("command", zh.label(crate::command_label("solid.box")))]);
assert_eq!(echo, &expected);
assert!(echo.contains("完成"), "{echo}");
assert!(!echo.ends_with("done"), "{echo}");
}
+39
View File
@@ -54,6 +54,45 @@ fn language_preference_cancel_restores_previous_locale() {
assert_eq!(h.app.tr("ui.preferences"), "Preferences");
}
/// The chrome a user sees before touching anything: the browser heading and the SELECT panel.
/// Both were English literals in the drawing code, and a broken message id falls back to
/// English silently, so check the word actually rendered in each language.
#[test]
fn window_chrome_renders_in_the_active_language() {
for (lang, browser, filter, faces) in [
("zh", "浏览器", "选择筛选", "面"),
("ja", "ブラウザ", "選択フィルター", "面"),
("de", "BROWSER", "Auswahlfilter", "Flächen"),
("ko", "브라우저", "선택 필터", "면"),
] {
let mut h = Harness::new();
h.app.preferences.language = lang.into();
h.app.home.open = false;
h.frames(2);
// The browser heading is on screen from the start; the selection filter lives in the
// SELECT panel, which is not the one shown by default.
assert!(h.widget(browser).is_some(), "{lang}: the browser heading must show {browser:?}");
let select = scenario::handle_at("panel:SOLID:SELECT").expect("the SELECT panel is on the SOLID tab");
h.step(&json!({"click": [select.x, select.y]})).unwrap();
h.frames(2);
assert!(h.widget(filter).is_some(), "{lang}: the selection filter must show {filter:?}");
assert!(h.widget(faces).is_some(), "{lang}: the Faces checkbox must show {faces:?}");
}
}
/// The command palette's hint embeds a JSON example, so its braces must not be mistaken for a
/// placeholder name by the catalog's parser, and the example must survive interpolation whole.
#[test]
fn command_palette_hint_keeps_its_json_example_intact() {
let mut h = Harness::new();
h.app.preferences.language = "zh".into();
h.app.home.open = false;
h.frames(2);
let hint = crate::i18n::format("ui.command_palette_hint", &[("example", "Extrude {\"distance\": 20}")]);
assert!(hint.contains("Extrude {\"distance\": 20}"), "the example is inserted literally: {hint:?}");
assert!(!hint.contains("{example}"), "the placeholder is substituted: {hint:?}");
}
#[test]
fn translated_dialog_buttons_do_not_wrap() {
fn cancel_rows(shape: &egui::Shape) -> Option<usize> {
+9 -1
View File
@@ -40,6 +40,8 @@ mod hole_placement_ui_tests;
pub mod home;
pub mod i18n;
#[cfg(test)]
mod i18n_menu_tests;
#[cfg(test)]
mod i18n_ui_tests;
pub mod icons;
pub mod inference;
@@ -494,7 +496,13 @@ impl SolveApp {
}
match &r {
Ok(_) => {
self.session.echo(format!("{} done", command_label(id)));
// Programmatic callers (the control channel, scripts) run outside a render
// language scope, so resolve the echo from the saved preference instead of the
// thread-local scope. The command's own label is translated too, so the echo
// reads the same way the toolbar button it came from does.
let language = i18n::Locale::for_language(&self.preferences.language);
let label = language.label(command_label(id));
self.session.echo(language.format("ui.command_done", &[("command", label)]));
if matches!(id, "file.new" | "doc.open" | "doc.recover") {
self.sketch_choices = sketch_families::Choices::default();
dim_view::cancel();
+359 -6
View File
@@ -65,14 +65,15 @@
"ui.combine": "Kombinieren",
"ui.coming_later": "bald verfügbar",
"ui.concentric": "Konzentrisch",
"ui.configurations": "Konfigurationen",
"ui.conic_curve": "Kegelschnitt",
"ui.constant": "Konstant",
"ui.constraints_conflict": "Bedingungen konfliktreich",
"ui.construct": "Konstruktion",
"ui.construction": "Konstruktionslinie",
"ui.copy": "Kopieren",
"ui.corner": "Ecke",
"ui.corners": "Ecken",
"ui.corner": "Ecke",
"ui.counterbore": "Tiefenbohrung",
"ui.countersink": "Senkung",
"ui.create": "Erstellen",
@@ -112,6 +113,7 @@
"ui.extent_type": "Ausdehnungstyp",
"ui.extrude": "Extrudieren",
"ui.factor": "Faktor",
"ui.feature_history": "Feature-Verlauf",
"ui.feature_options": "Funktionsoptionen",
"ui.features": "Funktionen",
"ui.file": "Datei",
@@ -249,8 +251,8 @@
"ui.profile_plane": "Profilebene",
"ui.profiles": "Profile",
"ui.project": "Projizieren",
"ui.quantity": "Anzahl",
"ui.quantity_2": "Anzahl 2",
"ui.quantity": "Anzahl",
"ui.quit": "Beenden",
"ui.radius": "Radius",
"ui.radius_type": "Radius-Typ",
@@ -273,7 +275,6 @@
"ui.shell": "Hülle",
"ui.show": "Einblenden",
"ui.show_constraints": "Bedingungen",
"ui.show_construction_geometries": "Konstruktionsgeometrien",
"ui.show_dimensions": "Maße",
"ui.show_points": "Punkte anzeigen",
"ui.show_profile": "Profil anzeigen",
@@ -291,8 +292,8 @@
"ui.slot": "Langloch",
"ui.smooth": "Glatt",
"ui.snap": "Einrasten",
"ui.spacing": "Abstand",
"ui.spacing_2": "Abstand 2",
"ui.spacing": "Abstand",
"ui.sphere": "Sphäre",
"ui.spline": "Spline",
"ui.split_body": "Körper trennen",
@@ -309,11 +310,13 @@
"ui.theme": "Design",
"ui.thickness": "Dicke",
"ui.thread": "Gewinde",
"ui.timeline_bottom": "Timeline unten",
"ui.timeline_left_note": "Im linken Layout wird die Rücksetzmarke über dem Teile- und Szenenbrowser eingeblendet.",
"ui.timeline_left_sidebar": "Linke Seitenleiste",
"ui.tip_angle": "Spitzenwinkel",
"ui.to_object": "Bis Objekt",
"ui.top": "Oben",
"ui.torus": "Torus",
"ui.total_angle": "Gesamtwinkel",
"ui.trim": "Kürzen",
"ui.two_sides": "Beidseitig",
"ui.ui_scale": "UI-Skalierung",
@@ -325,9 +328,359 @@
"ui.view_centre": "Ansichtszentrum",
"ui.visual_style": "Ansichtsstil",
"ui.workspace": "Arbeitsbereich",
"ui.x_distance": "X-Abstand",
"ui.y_distance": "Y-Abstand",
"ui.x_distance": "X-Abstand",
"ui.zoom_to_the_cursor": "Zum Cursor zoomen",
"ui.animateJoint": "Gelenk animieren",
"ui.calibrate": "Kalibrieren",
"ui.customizeToolbar": "Symbolleiste anpassen…",
"ui.editJointLimits": "Gelenkgrenzen bearbeiten",
"ui.exportDxf": "Als DXF exportieren…",
"ui.findInTimeline": "In der Zeitleiste suchen",
"ui.findInWindow": "Im Fenster suchen",
"ui.fit": "Einpassen",
"ui.groupSelected": "Auswahl gruppieren",
"ui.hideAxes": "Achsen ausblenden",
"ui.hideDimension": "Bemaßung ausblenden",
"ui.hideOrigin": "Ursprung ausblenden",
"ui.hidePlanes": "Ebenen ausblenden",
"ui.hideProfile": "Profil ausblenden",
"ui.homeView": "Startansicht",
"ui.isolate": "Isolieren",
"ui.lock": "Sperren",
"ui.newSketchGroup": "Neue Skizzengruppe",
"ui.normalConstruction": "Normal / Konstruktion",
"ui.orbit": "Drehen",
"ui.heading_position": "POSITION",
"ui.pan": "Verschieben",
"ui.pinToShortcuts": "An Verknüpfungen anheften",
"ui.pinToToolbar": "An Symbolleiste anheften",
"ui.properties": "Eigenschaften",
"ui.removeSection": "Schnitt entfernen",
"ui.removeFromToolbar": "Aus der Symbolleiste entfernen",
"ui.repeat": "Wiederholen",
"ui.report_a_bug": "Fehler melden",
"ui.restore": "Wiederherstellen",
"ui.heading_setup": "EINRICHTEN",
"ui.selectOther": "Andere auswählen…",
"ui.selectTangentChain": "Tangentialkette auswählen",
"ui.showAll": "Alle einblenden",
"ui.showAllBodies": "Alle Volumenkörper einblenden",
"ui.showAxes": "Achsen einblenden",
"ui.showDimension": "Bemaßung einblenden",
"ui.showOrigin": "Ursprung einblenden",
"ui.showPlanes": "Ebenen einblenden",
"ui.suppress": "Unterdrücken",
"ui.command_palette_hint": "Befehl eingeben, z. B. {example} — oder S drücken, um zu suchen",
"ui.unground": "Fixierung lösen",
"ui.unisolate": "Isolierung aufheben",
"ui.unlock": "Entsperren",
"ui.unsuppress": "Unterdrückung aufheben",
"ui.updateToCurrentView": "Auf aktuelle Ansicht aktualisieren",
"ui.zoom": "Zoomen",
"ui.command_done": "{command} fertig",
"cmd.appearance_assign": "Erscheinungsbild",
"cmd.appearance_library": "Erscheinungsbild-Bibliothek",
"cmd.appearance_list": "Erscheinungsbilder auflisten",
"cmd.body_rename": "Körper umbenennen",
"cmd.browser_group": "Neue Gruppe",
"cmd.browser_move": "Browser-Elemente verschieben",
"cmd.browser_order": "Browser-Elemente ordnen",
"cmd.browser_rename_group": "Gruppe umbenennen",
"cmd.browser_ungroup": "Gruppierung aufheben",
"cmd.browser_visibility": "Ein-/Ausblenden",
"cmd.canvas_calibrate": "Zeichenfläche kalibrieren",
"cmd.canvas_decal": "Dekal",
"cmd.canvas_delete": "Zeichenfläche löschen",
"cmd.canvas_edit": "Zeichenfläche bearbeiten",
"cmd.canvas_insert": "Zeichenfläche",
"cmd.component_activate": "Komponente aktivieren",
"cmd.component_break_link": "Verknüpfung trennen",
"cmd.component_capture_position": "Position erfassen",
"cmd.component_create": "Neue Komponente",
"cmd.component_delete": "Komponente löschen",
"cmd.component_from_bodies": "Komponenten aus Körpern erstellen",
"cmd.component_insert_design": "Konstruktion einfügen",
"cmd.component_links": "Verknüpfungen auflisten",
"cmd.component_list": "Komponenten auflisten",
"cmd.component_move_bodies": "Körper in Komponente verschieben",
"cmd.component_move_sketches": "Skizzen in Komponente verschieben",
"cmd.component_paste_new": "Neu einfügen",
"cmd.component_properties": "Physikalische Eigenschaften der Komponente",
"cmd.component_rename": "Komponente umbenennen",
"cmd.component_revert_position": "Position zurücksetzen",
"cmd.component_update_links": "Verknüpfungen aktualisieren",
"cmd.config_activate": "Konfiguration aktivieren",
"cmd.config_column": "Konfigurationsspalte",
"cmd.config_configure": "Konfigurieren",
"cmd.config_preview": "Konfiguration vorschauen",
"cmd.config_row": "Konfigurationszeile",
"cmd.config_rule": "Konfigurationsregel",
"cmd.config_rules": "Konfigurationsregeln",
"cmd.config_table": "Konfigurationstabelle anzeigen",
"cmd.construct_axis_edge": "Achse durch Kante",
"cmd.construct_axis_normal_to_face": "Achse senkrecht zur Fläche",
"cmd.construct_axis_through_cylinder": "Achse durch Zylinder/Kegel/Torus",
"cmd.construct_axis_two_planes": "Achse durch zwei Ebenen",
"cmd.construct_axis_two_points": "Achse durch zwei Punkte",
"cmd.construct_plane_along_path": "Ebene entlang Pfad",
"cmd.construct_plane_midplane": "Mittenebene",
"cmd.construct_plane_perpendicular": "Rechtebene",
"cmd.construct_plane_tangent": "Tangentialebene",
"cmd.construct_plane_three_points": "Ebene durch drei Punkte",
"cmd.construct_plane_two_edges": "Ebene durch zwei Kanten",
"cmd.construct_point_along_path": "Punkt entlang Pfad",
"cmd.construct_point_center": "Punkt im Mittelpunkt von Kreis/Kugel/Torus",
"cmd.construct_point_edge_plane": "Punkt an Kante und Ebene",
"cmd.construct_point_three_planes": "Punkt aus drei Ebenen",
"cmd.construct_point_two_edges": "Punkt aus zwei Kanten",
"cmd.construct_point_vertex": "Punkt an Scheitelpunkt",
"cmd.contact_check": "Kontakt prüfen",
"cmd.contact_create": "Neuer Kontaktsatz",
"cmd.contact_disable_all": "Kontakt deaktivieren",
"cmd.contact_edit": "Kontaktsatz bearbeiten",
"cmd.contact_enable_all": "Alle Kontakte aktivieren",
"cmd.contact_enable_sets": "Kontaktsätze aktivieren",
"cmd.contact_list": "Kontaktsätze auflisten",
"cmd.diagnostics_crash_report": "Absturzbericht",
"cmd.diagnostics_crash_reports": "Absturzberichte",
"cmd.diagnostics_crash_reports_clear": "Absturzberichte löschen",
"cmd.diagnostics_crash_test": "Absturztest",
"cmd.doc_recover": "Konstruktion wiederherstellen",
"cmd.doc_recovery_discard": "Wiederhergestellte Konstruktion verwerfen",
"cmd.doc_recovery_list": "Wiederherstellbare Konstruktionen",
"cmd.document_inspect": "Konstruktion prüfen",
"cmd.document_units": "Einheiten der Konstruktion ändern",
"cmd.edit_checkpoint": "Prüfpunkt",
"cmd.edit_restore_checkpoint": "Prüfpunkt wiederherstellen",
"cmd.engine_commands": "Befehle auflisten",
"cmd.explode_create": "Explosionsdarstellung",
"cmd.explode_delete": "Explosionsdarstellung löschen",
"cmd.explode_list": "Explosionsdarstellungen auflisten",
"cmd.explode_show": "Explosionsdarstellung anzeigen",
"cmd.expr_evaluate": "Ausdruck auswerten",
"cmd.face_delete": "Fläche löschen",
"cmd.file_export": "Exportieren",
"cmd.file_insert_mesh": "Netz einfügen",
"cmd.file_insert_step": "STEP einfügen",
"cmd.file_save_mesh": "Als Netz speichern",
"cmd.inspect_accessibility": "Zugänglichkeitsanalyse",
"cmd.inspect_center_of_mass": "Massenschwerpunkt",
"cmd.inspect_curvature_comb": "Krümmungskamm-Analyse",
"cmd.inspect_curvature_map": "Krümmungskartenanalyse",
"cmd.inspect_draft": "Auswinkelanalyse",
"cmd.inspect_environment_map": "Umgebungskartenanalyse",
"cmd.inspect_interference": "Eingriff",
"cmd.inspect_isocurve": "Isokurvenanalyse",
"cmd.inspect_minimum_radius": "Mindestradiusanalyse",
"cmd.inspect_zebra": "Zebra-Analyse",
"cmd.joint_as_built": "Fertigungsgelenk",
"cmd.joint_create": "Gelenk",
"cmd.joint_delete": "Gelenk löschen",
"cmd.joint_drive": "Gelenke antreiben",
"cmd.joint_edit": "Gelenk bearbeiten",
"cmd.joint_limits": "Gelenkgrenzen",
"cmd.joint_list": "Gelenke auflisten",
"cmd.joint_motion_link": "Bewegungsverknüpfung",
"cmd.joint_origin": "Gelenkursprung",
"cmd.joint_rigid_group": "Starrgruppe",
"cmd.joint_solve": "Gelenke lösen",
"cmd.material_assign": "Physikalisches Material",
"cmd.material_create": "Neues physikalisches Material",
"cmd.material_delete": "Physisches Material löschen",
"cmd.material_edit": "Physisches Material bearbeiten",
"cmd.material_list": "Materialien auflisten",
"cmd.mesh_convert": "Netz konvertieren",
"cmd.model_edges": "Kanten auflisten",
"cmd.model_faces": "Flächen auflisten",
"cmd.model_threads": "Gewinde auflisten",
"cmd.motion_delete": "Bewegungsuntersuchung löschen",
"cmd.motion_export": "Bewegungsuntersuchung exportieren",
"cmd.motion_list": "Bewegungsuntersuchungen auflisten",
"cmd.motion_play": "Bewegungsuntersuchung abspielen",
"cmd.motion_study": "Bewegungsuntersuchung",
"cmd.occurrence_copy": "Einfügen (Instanz)",
"cmd.occurrence_ground": "Festsetzen",
"cmd.occurrence_move": "Instanz verschieben",
"cmd.occurrence_properties": "Physikalische Eigenschaften der Instanz",
"cmd.parameters_add": "Benutzerparameter hinzufügen",
"cmd.parameters_change": "Parameter ändern",
"cmd.parameters_comment": "Parameter kommentieren",
"cmd.parameters_complete": "Ausdruck vervollständigen",
"cmd.parameters_delete": "Parameter löschen",
"cmd.parameters_export": "Parameter exportieren",
"cmd.parameters_favorite": "Favorisierter Parameter",
"cmd.parameters_graph": "Parametergraph",
"cmd.parameters_import": "Parameter importieren",
"cmd.parameters_list": "Parameter auflisten",
"cmd.parameters_rename": "Parameter umbenennen",
"cmd.parameters_users": "Parameterverwendungen",
"cmd.parts_fastener": "Verbindungselement einfügen",
"cmd.parts_insert": "Bauteil einfügen",
"cmd.parts_library": "Standardbauteile",
"cmd.parts_resize": "Bauteilgröße ändern",
"cmd.plastic_assign_rule": "Kunststoffregel zuweisen",
"cmd.plastic_boss": "Erhöhung",
"cmd.plastic_lip": "Lippe",
"cmd.plastic_manage_rules": "Kunststoffregeln verwalten",
"cmd.plastic_rest": "Auflage",
"cmd.plastic_rules": "Kunststoffregeln auflisten",
"cmd.plastic_snap_fit": "Rastverbindung",
"cmd.select_clear": "Auswahl aufheben",
"cmd.sheet_convert": "In Blech umwandeln",
"cmd.sheet_export_bend_table": "Biegungstabelle exportieren",
"cmd.sheet_export_dxf": "Flachmuster als DXF exportieren",
"cmd.sheet_flange": "Flansch",
"cmd.sheet_flat_pattern": "Flachmuster erstellen",
"cmd.sheet_fold": "Falten",
"cmd.sheet_hem": "Umkantung",
"cmd.sheet_manage_rules": "Blechregeln",
"cmd.sheet_refold": "Wieder falten",
"cmd.sheet_rules": "Blechregeln auflisten",
"cmd.sheet_unfold": "Entfalten",
"cmd.sketch_arc_center_point": "Mittelpunkt-Kreisbogen",
"cmd.sketch_arc_tangent": "Tangentialbogen",
"cmd.sketch_arc_three_point": "3-Punkt-Kreisbogen",
"cmd.sketch_auto_constrain": "Auto-Bedingung",
"cmd.sketch_auto_constrain_from_datum": "Auto-Bedingung von Bezug",
"cmd.sketch_auto_project": "Kanten automatisch auf Referenz projizieren",
"cmd.sketch_blend_curve": "Übergangskurve",
"cmd.sketch_chain": "Kette",
"cmd.sketch_chamfer_distance_angle": "Abschrägung mit Abstand und Winkel",
"cmd.sketch_chamfer_equal_distance": "Abschrägung mit gleichem Abstand",
"cmd.sketch_chamfer_two_distance": "Abschrägung mit zwei Abständen",
"cmd.sketch_circle_center": "Kreis aus Mittelpunkt und Durchmesser",
"cmd.sketch_circle_three_point": "3-Punkt-Kreis",
"cmd.sketch_circle_three_tangent": "3-Tangenten-Kreis",
"cmd.sketch_circle_two_point": "2-Punkt-Kreis",
"cmd.sketch_circle_two_tangent": "2-Tangenten-Kreis",
"cmd.sketch_constrainer": "Skizzen-Bedingung",
"cmd.sketch_constraint_fix": "Fixieren/Lösen",
"cmd.sketch_constraint_midpoint": "Mittelpunkt",
"cmd.sketch_construction": "Normal/Konstruktion",
"cmd.sketch_delete": "Skizzenentitäten löschen",
"cmd.sketch_dimension_text": "Maßtext verschieben",
"cmd.sketch_drag": "Skizzengeometrie ziehen",
"cmd.sketch_drag_end": "Skizzen-Ziehen beenden",
"cmd.sketch_draw_dimensioned": "Skizzengeometrie mit Maßen zeichnen",
"cmd.sketch_edit": "Skizze bearbeiten",
"cmd.sketch_edit_text": "Text bearbeiten",
"cmd.sketch_export_dxf": "Als DXF speichern",
"cmd.sketch_finish_auto_constrain": "Mit Auto-Bedingung fertigstellen",
"cmd.sketch_fit_curves_to_section": "Kurven an Netzquerschnitt anpassen",
"cmd.sketch_glyphs": "Bedingungssymbole",
"cmd.sketch_include_3d": "3D-Geometrie einbeziehen",
"cmd.sketch_insert_dxf": "DXF einfügen",
"cmd.sketch_insert_svg": "SVG einfügen",
"cmd.sketch_inspect": "Skizze prüfen",
"cmd.sketch_intersection_curve": "Schnittkurve",
"cmd.sketch_isoparametric_curve": "Isoparametrische Kurve",
"cmd.sketch_line3d": "3D-Linie",
"cmd.sketch_line_midpoint": "Linie über den Mittelpunkt",
"cmd.sketch_move": "Skizzenentitäten verschieben/kopieren",
"cmd.sketch_move3d": "3D-Punkt verschieben",
"cmd.sketch_move_point": "Skizzenpunkt ziehen",
"cmd.sketch_offset_break": "Versatzverknüpfung trennen",
"cmd.sketch_options": "Skizzenpalettenoptionen",
"cmd.sketch_point3d": "3D-Punkt",
"cmd.sketch_polygon_circumscribed": "Umgeschriebenes Polygon",
"cmd.sketch_polygon_edge": "Polygon über eine Kante",
"cmd.sketch_polygon_inscribed": "Eingeschriebenes Polygon",
"cmd.sketch_project_to_surface": "Auf Fläche projizieren",
"cmd.sketch_rectangle_center": "Rechteck vom Mittelpunkt",
"cmd.sketch_rectangle_three_point": "3-Punkt-Rechteck",
"cmd.sketch_rectangle_two_point": "2-Punkt-Rechteck",
"cmd.sketch_redefine": "Skizzierebene neu definieren",
"cmd.sketch_slot_arc_center": "Mittelpunkt-Bogenschlitz",
"cmd.sketch_slot_arc_three_point": "3-Punkt-Bogenschlitz",
"cmd.sketch_slot_center_point": "Mittelpunktschlitz",
"cmd.sketch_slot_center_to_center": "Schlitz von Mittelpunkt zu Mittelpunkt",
"cmd.sketch_slot_overall": "Gesamtschlitz",
"cmd.sketch_snap": "Einrastinferenz",
"cmd.sketch_solve": "Skizze lösen",
"cmd.sketch_spline3d": "3D-Spline",
"cmd.sketch_spline_control_point": "Spline mit Kontrollpunkten",
"cmd.sketch_spline_control_point_5": "Spline mit Kontrollpunkten (Grad 5)",
"cmd.sketch_spline_fit_point": "Spline mit Fitpunkten",
"cmd.sketch_spun_profile": "Gedrehtes Profil",
"cmd.sketch_toggle_driven": "Abhängiges Maß umschalten",
"cmd.solid_align": "Ausrichten",
"cmd.solid_boundary_fill": "Begrenzungsfüllung",
"cmd.solid_bounding_solid": "Begrenzender Körper",
"cmd.solid_emboss": "Prägen",
"cmd.solid_move": "Verschieben/Kopieren",
"cmd.solid_offset_face": "Fläche versetzen",
"cmd.solid_press_pull": "Drücken/Ziehen",
"cmd.solid_remove": "Entfernen",
"cmd.solid_replace_face": "Fläche ersetzen",
"cmd.solid_rib": "Rippe",
"cmd.solid_split_face": "Fläche teilen",
"cmd.solid_web": "Gewebe",
"cmd.surface_patch": "Patch",
"cmd.surface_stitch": "Nähen",
"cmd.surface_thicken": "Dicke vergeben",
"cmd.surface_extrude": "Flächen-Extrusion",
"cmd.surface_revolve": "Flächen-Rotation",
"cmd.surface_sweep": "Flächen-Sweep",
"cmd.surface_loft": "Flächen-Loft",
"cmd.surface_ruled": "Regelfläche",
"cmd.surface_boundary": "Begrenzungsfläche",
"cmd.surface_offset": "Offsetfläche",
"cmd.surface_blend": "Verbindungsfläche",
"cmd.surface_fillet": "Flächenverrundung",
"cmd.surface_untrim": "Trimmen aufheben",
"cmd.surface_unstitch": "Verbund aufheben",
"cmd.surface_reverse_normal": "Normale umkehren",
"cmd.inspect_continuity": "Kontinuitätsprüfung",
"cmd.timeline_compute_all": "Alles berechnen",
"cmd.timeline_copy": "Merkmale kopieren",
"cmd.timeline_dependents": "Merkmalsabhängigkeiten",
"cmd.timeline_inspect": "Merkmal prüfen",
"cmd.timeline_paste": "Merkmale einfügen",
"cmd.timeline_redefine": "Merkmal bearbeiten",
"cmd.timeline_rename": "Umbenennen",
"cmd.timeline_reorder": "Merkmal neu ordnen",
"cmd.timeline_roll_to": "Verlaufsmarkierung verschieben",
"cmd.timeline_rollback": "Zeitleistenmarkierung verschieben",
"cmd.timeline_suppress": "Merkmal unterdrücken",
"cmd.view_apply": "Benannte Ansicht wiederherstellen",
"cmd.view_delete": "Benannte Ansicht löschen",
"cmd.view_list": "Benannte Ansichten auflisten",
"cmd.view_rename": "Benannte Ansicht umbenennen",
"cmd.view_save": "Neue benannte Ansicht",
"ui.export_ellipsis_keymap": "Exportieren…",
"ui.heading_configure": "KONFIGURIEREN",
"ui.heading_constraints": "RANDBEDINGUNGEN",
"ui.heading_utilities": "WERKZEUGE",
"BROWSER": "BROWSER",
"Drive Joint": "Gelenk antreiben",
"Edit Profile Sketch": "Profile-Skizze bearbeiten",
"Find in Browser": "Im Browser suchen",
"Report a bug — review a screenshot and open a GitHub draft": "Fehler melden — Screenshot prüfen und einen GitHub-Entwurf öffnen",
"Reset Toolbar": "Symbolleiste zurücksetzen",
"Select bodies (a face picks its body)": "Körper auswählen (eine Fläche wählt ihren Körper)",
"Selection filter": "Auswahlfilter",
"Revert Position": "Position zurücksetzen",
"Construction": "Konstruktionslinie",
"Faces": "Flächen",
"Edges": "Kanten",
"Vertices": "Scheitelpunkte",
"Sketch geometry and profiles": "Skizzengeometrie und Profile",
"Sketch curves": "Skizzenkurven",
"Sketch points": "Skizzenpunkte",
"Sketch dimensions": "Skizzenmaße",
"Sketch constraints": "Skizzenbedingungen",
"Flat": "Flach",
"cmd.render_backends": "Render-Backends",
"cmd.view_navigate": "Ansicht navigieren",
"timeline.group": "Neuen Merkmalsordner anlegen",
"timeline.ungroup": "Merkmalsordner entfernen",
"timeline.rename_group": "Merkmalsordner umbenennen",
"timeline.move_to_group": "Merkmale in Ordner verschieben",
"timeline.move_many": "Zeitleistenelemente verschieben",
"timeline.reorder_many": "Merkmale neu ordnen",
"ui.show_construction_geometries": "Konstruktionsgeometrien",
"ui.total_angle": "Gesamtwinkel",
"sketch_text.builtin_font": "{family} (integriert)",
"sketch_text.font_search": "Schriftarten suchen",
"sketch_text.loading_fonts": "Installierte Schriftarten werden gesucht…",
+75 -3
View File
@@ -245,6 +245,19 @@
"cmd.surface_patch": "Patch",
"cmd.surface_stitch": "Stitch",
"cmd.surface_thicken": "Thicken",
"cmd.surface_extrude": "Surface Extrude",
"cmd.surface_revolve": "Surface Revolve",
"cmd.surface_sweep": "Surface Sweep",
"cmd.surface_loft": "Surface Loft",
"cmd.surface_ruled": "Ruled Surface",
"cmd.surface_boundary": "Boundary Surface",
"cmd.surface_offset": "Offset Surface",
"cmd.surface_blend": "Blend Surface",
"cmd.surface_fillet": "Surface Fillet",
"cmd.surface_untrim": "Untrim",
"cmd.surface_unstitch": "Unstitch",
"cmd.surface_reverse_normal": "Reverse Normal",
"cmd.inspect_continuity": "Continuity Analysis",
"cmd.timeline_compute_all": "Compute All",
"cmd.timeline_copy": "Copy Features",
"cmd.timeline_dependents": "Feature Dependents",
@@ -326,6 +339,7 @@
"ui.combine": "Combine",
"ui.coming_later": "coming later",
"ui.concentric": "Concentric",
"ui.configurations": "Configurations",
"ui.conic_curve": "Conic Curve",
"ui.constant": "Constant",
"ui.constraints_conflict": "Constraints conflict",
@@ -376,6 +390,7 @@
"ui.extent_type": "Extent Type",
"ui.extrude": "Extrude",
"ui.factor": "Factor",
"ui.feature_history": "Feature history",
"ui.feature_options": "Feature Options",
"ui.features": "Features",
"ui.file": "File",
@@ -556,7 +571,6 @@
"ui.shell": "Shell",
"ui.show": "Show",
"ui.show_constraints": "Constraints",
"ui.show_construction_geometries": "Construction Geometries",
"ui.show_dimensions": "Dimensions",
"ui.show_points": "Show Points",
"ui.show_profile": "Show Profile",
@@ -597,11 +611,13 @@
"ui.theme": "Theme",
"ui.thickness": "Thickness",
"ui.thread": "Thread",
"ui.timeline_bottom": "Bottom timeline",
"ui.timeline_left_note": "The left layout shows the rollback bar above the parts and scene browser.",
"ui.timeline_left_sidebar": "Left sidebar",
"ui.tip_angle": "Tip Angle",
"ui.to_object": "To Object",
"ui.top": "Top",
"ui.torus": "Torus",
"ui.total_angle": "Total angle",
"ui.trackpad_pan_tip": "Trackpad gestures pan (off: they zoom like the wheel); mouse wheel zooms, thumb wheel pans sideways, pinch always zooms",
"ui.trim": "Trim",
"ui.two_finger_scroll_pans": "Two-finger scroll pans",
@@ -862,6 +878,62 @@
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).",
"cmd.render_backends": "Render Backends",
"cmd.view_navigate": "Navigate View",
"ui.animateJoint": "Animate Joint",
"ui.calibrate": "Calibrate",
"ui.customizeToolbar": "Customize Toolbar…",
"ui.editJointLimits": "Edit Joint Limits",
"ui.exportDxf": "Export DXF…",
"ui.findInTimeline": "Find in Timeline",
"ui.findInWindow": "Find in Window",
"ui.fit": "Fit",
"ui.groupSelected": "Group Selected",
"ui.hideAxes": "Hide Axes",
"ui.hideDimension": "Hide Dimension",
"ui.hideOrigin": "Hide Origin",
"ui.hidePlanes": "Hide Planes",
"ui.hideProfile": "Hide Profile",
"ui.homeView": "Home View",
"ui.isolate": "Isolate",
"ui.lock": "Lock",
"ui.newSketchGroup": "New Sketch Group",
"ui.normalConstruction": "Normal / Construction",
"ui.orbit": "Orbit",
"ui.heading_position": "POSITION",
"ui.pan": "Pan",
"ui.pinToShortcuts": "Pin to Shortcuts",
"ui.pinToToolbar": "Pin to Toolbar",
"ui.properties": "Properties",
"ui.removeSection": "Remove Section",
"ui.removeFromToolbar": "Remove from Toolbar",
"ui.repeat": "Repeat",
"ui.report_a_bug": "Report a bug",
"ui.restore": "Restore",
"ui.heading_setup": "SETUP",
"ui.selectOther": "Select Other…",
"ui.selectTangentChain": "Select Tangent Chain",
"ui.showAll": "Show All",
"ui.showAllBodies": "Show All Bodies",
"ui.showAxes": "Show Axes",
"ui.showDimension": "Show Dimension",
"ui.showOrigin": "Show Origin",
"ui.showPlanes": "Show Planes",
"ui.suppress": "Suppress",
"ui.command_palette_hint": "Type a command, e.g. {example} — or press S to search",
"ui.unground": "Unground",
"ui.unisolate": "Unisolate",
"ui.unlock": "Unlock",
"ui.unsuppress": "Unsuppress",
"ui.updateToCurrentView": "Update to Current View",
"ui.zoom": "Zoom",
"ui.command_done": "{command} done",
"timeline.group": "New Feature Folder",
"timeline.ungroup": "Remove Feature Folders",
"timeline.rename_group": "Rename Feature Folder",
"timeline.move_to_group": "Move Features to Folder",
"timeline.move_many": "Move Timeline Items",
"timeline.reorder_many": "Reorder Features",
"ui.show_construction_geometries": "Construction Geometries",
"ui.total_angle": "Total angle",
"sketch_text.builtin_font": "{family} (built-in)",
"sketch_text.font_search": "Search fonts",
"sketch_text.loading_fonts": "Looking for installed fonts…",
@@ -879,4 +951,4 @@
"Line Spacing": "Line Spacing",
"Path": "Path",
"sketch_text.on_path": "The text follows its path: the curve places it"
}
}
+75 -3
View File
@@ -245,6 +245,19 @@
"cmd.surface_patch": "パッチ",
"cmd.surface_stitch": "ステッチ",
"cmd.surface_thicken": "厚み付け",
"cmd.surface_extrude": "サーフェス押し出し",
"cmd.surface_revolve": "サーフェス回転",
"cmd.surface_sweep": "サーフェススイープ",
"cmd.surface_loft": "サーフェスロフト",
"cmd.surface_ruled": "ルールドサーフェス",
"cmd.surface_boundary": "境界サーフェス",
"cmd.surface_offset": "オフセットサーフェス",
"cmd.surface_blend": "ブレンドサーフェス",
"cmd.surface_fillet": "サーフェスフィレット",
"cmd.surface_untrim": "トリム解除",
"cmd.surface_unstitch": "縫い合わせ解除",
"cmd.surface_reverse_normal": "法線を反転",
"cmd.inspect_continuity": "連続性解析",
"cmd.timeline_compute_all": "すべて再計算",
"cmd.timeline_copy": "フィーチャーをコピー",
"cmd.timeline_dependents": "従属フィーチャー",
@@ -326,6 +339,7 @@
"ui.combine": "結合",
"ui.coming_later": "準備中",
"ui.concentric": "同心",
"ui.configurations": "構成",
"ui.conic_curve": "円錐曲線",
"ui.constant": "一定",
"ui.constraints_conflict": "拘束が競合しています",
@@ -376,6 +390,7 @@
"ui.extent_type": "範囲タイプ",
"ui.extrude": "押し出し",
"ui.factor": "倍率",
"ui.feature_history": "フィーチャー履歴",
"ui.feature_options": "フィーチャーオプション",
"ui.features": "フィーチャー",
"ui.file": "ファイル",
@@ -556,7 +571,6 @@
"ui.shell": "シェル",
"ui.show": "表示",
"ui.show_constraints": "拘束",
"ui.show_construction_geometries": "構築ジオメトリ",
"ui.show_dimensions": "寸法",
"ui.show_points": "点を表示",
"ui.show_profile": "プロファイルを表示",
@@ -597,11 +611,13 @@
"ui.theme": "テーマ",
"ui.thickness": "厚さ",
"ui.thread": "ねじ",
"ui.timeline_bottom": "下部タイムライン",
"ui.timeline_left_note": "左レイアウトでは、ロールバックバーがパーツとシーンブラウザーの上に表示されます。",
"ui.timeline_left_sidebar": "左サイドバー",
"ui.tip_angle": "先端角度",
"ui.to_object": "オブジェクトまで",
"ui.top": "上面",
"ui.torus": "トーラス",
"ui.total_angle": "合計角度",
"ui.trackpad_pan_tip": "トラックパッドのジェスチャーでパンします(オフの場合はマウスホイールと同様にズームします)。マウスホイールはズーム、サイドホイールは横方向のパン、ピンチ操作は常にズームになります。",
"ui.trim": "トリム",
"ui.two_finger_scroll_pans": "2本指スクロールでパン",
@@ -862,6 +878,62 @@
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "その他を選択: モデル上で左ボタンを長押し(または右クリック › その他を選択…)するとカーソル下の要素が一覧表示されます。同じ場所を再度クリックすると次の要素が選択されます。中ボタンをダブルクリックするとホームビューに戻ります(環境設定 › ナビゲーション)。",
"cmd.render_backends": "レンダリング バックエンド",
"cmd.view_navigate": "ビューナビゲーション",
"ui.animateJoint": "ジョイントをアニメート",
"ui.calibrate": "校正",
"ui.customizeToolbar": "ツールバーをカスタマイズ…",
"ui.editJointLimits": "ジョイント制限を編集",
"ui.exportDxf": "DXF をエクスポート…",
"ui.findInTimeline": "タイムラインで検索",
"ui.findInWindow": "ウィンドウで検索",
"ui.fit": "フィット",
"ui.groupSelected": "選択をグループ化",
"ui.hideAxes": "軸を非表示",
"ui.hideDimension": "寸法を非表示",
"ui.hideOrigin": "原点を非表示",
"ui.hidePlanes": "平面を非表示",
"ui.hideProfile": "プロファイルを非表示",
"ui.homeView": "ホームビュー",
"ui.isolate": "分離表示",
"ui.lock": "ロック",
"ui.newSketchGroup": "新しいスケッチグループ",
"ui.normalConstruction": "通常 / コンストラクション",
"ui.orbit": "回転",
"ui.heading_position": "配置",
"ui.pan": "パン",
"ui.pinToShortcuts": "ショートカットに固定",
"ui.pinToToolbar": "ツールバーに固定",
"ui.properties": "プロパティ",
"ui.removeSection": "セクションを解除",
"ui.removeFromToolbar": "ツールバーから削除",
"ui.repeat": "繰り返し",
"ui.report_a_bug": "不具合を報告",
"ui.restore": "復元",
"ui.heading_setup": "セットアップ",
"ui.selectOther": "その他を選択…",
"ui.selectTangentChain": "接線チェーンを選択",
"ui.showAll": "すべて表示",
"ui.showAllBodies": "すべてのボディを表示",
"ui.showAxes": "軸を表示",
"ui.showDimension": "寸法を表示",
"ui.showOrigin": "原点を表示",
"ui.showPlanes": "平面を表示",
"ui.suppress": "抑制",
"ui.command_palette_hint": "コマンドを入力(例: {example})— または S キーで検索",
"ui.unground": "固定を解除",
"ui.unisolate": "分離表示を解除",
"ui.unlock": "ロック解除",
"ui.unsuppress": "抑制を解除",
"ui.updateToCurrentView": "現在のビューに更新",
"ui.zoom": "ズーム",
"ui.command_done": "{command} 完了",
"timeline.group": "フィーチャーフォルダを新規作成",
"timeline.ungroup": "フィーチャーフォルダを削除",
"timeline.rename_group": "フィーチャーフォルダの名前を変更",
"timeline.move_to_group": "フィーチャーをフォルダへ移動",
"timeline.move_many": "タイムライン項目を移動",
"timeline.reorder_many": "フィーチャーの順序を変更",
"ui.show_construction_geometries": "構築ジオメトリ",
"ui.total_angle": "合計角度",
"sketch_text.builtin_font": "{family}(内蔵)",
"sketch_text.font_search": "フォントを検索",
"sketch_text.loading_fonts": "インストール済みフォントを検索中…",
@@ -879,4 +951,4 @@
"Line Spacing": "行間",
"Path": "パス",
"sketch_text.on_path": "文字はパスに沿います: 位置は曲線で決まります"
}
}
+360 -7
View File
@@ -65,14 +65,15 @@
"ui.combine": "결합",
"ui.coming_later": "추후 지원 예정",
"ui.concentric": "동심",
"ui.configurations": "구성",
"ui.conic_curve": "원뿔 곡선",
"ui.constant": "상수",
"ui.constraints_conflict": "구속 조건 충돌",
"ui.construct": "구성",
"ui.construction": "구성선",
"ui.copy": "복사",
"ui.corner": "코너",
"ui.corners": "코너",
"ui.corner": "코너",
"ui.counterbore": "카운터보어",
"ui.countersink": "카운터싱크",
"ui.create": "만들기",
@@ -112,6 +113,7 @@
"ui.extent_type": "범위 유형",
"ui.extrude": "돌출",
"ui.factor": "배율",
"ui.feature_history": "피처 기록",
"ui.feature_options": "피처 옵션",
"ui.features": "피처",
"ui.file": "파일",
@@ -249,8 +251,8 @@
"ui.profile_plane": "프로파일 평면",
"ui.profiles": "프로파일",
"ui.project": "투영",
"ui.quantity": "수량",
"ui.quantity_2": "수량 2",
"ui.quantity": "수량",
"ui.quit": "종료",
"ui.radius": "반지름",
"ui.radius_type": "반지름 유형",
@@ -273,7 +275,6 @@
"ui.shell": "쉘",
"ui.show": "표시",
"ui.show_constraints": "구속 조건",
"ui.show_construction_geometries": "구성 형상",
"ui.show_dimensions": "치수",
"ui.show_points": "점 표시",
"ui.show_profile": "프로파일 표시",
@@ -291,8 +292,8 @@
"ui.slot": "슬롯",
"ui.smooth": "부드럽게",
"ui.snap": "스냅",
"ui.spacing": "간각",
"ui.spacing_2": "간각 2",
"ui.spacing_2": "간격 2",
"ui.spacing": "간격",
"ui.sphere": "구",
"ui.spline": "스플라인",
"ui.split_body": "바디 분할",
@@ -309,11 +310,13 @@
"ui.theme": "테마",
"ui.thickness": "두께",
"ui.thread": "나사산",
"ui.timeline_bottom": "하단 타임라인",
"ui.timeline_left_note": "왼쪽 레이아웃에서는 롤백 바가 부품 및 장면 브라우저 위에 표시됩니다.",
"ui.timeline_left_sidebar": "왼쪽 사이드바",
"ui.tip_angle": "선단 각도",
"ui.to_object": "객체까지",
"ui.top": "상면",
"ui.torus": "토러스",
"ui.total_angle": "전진 각도",
"ui.trim": "트림",
"ui.two_sides": "양방향",
"ui.ui_scale": "UI 배율",
@@ -325,9 +328,359 @@
"ui.view_centre": "뷰 중심",
"ui.visual_style": "시각 스타일",
"ui.workspace": "작업 공간",
"ui.x_distance": "X 거리",
"ui.y_distance": "Y 거리",
"ui.x_distance": "X 거리",
"ui.zoom_to_the_cursor": "커서 위치로 확대/축소",
"ui.animateJoint": "조인트 애니메이션",
"ui.calibrate": "캘리브레이션",
"ui.customizeToolbar": "도구 모음 사용자 지정…",
"ui.editJointLimits": "조인트 제한 편집",
"ui.exportDxf": "DXF 내보내기…",
"ui.findInTimeline": "타임라인에서 찾기",
"ui.findInWindow": "창에서 찾기",
"ui.fit": "맞춤",
"ui.groupSelected": "선택 항목 그룹화",
"ui.hideAxes": "축 숨기기",
"ui.hideDimension": "치수 숨기기",
"ui.hideOrigin": "원점 숨기기",
"ui.hidePlanes": "평면 숨기기",
"ui.hideProfile": "윤곽 숨기기",
"ui.homeView": "홈 보기",
"ui.isolate": "분리 표시",
"ui.lock": "잠금",
"ui.newSketchGroup": "새 스케치 그룹",
"ui.normalConstruction": "일반 / 생성",
"ui.orbit": "회전",
"ui.heading_position": "배치",
"ui.pan": "이동",
"ui.pinToShortcuts": "바로 가기에 고정",
"ui.pinToToolbar": "도구 모음에 고정",
"ui.properties": "속성",
"ui.removeSection": "단면 제거",
"ui.removeFromToolbar": "도구 모음에서 제거",
"ui.repeat": "반복",
"ui.report_a_bug": "버그 신고",
"ui.restore": "복원",
"ui.heading_setup": "설정",
"ui.selectOther": "기타 선택…",
"ui.selectTangentChain": "접선 체인 선택",
"ui.showAll": "모두 표시",
"ui.showAllBodies": "모두 표시",
"ui.showAxes": "축 표시",
"ui.showDimension": "치수 표시",
"ui.showOrigin": "원점 표시",
"ui.showPlanes": "평면 표시",
"ui.suppress": "비활성화",
"ui.command_palette_hint": "명령 입력(예: {example}) — 또는 S 키를 눌러 검색",
"ui.unground": "고정 해제",
"ui.unisolate": "분리 표시 해제",
"ui.unlock": "잠금 해제",
"ui.unsuppress": "비활성화 해제",
"ui.updateToCurrentView": "현재 보기로 업데이트",
"ui.zoom": "확대/축소",
"ui.command_done": "{command} 완료",
"cmd.appearance_assign": "외관",
"cmd.appearance_library": "외관 라이브러리",
"cmd.appearance_list": "외관 목록",
"cmd.body_rename": "바디 이름 변경",
"cmd.browser_group": "새 그룹",
"cmd.browser_move": "브라우저 항목 이동",
"cmd.browser_order": "브라우저 항목 정렬",
"cmd.browser_rename_group": "그룹 이름 변경",
"cmd.browser_ungroup": "그룹 해제",
"cmd.browser_visibility": "표시/숨기기",
"cmd.canvas_calibrate": "캔버스 보정",
"cmd.canvas_decal": "데칼",
"cmd.canvas_delete": "캔버스 삭제",
"cmd.canvas_edit": "캔버스 편집",
"cmd.canvas_insert": "캔버스",
"cmd.component_activate": "구성 요소 활성화",
"cmd.component_break_link": "링크 끊기",
"cmd.component_capture_position": "위치 캡처",
"cmd.component_create": "새 구성 요소",
"cmd.component_delete": "구성 요소 삭제",
"cmd.component_from_bodies": "바디로 구성 요소 만들기",
"cmd.component_insert_design": "설계 삽입",
"cmd.component_links": "링크 목록",
"cmd.component_list": "구성 요소 목록",
"cmd.component_move_bodies": "바디를 구성 요소로 이동",
"cmd.component_move_sketches": "스케치를 구성 요소로 이동",
"cmd.component_paste_new": "새로 붙여넣기",
"cmd.component_properties": "구성 요소 물리 속성",
"cmd.component_rename": "구성 요소 이름 변경",
"cmd.component_revert_position": "위치 복원",
"cmd.component_update_links": "링크 업데이트",
"cmd.config_activate": "구성 활성화",
"cmd.config_column": "구성 열",
"cmd.config_configure": "구성",
"cmd.config_preview": "구성 미리 보기",
"cmd.config_row": "구성 행",
"cmd.config_rule": "구성 규칙",
"cmd.config_rules": "구성 규칙",
"cmd.config_table": "구성 표시",
"cmd.construct_axis_edge": "모서리를 통과하는 축",
"cmd.construct_axis_normal_to_face": "면에 수직인 축",
"cmd.construct_axis_through_cylinder": "원기둥/원뿔/토러스를 통과하는 축",
"cmd.construct_axis_two_planes": "두 평면을 통과하는 축",
"cmd.construct_axis_two_points": "두 점을 통과하는 축",
"cmd.construct_plane_along_path": "경로를 따르는 평면",
"cmd.construct_plane_midplane": "중간 평면",
"cmd.construct_plane_perpendicular": "수직 평면",
"cmd.construct_plane_tangent": "접선 평면",
"cmd.construct_plane_three_points": "세 점을 통과하는 평면",
"cmd.construct_plane_two_edges": "두 모서리를 통과하는 평면",
"cmd.construct_point_along_path": "경로를 따르는 점",
"cmd.construct_point_center": "원/구/토러스 중심의 점",
"cmd.construct_point_edge_plane": "모서리와 평면의 점",
"cmd.construct_point_three_planes": "세 평면이 만나는 점",
"cmd.construct_point_two_edges": "두 모서리가 만나는 점",
"cmd.construct_point_vertex": "꼭짓점의 점",
"cmd.contact_check": "접촉 확인",
"cmd.contact_create": "새 접촉 집합",
"cmd.contact_disable_all": "접촉 비활성화",
"cmd.contact_edit": "접촉 집합 편집",
"cmd.contact_enable_all": "모든 접촉 활성화",
"cmd.contact_enable_sets": "접촉 집합 활성화",
"cmd.contact_list": "접촉 집합 목록",
"cmd.diagnostics_crash_report": "충돌 보고서",
"cmd.diagnostics_crash_reports": "충돌 보고서",
"cmd.diagnostics_crash_reports_clear": "충돌 보고서 삭제",
"cmd.diagnostics_crash_test": "충돌 테스트",
"cmd.doc_recover": "설계 복구",
"cmd.doc_recovery_discard": "복구된 설계 폐기",
"cmd.doc_recovery_list": "복구 가능한 설계",
"cmd.document_inspect": "설계 검사",
"cmd.document_units": "설계 단위 변경",
"cmd.edit_checkpoint": "체크포인트",
"cmd.edit_restore_checkpoint": "체크포인트 복원",
"cmd.engine_commands": "명령 목록",
"cmd.explode_create": "분해 보기",
"cmd.explode_delete": "분해 보기 삭제",
"cmd.explode_list": "분해 보기 목록",
"cmd.explode_show": "분해 보기 표시",
"cmd.expr_evaluate": "식 평가",
"cmd.face_delete": "면 삭제",
"cmd.file_export": "내보내기",
"cmd.file_insert_mesh": "메쉬 삽입",
"cmd.file_insert_step": "STEP 삽입",
"cmd.file_save_mesh": "메쉬로 저장",
"cmd.inspect_accessibility": "접근성 분석",
"cmd.inspect_center_of_mass": "무게중심",
"cmd.inspect_curvature_comb": "곡률빗 분석",
"cmd.inspect_curvature_map": "곡률맵 분석",
"cmd.inspect_draft": "블록각 분석",
"cmd.inspect_environment_map": "환경 맵 분석",
"cmd.inspect_interference": "간섭",
"cmd.inspect_isocurve": "등가곡선 분석",
"cmd.inspect_minimum_radius": "최소 반경 분석",
"cmd.inspect_zebra": "얼룩말줄무늬 분석",
"cmd.joint_as_built": "조립 상태 관절",
"cmd.joint_create": "관절",
"cmd.joint_delete": "관절 삭제",
"cmd.joint_drive": "관절 구동",
"cmd.joint_edit": "관절 편집",
"cmd.joint_limits": "관절 제한",
"cmd.joint_list": "관절 목록",
"cmd.joint_motion_link": "모션 링크",
"cmd.joint_origin": "관절 원점",
"cmd.joint_rigid_group": "강체 그룹",
"cmd.joint_solve": "관절 해석",
"cmd.material_assign": "물리 재질",
"cmd.material_create": "새 물리 재질",
"cmd.material_delete": "물리 재질 삭제",
"cmd.material_edit": "물리 재질 편집",
"cmd.material_list": "재질 목록",
"cmd.mesh_convert": "메쉬 변환",
"cmd.model_edges": "모서리 목록",
"cmd.model_faces": "면 목록",
"cmd.model_threads": "나사산 목록",
"cmd.motion_delete": "운동 연구 삭제",
"cmd.motion_export": "운동 연구 내보내기",
"cmd.motion_list": "운동 연구 목록",
"cmd.motion_play": "운동 연구 재생",
"cmd.motion_study": "운동 연구",
"cmd.occurrence_copy": "붙여넣기(인스턴스)",
"cmd.occurrence_ground": "고정",
"cmd.occurrence_move": "인스턴스 이동",
"cmd.occurrence_properties": "인스턴스 물리 속성",
"cmd.parameters_add": "사용자 매개 변수 추가",
"cmd.parameters_change": "매개 변수 변경",
"cmd.parameters_comment": "매개 변수에 설명 추가",
"cmd.parameters_complete": "식 완성",
"cmd.parameters_delete": "매개 변수 삭제",
"cmd.parameters_export": "매개 변수 내보내기",
"cmd.parameters_favorite": "즐겨찾는 매개 변수",
"cmd.parameters_graph": "매개 변수 그래프",
"cmd.parameters_import": "매개 변수 가져오기",
"cmd.parameters_list": "매개 변수 목록",
"cmd.parameters_rename": "매개 변수 이름 변경",
"cmd.parameters_users": "매개 변수 사용처",
"cmd.parts_fastener": "체결 부품 삽입",
"cmd.parts_insert": "부품 삽입",
"cmd.parts_library": "표준 부품",
"cmd.parts_resize": "부품 크기 변경",
"cmd.plastic_assign_rule": "플라스틱 규칙 지정",
"cmd.plastic_boss": "보스",
"cmd.plastic_lip": "리프",
"cmd.plastic_manage_rules": "플라스틱 규칙 관리",
"cmd.plastic_rest": "레스트",
"cmd.plastic_rules": "플라스틱 규칙 목록",
"cmd.plastic_snap_fit": "스냅핏",
"cmd.select_clear": "선택 지우기",
"cmd.sheet_convert": "판금으로 변환",
"cmd.sheet_export_bend_table": "벤딩 표 내보내기",
"cmd.sheet_export_dxf": "전개도를 DXF로 내보내기",
"cmd.sheet_flange": "플랜지",
"cmd.sheet_flat_pattern": "전개도 만들기",
"cmd.sheet_fold": "접기",
"cmd.sheet_hem": "헴",
"cmd.sheet_manage_rules": "판금 규칙",
"cmd.sheet_refold": "다시 접기",
"cmd.sheet_rules": "판금 규칙 목록",
"cmd.sheet_unfold": "펼치기",
"cmd.sketch_arc_center_point": "중심점 호",
"cmd.sketch_arc_tangent": "접선 호",
"cmd.sketch_arc_three_point": "3점 호",
"cmd.sketch_auto_constrain": "자동 구속",
"cmd.sketch_auto_constrain_from_datum": "기준으로 자동 구속",
"cmd.sketch_auto_project": "참조에 모서리 자동 투영",
"cmd.sketch_blend_curve": "블렌드 곡선",
"cmd.sketch_chain": "연속",
"cmd.sketch_chamfer_distance_angle": "거리와 각도 모따기",
"cmd.sketch_chamfer_equal_distance": "등거리 모따기",
"cmd.sketch_chamfer_two_distance": "두 거리 모따기",
"cmd.sketch_circle_center": "중심 지름 원",
"cmd.sketch_circle_three_point": "3점 원",
"cmd.sketch_circle_three_tangent": "3접선 원",
"cmd.sketch_circle_two_point": "2점 원",
"cmd.sketch_circle_two_tangent": "2접선 원",
"cmd.sketch_constrainer": "스케치 구속기",
"cmd.sketch_constraint_fix": "고정/고정 해제",
"cmd.sketch_constraint_midpoint": "중간점",
"cmd.sketch_construction": "일반/구성선",
"cmd.sketch_delete": "스케치 개체 삭제",
"cmd.sketch_dimension_text": "치수 텍스트 이동",
"cmd.sketch_drag": "스케치 기하 드래그",
"cmd.sketch_drag_end": "스케치 드래그 종료",
"cmd.sketch_draw_dimensioned": "치수가 있는 스케치 개체 그리기",
"cmd.sketch_edit": "스케치 편집",
"cmd.sketch_edit_text": "텍스트 편집",
"cmd.sketch_export_dxf": "DXF로 저장",
"cmd.sketch_finish_auto_constrain": "자동 구속으로 완료",
"cmd.sketch_fit_curves_to_section": "메시 단면에 곡선 맞추기",
"cmd.sketch_glyphs": "구속 기호",
"cmd.sketch_include_3d": "3D 기하 포함",
"cmd.sketch_insert_dxf": "DXF 삽입",
"cmd.sketch_insert_svg": "SVG 삽입",
"cmd.sketch_inspect": "스케치 검사",
"cmd.sketch_intersection_curve": "교차 곡선",
"cmd.sketch_isoparametric_curve": "등매개 곡선",
"cmd.sketch_line3d": "3D 선",
"cmd.sketch_line_midpoint": "중점 선",
"cmd.sketch_move": "스케치 개체 이동/복사",
"cmd.sketch_move3d": "3D 점 이동",
"cmd.sketch_move_point": "스케치 점 드래그",
"cmd.sketch_offset_break": "오프셋 연결 끊기",
"cmd.sketch_options": "스케치 팔레트 옵션",
"cmd.sketch_point3d": "3D 점",
"cmd.sketch_polygon_circumscribed": "외접 다각형",
"cmd.sketch_polygon_edge": "변 다각형",
"cmd.sketch_polygon_inscribed": "내접 다각형",
"cmd.sketch_project_to_surface": "곡면으로 투영",
"cmd.sketch_rectangle_center": "중심 사각형",
"cmd.sketch_rectangle_three_point": "3점 사각형",
"cmd.sketch_rectangle_two_point": "2점 사각형",
"cmd.sketch_redefine": "스케치 평면 재정의",
"cmd.sketch_slot_arc_center": "중심점 호 슬롯",
"cmd.sketch_slot_arc_three_point": "3점 호 슬롯",
"cmd.sketch_slot_center_point": "중심점 슬롯",
"cmd.sketch_slot_center_to_center": "중심에서 중심 슬롯",
"cmd.sketch_slot_overall": "전장 슬롯",
"cmd.sketch_snap": "스냅 추론",
"cmd.sketch_solve": "스케치 해석",
"cmd.sketch_spline3d": "3D 스플라인",
"cmd.sketch_spline_control_point": "제어점 스플라인",
"cmd.sketch_spline_control_point_5": "제어점 스플라인(5차)",
"cmd.sketch_spline_fit_point": "맞춤점 스플라인",
"cmd.sketch_spun_profile": "회전 프로파일",
"cmd.sketch_toggle_driven": "종속 치수 전환",
"cmd.solid_align": "정렬",
"cmd.solid_boundary_fill": "경계 채우기",
"cmd.solid_bounding_solid": "둘러싸는 솔리드",
"cmd.solid_emboss": "엠보스",
"cmd.solid_move": "이동/복사",
"cmd.solid_offset_face": "면 오프셋",
"cmd.solid_press_pull": "밀기/당기기",
"cmd.solid_remove": "제거",
"cmd.solid_replace_face": "면 교체",
"cmd.solid_rib": "리브",
"cmd.solid_split_face": "면 분할",
"cmd.solid_web": "웹",
"cmd.surface_patch": "패치",
"cmd.surface_stitch": "재봉",
"cmd.surface_thicken": "두께 주기",
"cmd.surface_extrude": "서피스 돌출",
"cmd.surface_revolve": "서피스 회전",
"cmd.surface_sweep": "서피스 스윕",
"cmd.surface_loft": "서피스 로프트",
"cmd.surface_ruled": "룰드 서피스",
"cmd.surface_boundary": "바운더리 서피스",
"cmd.surface_offset": "오프셋 서피스",
"cmd.surface_blend": "블렌드 서피스",
"cmd.surface_fillet": "서피스 필렛",
"cmd.surface_untrim": "트림 해제",
"cmd.surface_unstitch": "스티치 해제",
"cmd.surface_reverse_normal": "법선 반전",
"cmd.inspect_continuity": "연속성 분석",
"cmd.timeline_compute_all": "모두 다시 계산",
"cmd.timeline_copy": "특성 복사",
"cmd.timeline_dependents": "특성 종속 항목",
"cmd.timeline_inspect": "특성 검사",
"cmd.timeline_paste": "특성 붙여넣기",
"cmd.timeline_redefine": "특성 편집",
"cmd.timeline_rename": "이름 변경",
"cmd.timeline_reorder": "특성 순서 변경",
"cmd.timeline_roll_to": "이력 마커 이동",
"cmd.timeline_rollback": "타임라인 마커 이동",
"cmd.timeline_suppress": "특성 비활성화",
"cmd.view_apply": "이름 있는 보기 복원",
"cmd.view_delete": "이름 있는 보기 삭제",
"cmd.view_list": "이름 있는 보기 목록",
"cmd.view_rename": "이름 있는 보기 이름 변경",
"cmd.view_save": "새 이름 있는 보기",
"ui.export_ellipsis_keymap": "내보내기…",
"ui.heading_configure": "구성",
"ui.heading_constraints": "구속 조건",
"ui.heading_utilities": "유틸리티",
"BROWSER": "브라우저",
"Drive Joint": "조인트 구동",
"Edit Profile Sketch": "윤곽 스케치 편집",
"Find in Browser": "브라우저에서 찾기",
"Report a bug — review a screenshot and open a GitHub draft": "버그 신고 — 스크린샷을 검토하고 GitHub 초안 열기",
"Reset Toolbar": "도구 모음 재설정",
"Select bodies (a face picks its body)": "바디 선택(면을 클릭하면 해당 바디 선택)",
"Selection filter": "선택 필터",
"Revert Position": "위치 복원",
"Construction": "구성선",
"Faces": "면",
"Edges": "모서리",
"Vertices": "꼭짓점",
"Sketch geometry and profiles": "스케치 기하 및 프로파일",
"Sketch curves": "스케치 곡선",
"Sketch points": "스케치 점",
"Sketch dimensions": "스케치 치수",
"Sketch constraints": "스케치 구속 조건",
"Flat": "플랫",
"cmd.render_backends": "렌더링 백엔드",
"cmd.view_navigate": "보기 탐색",
"timeline.group": "새 특성 폴더",
"timeline.ungroup": "특성 폴더 제거",
"timeline.rename_group": "특성 폴더 이름 변경",
"timeline.move_to_group": "특성을 폴더로 이동",
"timeline.move_many": "타임라인 항목 이동",
"timeline.reorder_many": "특성 순서 변경",
"ui.show_construction_geometries": "구성 형상",
"ui.total_angle": "전진 각도",
"sketch_text.builtin_font": "{family}(내장)",
"sketch_text.font_search": "글꼴 검색",
"sketch_text.loading_fonts": "설치된 글꼴을 찾는 중…",
+954
View File
@@ -0,0 +1,954 @@
{
"browser.body_name": "实体{number}",
"browser.component_name": "组件{number}",
"browser.parameters": "参数 ({count})",
"browser.precision": "精度: {precision}",
"browser.sketch_name": "草图{number}",
"browser.units": "单位: {units}",
"cmd.appearance_assign": "外观",
"cmd.appearance_library": "外观库",
"cmd.appearance_list": "列出外观",
"cmd.body_rename": "重命名实体",
"cmd.browser_group": "新建组",
"cmd.browser_move": "移动浏览器项目",
"cmd.browser_order": "排列浏览器项目",
"cmd.browser_rename_group": "重命名组",
"cmd.browser_ungroup": "取消编组",
"cmd.browser_visibility": "显示/隐藏",
"cmd.canvas_calibrate": "校准画布",
"cmd.canvas_decal": "贴花",
"cmd.canvas_delete": "删除画布",
"cmd.canvas_edit": "编辑画布",
"cmd.canvas_insert": "画布",
"cmd.component_activate": "激活组件",
"cmd.component_break_link": "断开链接",
"cmd.component_capture_position": "捕获位置",
"cmd.component_create": "新建组件",
"cmd.component_delete": "删除组件",
"cmd.component_from_bodies": "由实体创建组件",
"cmd.component_insert_design": "插入设计",
"cmd.component_links": "列出链接",
"cmd.component_list": "列出组件",
"cmd.component_move_bodies": "将实体移至组件",
"cmd.component_move_sketches": "将草图移至组件",
"cmd.component_paste_new": "粘贴为新对象",
"cmd.component_properties": "组件物理属性",
"cmd.component_rename": "重命名组件",
"cmd.component_revert_position": "恢复位置",
"cmd.component_update_links": "更新链接",
"cmd.config_activate": "激活配置",
"cmd.config_column": "配置列",
"cmd.config_configure": "配置",
"cmd.config_preview": "预览配置",
"cmd.config_row": "配置行",
"cmd.config_rule": "配置规则",
"cmd.config_rules": "配置规则",
"cmd.config_table": "显示配置表",
"cmd.construct_axis_edge": "过边的轴",
"cmd.construct_axis_normal_to_face": "垂直于面的轴",
"cmd.construct_axis_through_cylinder": "过圆柱/圆锥/圆环的轴",
"cmd.construct_axis_two_planes": "过两个平面的轴",
"cmd.construct_axis_two_points": "过两点的轴",
"cmd.construct_plane_along_path": "沿路径的平面",
"cmd.construct_plane_midplane": "中平面",
"cmd.construct_plane_perpendicular": "垂直平面",
"cmd.construct_plane_tangent": "相切平面",
"cmd.construct_plane_three_points": "过三点的平面",
"cmd.construct_plane_two_edges": "过两条边的平面",
"cmd.construct_point_along_path": "沿路径的点",
"cmd.construct_point_center": "圆/球/圆环中心的点",
"cmd.construct_point_edge_plane": "边与平面交点",
"cmd.construct_point_three_planes": "过三个平面的点",
"cmd.construct_point_two_edges": "过两条边的点",
"cmd.construct_point_vertex": "顶点处的点",
"cmd.contact_check": "检查接触",
"cmd.contact_create": "新建接触集",
"cmd.contact_disable_all": "禁用接触",
"cmd.contact_edit": "编辑接触集",
"cmd.contact_enable_all": "启用全部接触",
"cmd.contact_enable_sets": "启用接触集",
"cmd.contact_list": "列出接触集",
"cmd.diagnostics_crash_report": "崩溃报告",
"cmd.diagnostics_crash_reports": "崩溃报告",
"cmd.diagnostics_crash_reports_clear": "删除崩溃报告",
"cmd.diagnostics_crash_test": "崩溃测试",
"cmd.doc_recover": "恢复设计",
"cmd.doc_recovery_discard": "丢弃已恢复的设计",
"cmd.doc_recovery_list": "可恢复的设计",
"cmd.document_inspect": "检查设计",
"cmd.document_units": "更改设计单位",
"cmd.edit_checkpoint": "检查点",
"cmd.edit_restore_checkpoint": "恢复检查点",
"cmd.engine_commands": "列出命令",
"cmd.explode_create": "爆炸图",
"cmd.explode_delete": "删除爆炸图",
"cmd.explode_list": "列出爆炸图",
"cmd.explode_show": "显示爆炸图",
"cmd.expr_evaluate": "计算表达式",
"cmd.face_delete": "删除面",
"cmd.file_export": "导出",
"cmd.file_insert_mesh": "插入网格",
"cmd.file_insert_step": "插入 STEP",
"cmd.file_save_mesh": "另存为网格",
"cmd.inspect_accessibility": "可达性分析",
"cmd.inspect_center_of_mass": "质心",
"cmd.inspect_curvature_comb": "曲率梳分析",
"cmd.inspect_curvature_map": "曲率图分析",
"cmd.inspect_draft": "拔模分析",
"cmd.inspect_environment_map": "环境贴图分析",
"cmd.inspect_interference": "干涉",
"cmd.inspect_isocurve": "等参线分析",
"cmd.inspect_minimum_radius": "最小半径分析",
"cmd.inspect_zebra": "斑马纹分析",
"cmd.joint_as_built": "现状接头",
"cmd.joint_create": "接头",
"cmd.joint_delete": "删除接头",
"cmd.joint_drive": "驱动接头",
"cmd.joint_edit": "编辑接头",
"cmd.joint_limits": "接头限制",
"cmd.joint_list": "列出接头",
"cmd.joint_motion_link": "运动关联",
"cmd.joint_origin": "接头原点",
"cmd.joint_rigid_group": "刚性组",
"cmd.joint_solve": "解算接头",
"cmd.material_assign": "物理材质",
"cmd.material_create": "新建物理材质",
"cmd.material_delete": "删除物理材质",
"cmd.material_edit": "编辑物理材质",
"cmd.material_list": "列出材质",
"cmd.mesh_convert": "转换网格",
"cmd.model_edges": "列出边",
"cmd.model_faces": "列出面",
"cmd.model_threads": "列出螺纹",
"cmd.motion_delete": "删除运动研究",
"cmd.motion_export": "导出运动研究",
"cmd.motion_list": "列出运动研究",
"cmd.motion_play": "播放运动研究",
"cmd.motion_study": "运动研究",
"cmd.occurrence_copy": "粘贴(实例)",
"cmd.occurrence_ground": "固定",
"cmd.occurrence_move": "移动实例",
"cmd.occurrence_properties": "实例物理属性",
"cmd.parameters_add": "添加用户参数",
"cmd.parameters_change": "更改参数",
"cmd.parameters_comment": "注释参数",
"cmd.parameters_complete": "补全表达式",
"cmd.parameters_delete": "删除参数",
"cmd.parameters_export": "导出参数",
"cmd.parameters_favorite": "收藏参数",
"cmd.parameters_graph": "参数关系图",
"cmd.parameters_import": "导入参数",
"cmd.parameters_list": "列出参数",
"cmd.parameters_rename": "重命名参数",
"cmd.parameters_users": "参数使用者",
"cmd.parts_fastener": "插入紧固件",
"cmd.parts_insert": "插入零件",
"cmd.parts_library": "标准零件",
"cmd.parts_resize": "更改零件尺寸",
"cmd.plastic_assign_rule": "指定塑料规则",
"cmd.plastic_boss": "凸台",
"cmd.plastic_lip": "凸缘",
"cmd.plastic_manage_rules": "管理塑料规则",
"cmd.plastic_rest": "垫块",
"cmd.plastic_rules": "列出塑料规则",
"cmd.plastic_snap_fit": "卡扣",
"cmd.select_clear": "清除选择",
"cmd.sheet_convert": "转换为钣金",
"cmd.sheet_export_bend_table": "导出折弯表",
"cmd.sheet_export_dxf": "将展开图导出为 DXF",
"cmd.sheet_flange": "法兰",
"cmd.sheet_flat_pattern": "创建展开图",
"cmd.sheet_fold": "折叠",
"cmd.sheet_hem": "卷边",
"cmd.sheet_manage_rules": "钣金规则",
"cmd.sheet_refold": "重新折弯",
"cmd.sheet_rules": "列出钣金规则",
"cmd.sheet_unfold": "展开",
"cmd.sketch_arc_center_point": "中心点圆弧",
"cmd.sketch_arc_tangent": "相切圆弧",
"cmd.sketch_arc_three_point": "三点圆弧",
"cmd.sketch_auto_constrain": "自动约束",
"cmd.sketch_auto_constrain_from_datum": "基于基准自动约束",
"cmd.sketch_auto_project": "自动投影边到参考",
"cmd.sketch_blend_curve": "混合曲线",
"cmd.sketch_chain": "连续链",
"cmd.sketch_chamfer_distance_angle": "距离和角度倒角",
"cmd.sketch_chamfer_equal_distance": "等距倒角",
"cmd.sketch_chamfer_two_distance": "双距离倒角",
"cmd.sketch_circle_center": "圆心直径圆",
"cmd.sketch_circle_three_point": "三点圆",
"cmd.sketch_circle_three_tangent": "三切线圆",
"cmd.sketch_circle_two_point": "两点圆",
"cmd.sketch_circle_two_tangent": "两切线圆",
"cmd.sketch_constrainer": "草图约束器",
"cmd.sketch_constraint_fix": "固定/解除固定",
"cmd.sketch_constraint_midpoint": "中点",
"cmd.sketch_construction": "普通/构造",
"cmd.sketch_delete": "删除草图图元",
"cmd.sketch_dimension_text": "移动尺寸文字",
"cmd.sketch_drag": "拖动草图几何",
"cmd.sketch_drag_end": "结束草图拖动",
"cmd.sketch_draw_dimensioned": "绘制带尺寸的草图图元",
"cmd.sketch_edit": "编辑草图",
"cmd.sketch_edit_text": "编辑文字",
"cmd.sketch_export_dxf": "另存为 DXF",
"cmd.sketch_finish_auto_constrain": "使用自动约束完成",
"cmd.sketch_fit_curves_to_section": "将曲线拟合到网格截面",
"cmd.sketch_glyphs": "约束符号",
"cmd.sketch_include_3d": "包含三维几何",
"cmd.sketch_insert_dxf": "插入 DXF",
"cmd.sketch_insert_svg": "插入 SVG",
"cmd.sketch_inspect": "检查草图",
"cmd.sketch_intersection_curve": "相交曲线",
"cmd.sketch_isoparametric_curve": "等参数曲线",
"cmd.sketch_line3d": "三维直线",
"cmd.sketch_line_midpoint": "中点线",
"cmd.sketch_move": "移动/复制草图图元",
"cmd.sketch_move3d": "移动三维点",
"cmd.sketch_move_point": "拖动草图点",
"cmd.sketch_offset_break": "断开偏移关联",
"cmd.sketch_options": "草图选项板选项",
"cmd.sketch_point3d": "三维点",
"cmd.sketch_polygon_circumscribed": "外切多边形",
"cmd.sketch_polygon_edge": "边长多边形",
"cmd.sketch_polygon_inscribed": "内接多边形",
"cmd.sketch_project_to_surface": "投影到曲面",
"cmd.sketch_rectangle_center": "中心矩形",
"cmd.sketch_rectangle_three_point": "三点矩形",
"cmd.sketch_rectangle_two_point": "两点矩形",
"cmd.sketch_redefine": "重定义草图平面",
"cmd.sketch_slot_arc_center": "中心点圆弧槽",
"cmd.sketch_slot_arc_three_point": "三点圆弧槽",
"cmd.sketch_slot_center_point": "中心点槽",
"cmd.sketch_slot_center_to_center": "中心距槽",
"cmd.sketch_slot_overall": "全长槽",
"cmd.sketch_snap": "捕捉推断",
"cmd.sketch_solve": "解算草图",
"cmd.sketch_spline3d": "三维样条曲线",
"cmd.sketch_spline_control_point": "控制点样条曲线",
"cmd.sketch_spline_control_point_5": "控制点样条曲线(5 次)",
"cmd.sketch_spline_fit_point": "拟合点样条曲线",
"cmd.sketch_spun_profile": "旋转轮廓",
"cmd.sketch_toggle_driven": "切换被驱动尺寸",
"cmd.solid_align": "对齐",
"cmd.solid_boundary_fill": "边界填充",
"cmd.solid_bounding_solid": "包围实体",
"cmd.solid_emboss": "压印",
"cmd.solid_move": "移动/复制",
"cmd.solid_offset_face": "偏移面",
"cmd.solid_press_pull": "按压拖动",
"cmd.solid_remove": "移除",
"cmd.solid_replace_face": "替换面",
"cmd.solid_rib": "筋板",
"cmd.solid_split_face": "拆分面",
"cmd.solid_web": "网格筋",
"cmd.surface_patch": "补面",
"cmd.surface_stitch": "缝合",
"cmd.surface_thicken": "加厚",
"cmd.surface_extrude": "曲面拉伸",
"cmd.surface_revolve": "曲面旋转",
"cmd.surface_sweep": "曲面扫掠",
"cmd.surface_loft": "曲面放样",
"cmd.surface_ruled": "直纹曲面",
"cmd.surface_boundary": "边界曲面",
"cmd.surface_offset": "偏移曲面",
"cmd.surface_blend": "混合曲面",
"cmd.surface_fillet": "曲面圆角",
"cmd.surface_untrim": "取消修剪",
"cmd.surface_unstitch": "取消缝合",
"cmd.surface_reverse_normal": "反转法向",
"cmd.inspect_continuity": "连续性分析",
"cmd.timeline_compute_all": "全部重新計算",
"cmd.timeline_copy": "复制特征",
"cmd.timeline_dependents": "特征依存项",
"cmd.timeline_inspect": "检查特征",
"cmd.timeline_paste": "粘贴特征",
"cmd.timeline_redefine": "编辑特征",
"cmd.timeline_rename": "重命名",
"cmd.timeline_reorder": "重排特征",
"cmd.timeline_roll_to": "滚动历史标记",
"cmd.timeline_rollback": "移动时间线标记",
"cmd.timeline_suppress": "抑制特征",
"cmd.view_apply": "还原命名视图",
"cmd.view_delete": "删除命名视图",
"cmd.view_list": "列出命名视图",
"cmd.view_rename": "重命名命名视图",
"cmd.view_save": "新建命名视图",
"dialog.custom_axis": "↖ 自定义轴",
"dialog.edit_title": "编辑 {title}",
"dialog.select": "↖ 选择",
"dialog.selected_count": "↖ 已选择 {count} 个",
"document.save_changes": "保存对 {name} 的更改?",
"document.unsaved_changes": "{name} 有未保存的更改。如果不保存,将丢失这些更改。",
"settings.msaa_applies_on_restart": "抗锯齿将在下次启动 SolidCraft 时生效",
"settings.msaa_reset": "{setting}: {requested}× 不受此图形设备支持;已重置为 {reset}× (支持: {supported})。",
"settings.msaa_unsupported": "此图形设备不支持",
"settings.reset_intro": "这些设置在此计算机上无法正常工作,会导致 SolidCraft 无法启动,因此已更改:",
"settings.reset_title": "设置已更改",
"sketch.degrees_of_freedom": "{count} 个自由度",
"sketch.draw_curves": "绘制为 {linetype}",
"sketch.make_selection": "将选择转换为 {linetype}",
"ui.1_degree_of_freedom": "1 个自由度",
"ui.3d_mouse_speed": "3D 鼠标速度",
"ui.3d_mouse_windows": "3D 鼠标(Windows)",
"ui.3d_sketch": "3D 草图",
"ui.about": "关于",
"ui.activate": "激活",
"ui.active_component": "活动组件",
"ui.agent_cursor": "代理光标",
"ui.agent_cursor_speed": "代理光标速度",
"ui.all": "全部",
"ui.angle": "角度",
"ui.angle_decimals": "角度小数位",
"ui.animate_view_changes": "视图变化动画",
"ui.animation": "动画",
"ui.animation_speed": "动画速度",
"ui.anti_aliasing": "抗锯齿",
"ui.apply": "应用",
"ui.arc": "圆弧",
"ui.assemble": "装配",
"ui.autosave_every": "自动保存间隔",
"ui.axes": "轴",
"ui.axis": "轴",
"ui.base_point": "基点",
"ui.bodies": "实体",
"ui.box": "长方体",
"ui.break": "打断",
"ui.cancel": "取消",
"ui.canvases": "画布",
"ui.center": "中心",
"ui.centerline": "中心线",
"ui.chain": "链",
"ui.chamfer": "倒角",
"ui.chamfer_type": "倒角类型",
"ui.change_workspace": "更改工作区",
"ui.chord_length": "弦长",
"ui.circle": "圆",
"ui.circular_pattern": "圆形阵列",
"ui.clear": "清除",
"ui.clear_recent": "清除最近",
"ui.clear_the_selection": "清除选择",
"ui.click_selects_whole_bodies": "单击选择整个实体",
"ui.click_then_press_key": "单击,然后按新按键",
"ui.close": "关闭",
"ui.coil": "螺旋",
"ui.coincident": "重合",
"ui.collapse": "折叠",
"ui.collinear": "共线",
"ui.combine": "组合",
"ui.coming_later": "即将推出",
"ui.concentric": "同心",
"ui.configurations": "配置",
"ui.conic_curve": "圆锥曲线",
"ui.constant": "恒定",
"ui.constraints_conflict": "约束冲突",
"ui.construct": "构造",
"ui.construction": "构造",
"ui.context_menu": "上下文菜单",
"ui.copy": "复制",
"ui.corners": "角点",
"ui.corner": "角",
"ui.counterbore": "沉头孔",
"ui.countersink": "锥形沉孔",
"ui.create": "创建",
"ui.create_copy": "创建副本",
"ui.create_sketch": "创建草图",
"ui.current": "当前",
"ui.curvature": "曲率",
"ui.curves": "曲线",
"ui.cut": "剪切",
"ui.cylinder": "圆柱体",
"ui.dark": "深色",
"ui.default_modelling_orientation": "默认建模方向",
"ui.degrees_of_freedom": "自由度",
"ui.delete": "删除",
"ui.depth": "深度",
"ui.design": "设计",
"ui.diameter": "直径",
"ui.dimension": "尺寸",
"ui.direction": "方向",
"ui.distance": "距离",
"ui.distance_1": "距离 1",
"ui.distance_2": "距离 2",
"ui.document_settings": "文档设置",
"ui.don_t_save": "不保存",
"ui.draft": "拔模",
"ui.drawing": "绘图",
"ui.drill_point": "钻尖",
"ui.edit": "编辑",
"ui.ellipse": "椭圆",
"ui.end_radius": "结束半径",
"ui.entities": "实体",
"ui.equal": "相等",
"ui.expand": "展开",
"ui.export_ellipsis": "导出...",
"ui.export_ellipsis_keymap": "导出…",
"ui.export_keymap_tip": "将按键、S 框收藏和工具栏导出为文件",
"ui.extend": "延伸",
"ui.extent_type": "延伸类型",
"ui.extrude": "拉伸",
"ui.factor": "系数",
"ui.feature_history": "特征历史",
"ui.feature_options": "特征选项",
"ui.features": "特征",
"ui.file": "文件",
"ui.fillet": "圆角",
"ui.filter_commands_or_keys": "筛选命令或按键",
"ui.finish_sketch": "完成草图",
"ui.fix_unfix": "固定/取消固定",
"ui.flat": "平面",
"ui.flip": "翻转",
"ui.front": "前视",
"ui.fully_constrained": "完全约束",
"ui.general": "常规",
"ui.graphics": "图形",
"ui.ground_shadow": "地面阴影",
"ui.heading_add_ins": "加载项",
"ui.heading_assemble": "装配",
"ui.heading_box": "长方体",
"ui.heading_chamfer": "倒角",
"ui.heading_circular_pattern": "圆形阵列",
"ui.heading_coil": "螺旋",
"ui.heading_combine": "组合",
"ui.heading_configure": "配置",
"ui.heading_constraints": "约束",
"ui.heading_construct": "构造",
"ui.heading_create": "创建",
"ui.heading_create_sketch": "创建草图",
"ui.heading_cylinder": "圆柱体",
"ui.heading_design": "设计",
"ui.heading_draft": "拔模",
"ui.heading_edit": "编辑",
"ui.heading_extrude": "拉伸",
"ui.heading_fillet": "圆角",
"ui.heading_finish_sketch": "完成草图",
"ui.heading_front": "前视",
"ui.heading_hole": "孔",
"ui.heading_home": "主页",
"ui.heading_insert": "插入",
"ui.heading_inspect": "检查",
"ui.heading_loft": "放样",
"ui.heading_make": "制作",
"ui.heading_measure": "测量",
"ui.heading_mesh": "网格",
"ui.heading_mirror": "镜像",
"ui.heading_modify": "修改",
"ui.heading_move": "移动",
"ui.heading_offset": "偏移",
"ui.heading_move_copy": "移动/复制",
"ui.heading_offset_plane": "偏移平面",
"ui.heading_ok": "确定",
"ui.heading_parameters": "参数",
"ui.heading_pattern_on_path": "路径阵列",
"ui.heading_pipe": "管道",
"ui.heading_plane_at_angle": "角度平面",
"ui.heading_plastic": "塑料",
"ui.heading_prepare": "准备",
"ui.heading_rectangular_pattern": "矩形阵列",
"ui.heading_revolve": "旋转",
"ui.heading_right": "右视",
"ui.heading_scale": "缩放",
"ui.heading_section_analysis": "截面分析",
"ui.heading_select": "选择",
"ui.heading_sheet_metal": "钣金",
"ui.heading_shell": "抽壳",
"ui.heading_sketch": "草图",
"ui.heading_sketch_palette": "草图面板",
"ui.heading_sketch_scale": "草图缩放",
"ui.heading_solid": "实体",
"ui.heading_sphere": "球体",
"ui.heading_split_body": "分割实体",
"ui.heading_surface": "曲面",
"ui.heading_sweep": "扫掠",
"ui.heading_thread": "螺纹",
"ui.heading_top": "上视",
"ui.heading_torus": "圆环体",
"ui.heading_utilities": "工具",
"ui.heading_utility": "实用工具",
"ui.help": "帮助",
"ui.hide": "隐藏",
"ui.hole": "孔",
"ui.hole_tap_type": "孔攻丝类型",
"ui.hole_type": "孔类型",
"ui.home": "主页",
"ui.horizontal_vertical": "水平/垂直",
"ui.import_ellipsis": "导入…",
"ui.insert": "插入",
"ui.inspect": "检查",
"ui.intersect": "相交",
"ui.join": "连接",
"ui.joints": "关节",
"ui.keyboard_shortcuts": "键盘快捷键",
"ui.language": "语言",
"ui.length_decimals": "长度小数位",
"ui.light": "浅色",
"ui.line": "直线",
"ui.linetype": "线型",
"ui.loft": "放样",
"ui.look_at": "朝向",
"ui.look_at_anim_desc": "轴视图、注视、主视图与适合窗口",
"ui.manufacture": "制造",
"ui.measure": "测量",
"ui.midpoint": "中点",
"ui.mirror": "镜像",
"ui.mirror_line": "镜像线",
"ui.modify": "修改",
"ui.move": "移动",
"ui.multiple": "多个",
"ui.named_views": "命名视图",
"ui.navigation": "导航",
"ui.needs_design": "{command}: 请先打开一个设计",
"ui.new_body": "新建实体",
"ui.new_design": "新建设计",
"ui.normal": "法向",
"ui.object_type": "对象类型",
"ui.objects": "对象",
"ui.offer_to_stand_up_y_up_files": "提供站立 Y-up 文件",
"ui.offset": "偏移",
"ui.offset_plane": "偏移平面",
"ui.one_side": "单侧",
"ui.open": "打开",
"ui.open_ellipsis": "打开...",
"ui.open_preferences": "打开首选项",
"ui.open_recent": "打开最近",
"ui.operation": "操作",
"ui.options": "选项",
"ui.orbit_around": "环绕",
"ui.origin": "原点",
"ui.palette_points": "点",
"ui.palette_profile": "轮廓",
"ui.pan_zoom_orbit": "平移、缩放、环绕",
"ui.parallel": "平行",
"ui.parameters": "参数",
"ui.paste": "粘贴",
"ui.path": "路径",
"ui.pattern_on_path": "路径阵列",
"ui.perpendicular": "垂直",
"ui.perspective_view": "透视图",
"ui.pipe": "管道",
"ui.placement": "放置",
"ui.plane": "平面",
"ui.plane_at_angle": "角度平面",
"ui.point": "点",
"ui.point_under_the_cursor": "光标下的点",
"ui.points": "点",
"ui.polygon": "多边形",
"ui.preferences": "首选项",
"ui.press_a_key": "按一个键…",
"ui.profile": "轮廓",
"ui.profile_plane": "轮廓平面",
"ui.profiles": "轮廓",
"ui.project": "投影",
"ui.project_face_edges_sketch": "将面的边投影到新草图",
"ui.quantity_2": "数量 2",
"ui.quantity": "数量",
"ui.quit": "退出",
"ui.radial_context_menu": "环形上下文菜单",
"ui.radius": "半径",
"ui.radius_type": "半径类型",
"ui.rectangle": "矩形",
"ui.rectangular_pattern": "矩形阵列",
"ui.redo": "重做",
"ui.render": "渲染",
"ui.renderer": "渲染器",
"ui.reset": "重置",
"ui.reset_all": "全部重置",
"ui.reset_the_settings_on_this_page": "重置此页面上的设置",
"ui.restore_defaults": "恢复默认值",
"ui.reverse_zoom_direction": "反转缩放方向",
"ui.revolve": "旋转",
"ui.right": "右视",
"ui.save": "保存",
"ui.save_as": "另存为",
"ui.save_as_ellipsis": "另存为...",
"ui.scale": "缩放",
"ui.section_analysis": "截面分析",
"ui.select": "选择",
"ui.select_other_hint": "“选择其他”:在模型上按住左键(或右键单击 › 选择其他…)列出光标下的所有对象;在同一位置再次单击可选择该处的下一个对象。",
"ui.selection": "选择",
"ui.shell": "抽壳",
"ui.show": "显示",
"ui.show_constraints": "约束",
"ui.show_dimensions": "尺寸",
"ui.show_points": "显示点",
"ui.show_profile": "显示轮廓",
"ui.show_projected_geometries": "投影几何",
"ui.simple": "简单",
"ui.simulation": "仿真",
"ui.single": "单个",
"ui.sketch": "草图",
"ui.sketch_dimension": "草图尺寸",
"ui.sketch_grid": "草图网格",
"ui.sketch_scale": "草图比例",
"ui.sketch_status": "草图状态",
"ui.sketches": "草图",
"ui.slice": "切片",
"ui.slot": "槽",
"ui.smooth": "平滑",
"ui.smooth_wheel_zoom": "平滑滚轮缩放",
"ui.smooth_wheel_zoom_tip": "关闭后每个滚轮事件立即生效,不做平滑延迟",
"ui.snap": "捕捉",
"ui.space_mouse_hint": "同时移动和旋转视图;草图中仅支持平移和缩放。",
"ui.space_mouse_navigate": "使用 SpaceNavigator / SpaceMouse 导航",
"ui.spacing_2": "间距 2",
"ui.spacing": "间距",
"ui.sphere": "球体",
"ui.spline": "样条曲线",
"ui.split_body": "分割实体",
"ui.stand_up_tip": "当 Z 朝上的 STEP 或 IGES 文件打开后,提示绕 X 轴旋转四分之一周",
"ui.start": "开始",
"ui.start_radius": "起始半径",
"ui.sweep": "扫掠",
"ui.symmetric": "对称",
"ui.symmetry": "对称",
"ui.system": "系统",
"ui.tangent": "相切",
"ui.taper_angle": "锥角",
"ui.tapped": "攻丝",
"ui.text": "文本",
"ui.theme": "主题",
"ui.thickness": "厚度",
"ui.thread": "螺纹",
"ui.timeline_bottom": "底部时间轴",
"ui.timeline_left_note": "左侧布局下,回退条显示在零件和场景浏览器的上方。",
"ui.timeline_left_sidebar": "左侧边栏",
"ui.tip_angle": "尖端角度",
"ui.to_object": "到对象",
"ui.top": "上视",
"ui.torus": "圆环体",
"ui.trackpad_pan_tip": "触控板手势用于平移(关闭:像滚轮一样缩放);鼠标滚轮缩放、拇指滚轮横向平移、双指捏合始终缩放",
"ui.trim": "修剪",
"ui.two_finger_scroll_pans": "双指滚动平移",
"ui.two_sides": "双侧",
"ui.ui_scale": "界面缩放",
"ui.undo": "撤销",
"ui.units": "单位",
"ui.units_of_new_designs": "新设计的单位",
"ui.untitled": "无标题",
"ui.up_axis_note": "视图中朝上的轴(轴视图、主视图、注视)。设计本身不变。",
"ui.variable": "变量",
"ui.view_centre": "视图中心",
"ui.visual_shaded_hidden_edges": "带隐藏边的着色",
"ui.visual_shaded_with_edges": "带边着色",
"ui.visual_style": "视觉样式",
"ui.visual_wireframe": "线框",
"ui.workspace": "工作区",
"ui.y_distance": "Y 距离",
"ui.x_distance": "X 距离",
"ui.y_up": "Y 朝上",
"ui.z_up": "Z 朝上",
"ui.zoom_to_cursor_tip": "滚轮向光标所在点缩放(关闭:向视图中心缩放)",
"ui.zoom_to_the_cursor": "缩放到光标",
"A new configuration, a copy of the active one": "新建配置,为当前配置的副本",
"About SolidCraft": "关于 SolidCraft",
"Active": "活动",
"Active rule": "活动规则",
"Add": "添加",
"Add Key": "添加按键",
"Add Mid Radius": "添加中间半径",
"Add Row": "添加行",
"All Sketch Points": "所有草图点",
"All open designs": "所有打开的设计",
"Allowed expressions, separated by semicolons": "允许的表达式,以分号分隔",
"Also deletes": "同时删除",
"Angle 2": "角度 2",
"Animate": "动画",
"Appearance name": "外观名称",
"Applied Radius": "应用半径",
"Apply To": "应用于",
"Area": "面积",
"Attachment": "附着",
"BROWSER": "浏览器",
"Bend Line Position": "弯折线位置",
"Bend Position": "折弯位置",
"Bend Radius": "折弯半径",
"Bends": "折弯",
"Body": "实体",
"Bounding box": "边界框",
"CSV or JSON: updates existing parameters, adds new ones": "CSV 或 JSON:更新现有参数、添加新参数",
"Capture All Positions": "捕获所有位置",
"Catch Direction": "卡扣方向",
"Cells": "区域",
"Center X": "中心 X",
"Center Y": "中心 Y",
"Center of mass": "质心",
"Chamfer Type": "倒角类型",
"Check collisions": "检查碰撞",
"Checked": "已检查",
"Choose a new plane. Sketch geometry and dimensions stay unchanged in its two-dimensional coordinates.": "选择一个新平面。草图几何和尺寸在其二维坐标中保持不变。",
"Close draft": "关闭草稿",
"Collisions": "碰撞",
"Colour": "颜色",
"Component1": "组件1",
"Configuration": "配置",
"Configuration rules": "配置规则",
"Contact": "接触",
"Copy all licences": "复制所有许可证",
"Copy diagnostic information": "复制诊断信息",
"Copy report": "复制报告",
"Corner Relief Shape": "拐角释放形状",
"Counterbore depth": "沉孔深度",
"Countersink angle": "沉头角度",
"Create Issue — review draft": "创建 Issue——审阅草稿",
"Customize Toolbar": "自定义工具栏",
"Delete all": "全部删除",
"Delete rule": "删除规则",
"Delete the row": "删除此行",
"Delete the set": "删除此集合",
"Delete this parameter": "删除此参数",
"Density": "密度",
"Designs you open or save appear here.": "你打开或保存的设计会显示在此处。",
"Determined by To Object. Choose Angle to edit the angular extent.": "由“到对象”确定。选择“角度”可编辑角度范围。",
"Discard": "放弃",
"Double-click to rename": "双击重命名",
"Drive Joint": "驱动接头",
"Edit Profile Sketch": "编辑轮廓草图",
"Enable rule": "启用规则",
"Enabled": "已启用",
"Explode": "爆炸",
"Extents": "范围",
"Face attachment lost": "面附着丢失",
"Faces / edges / vertices": "面 / 边 / 顶点",
"Favourite": "收藏",
"Files from many CAD programs have Y up, so they open lying on their back here (Z up).": "许多 CAD 程序的文件以 Y 为上轴,因此在此处打开时会平躺(Z 朝上)。",
"Filter": "筛选",
"Find in Browser": "在浏览器中查找",
"Flat size": "平板尺寸",
"Follow camera (Look At sketches)": "跟随相机(注视草图)",
"Font": "字体",
"Full Length": "全长",
"Gap": "间隙",
"Grid": "网格",
"Height": "高度",
"Home view": "主视图",
"In This Design": "在此设计中",
"Interferes": "发生干涉",
"Issue title": "Issue 标题",
"Joint Origin1": "接头原点1",
"Keep Tools": "保留工具",
"Later": "稍后",
"Leave it": "保持原样",
"Legacy face attachment. Rebinding to a certified face creates an exact attachment.": "旧版面附着。重新绑定到经验证的面可创建精确附着。",
"Length": "长度",
"Length units": "长度单位",
"Library": "零件库",
"Loop": "循环",
"Margin": "余量",
"Mass": "质量",
"Material": "材质",
"Mid Radius": "中间半径",
"Modeled": "已建模",
"More toolbar panels": "更多工具栏面板",
"Motion": "运动",
"Move Type": "移动类型",
"Move earlier": "向前移动",
"Move later": "向后移动",
"Name": "名称",
"No crash reports.": "没有崩溃报告。",
"No matching appearances": "没有匹配的外观",
"Not available yet": "暂不可用",
"Opacity": "不透明度",
"Open GitHub draft": "打开 GitHub 草稿",
"Open-source parametric 3D CAD in Rust. Licensed MIT OR Apache-2.0.": "使用 Rust 编写的开源参数化 3D CAD。基于 MIT OR Apache-2.0 许可。",
"Other side": "另一侧",
"Parameter values": "参数值",
"Per Edge": "每条边",
"Pick the tool bodies": "选择工具实体",
"Place at the origin instead": "改为放置在原点",
"Playback": "播放",
"Position": "位置",
"Position (0 to 1)": "位置(0 到 1)",
"Position along the edge, 0 at the start end, 1 at the other": "沿边的位置,起点端为 0,另一端为 1",
"Preview leaves the current design unchanged.": "预览不会更改当前设计。",
"RECENT": "最近使用",
"Radius Fit": "半径拟合",
"Ratio": "比率",
"Recover": "恢复",
"Recover unsaved design?": "恢复未保存的设计?",
"Remove Tools": "移除工具",
"Remove from list": "从列表移除",
"Remove private design details or paths before sharing.": "共享前请移除私密设计细节或路径。",
"Remove the column": "移除此列",
"Remove the track": "移除轨迹",
"Remove this point": "移除此点",
"Report a bug — review a screenshot and open a GitHub draft": "报告缺陷 — 复核截图并开启 GitHub 草稿",
"Reset Toolbar": "重置工具栏",
"Restore the inherited component or physical material appearance": "还原继承的组件或物理材质外观",
"Result": "结果",
"Retake screenshot": "重新截图",
"Reverse": "反向",
"Reverse Direction": "反向",
"Revert": "还原",
"Revert All Positions": "还原所有位置",
"Review the report and screenshot before opening GitHub.": "打开 GitHub 前请审阅报告和截图。",
"Rim Edge": "轮缘边",
"Roll History Marker Here": "将历史标记滚动到此处",
"Rule": "规则",
"Saved preview. Geometry is being checked before editing.": "已保存预览。编辑前正在检查几何。",
"Scale factor": "比例因子",
"Search": "搜索",
"Search commands": "搜索命令",
"Select bodies (a face picks its body)": "选择实体(单击面即选择其所属实体)",
"Select bodies or faces instead": "改为选择实体或面",
"Selection filter": "选择筛选",
"Semantic faces share their appearance across instances.": "语义面在各实例间共享外观。",
"Shape": "形状",
"Show Agent Cursor": "显示代理光标",
"Show in folder": "在文件夹中显示",
"Size": "大小",
"Sketch plane has no body-face attachment.": "草图平面没有实体面附着。",
"SolidCraft closed before these designs were saved. Their last autosave can be opened.": "SolidCraft 在这些设计保存前已关闭。可以打开它们的上次自动保存。",
"Speed": "速度",
"Stand it up": "将其立起",
"Stand it up: a quarter turn about X, as one Move feature you can undo.": "将其立起:绕 X 轴旋转四分之一周,作为一个可撤销的移动特征。",
"Stand this part up?": "立起此零件?",
"Step": "步骤",
"Steps": "步数",
"Suppressed": "已抑制",
"Swap Ends": "交换端点",
"Tangent Chain": "相切链",
"The dashed sketch is a saved plane guide. Select a new face to repair the attachment.": "虚线草图是已保存的平面引导。选择一个新面以修复附着。",
"The saved author occurrence is missing. Select a valid author placement before rebinding.": "保存的作者实例缺失。重新绑定前请选择有效的作者放置。",
"Then": "操作",
"These features will be deleted:": "以下特征将被删除:",
"These features will fail:": "以下特征将失败:",
"This child is shared. Deleting it removes it from every copy of its parent.": "此子项是共享的。删除它会从其父项的每个副本中移除。",
"This child is shared. Position changes apply to every copy of its parent.": "此子项是共享的。位置更改会应用到其父项的每个副本。",
"This face cannot provide a durable attachment. Choose another face or explicitly use a fixed plane.": "此面无法提供持久附着。请选择其他面或显式使用固定平面。",
"To Offset": "偏移",
"Tolerance": "公差",
"Type": "类型",
"Updating the preview": "正在更新预览",
"Use fixed plane": "使用固定平面",
"VIEW": "视图",
"Value": "值",
"Volume": "体积",
"Wall": "壁厚",
"When": "条件",
"Width": "宽度",
"Will fail": "将失败",
"angle, height": "角度、高度",
"command name": "命令名称",
"expression, e.g. 25 mm": "表达式,例如 25 mm",
"fits the face, e.g. M8": "适配该面,例如 M8",
"from the rule": "来自规则",
"needs two joints": "需要两个接头",
"new configuration": "新配置",
"new name": "新名称",
"new parameter": "新参数",
"no interference": "无干涉",
"no joint that moves yet": "尚无运动接头",
"no picture": "无图片",
"pick a hole to seat it, or OK places it at the origin": "选择一个孔放置,或单击确定放置在原点",
"pick one or two vertices, edges or faces": "选择一个或两个顶点、边或面",
"the parts library is not available": "零件库不可用",
"to the next face": "到下一个面",
"Revert Position": "恢复位置",
"Construction": "构造",
"Faces": "面",
"Edges": "边",
"Vertices": "顶点",
"Sketch geometry and profiles": "草图几何和轮廓",
"Sketch curves": "草图曲线",
"Sketch points": "草图点",
"Sketch dimensions": "草图尺寸",
"Sketch constraints": "草图约束",
"0 turns it off": "0 表示关闭",
"Show the pointer an AI agent moves (#35)": "显示 AI 代理移动的指针(#35)",
"Follow the camera (Look At sketches)": "跟随相机(注视草图)",
"Flat": "平面",
"Save Rule": "保存规则",
"Preview Row": "预览行",
"Add condition": "添加条件",
"Apply to selection": "应用到选择",
"Remove override": "移除覆盖",
"Copy screenshot": "复制截图",
"Remove screenshot": "移除截图",
"Use active author placement": "使用活动作者放置",
"Reattach selected face": "重新附着所选面",
"Use saved fixed plane": "使用已保存的固定平面",
"Use selected face as fixed plane": "使用所选面作为固定平面",
"View navigator": "视图导航器",
"Signed axes": "带符号轴",
"Cube": "立方体",
"Middle double-click": "中键双击",
"Double-clicking the middle button in the view: Home (the home view, framing what is shown), Fit (frame what is shown, keeping the orientation) or nothing": "在视图中双击中键:主视图(主视图,框住所显示的内容)、适合窗口(框住所显示的内容,保持方向)或无动作",
"Select Other: hold the left button still on the model (or right-click › Select Other…) to list everything under the cursor; click again on the same spot to select the next thing there. Double-click the middle button to go Home (Preferences › Navigation).": "“选择其他”:在模型上按住左键(或右键单击 › 选择其他…)列出光标下的所有对象;在同一位置再次单击可选择该处的下一个对象。双击中键转到主视图(首选项 › 导航)。",
"cmd.render_backends": "渲染后端",
"cmd.view_navigate": "导航视图",
"ui.animateJoint": "动画接头",
"ui.calibrate": "校准",
"ui.customizeToolbar": "自定义工具栏…",
"ui.editJointLimits": "编辑接头限制",
"ui.exportDxf": "导出 DXF…",
"ui.findInTimeline": "在时间线中查找",
"ui.findInWindow": "在窗口中查找",
"ui.fit": "适合",
"ui.groupSelected": "将所选编组",
"ui.hideAxes": "隐藏轴",
"ui.hideDimension": "隐藏尺寸",
"ui.hideOrigin": "隐藏原点",
"ui.hidePlanes": "隐藏平面",
"ui.hideProfile": "隐藏轮廓",
"ui.homeView": "主视图",
"ui.isolate": "隔离",
"ui.lock": "锁定",
"ui.newSketchGroup": "新建草图组",
"ui.normalConstruction": "普通 / 构造",
"ui.orbit": "环绕",
"ui.heading_position": "位置",
"ui.pan": "平移",
"ui.pinToShortcuts": "固定到快捷方式",
"ui.pinToToolbar": "固定到工具栏",
"ui.properties": "属性",
"ui.removeSection": "移除剖面",
"ui.removeFromToolbar": "从工具栏移除",
"ui.repeat": "重复",
"ui.report_a_bug": "报告缺陷",
"ui.restore": "还原",
"ui.heading_setup": "设置",
"ui.selectOther": "选择其他…",
"ui.selectTangentChain": "选择相切链",
"ui.showAll": "显示全部",
"ui.showAllBodies": "显示所有实体",
"ui.showAxes": "显示轴",
"ui.showDimension": "显示尺寸",
"ui.showOrigin": "显示原点",
"ui.showPlanes": "显示平面",
"ui.suppress": "抑制",
"ui.command_palette_hint": "输入命令,例如 {example} — 或按 S 搜索",
"ui.unground": "取消固定",
"ui.unisolate": "取消隔离",
"ui.unlock": "解锁",
"ui.unsuppress": "取消抑制",
"ui.updateToCurrentView": "更新为当前视图",
"ui.zoom": "缩放",
"ui.command_done": "{command} 完成",
"timeline.group": "新建特征文件夹",
"timeline.ungroup": "移除特征文件夹",
"timeline.rename_group": "重命名特征文件夹",
"timeline.move_to_group": "将特征移至文件夹",
"timeline.move_many": "移动时间线项目",
"timeline.reorder_many": "特征重新排序",
"ui.show_construction_geometries": "构造几何图元",
"ui.total_angle": "总角度",
"sketch_text.builtin_font": "{family}(内置)",
"sketch_text.font_search": "搜索字体",
"sketch_text.loading_fonts": "正在查找已安装字体…",
"sketch_text.use_font_file": "使用字体文件 {path}",
"sketch_text.bold": "粗体",
"sketch_text.italic": "斜体",
"sketch_text.align_left": "左对齐",
"sketch_text.align_center": "居中",
"sketch_text.align_right": "右对齐",
"sketch_text.path_hint": "文字所跟随的草图曲线:先单击此处,再选择曲线",
"sketch_text.path_clear": "将文字移离其曲线",
"Style": "样式",
"Alignment": "对齐",
"Letter Spacing": "字间距",
"Line Spacing": "行间距",
"Path": "路径",
"sketch_text.on_path": "文字沿路径排列:由曲线放置",
"ui.analysis": "分析",
"ui.edit_section_analysis": "编辑截面分析"
}
+3 -1
View File
@@ -67,7 +67,9 @@ pub fn palette_bar(app: &mut SolveApp, ui: &mut egui::Ui) {
ui.label(RichText::new("›").strong().color(t.accent));
let r = ui.add(
egui::TextEdit::singleline(&mut app.palette.text)
.hint_text("Type a command, e.g. Extrude {\"distance\": 20} — or press S to search")
// The JSON example keeps its braces here rather than in the catalog, so the
// placeholder parser never has to treat JSON punctuation as a name.
.hint_text(crate::i18n::format("ui.command_palette_hint", &[("example", "Extrude {\"distance\": 20}")]))
.desired_width(520.0),
);
if app.palette.focus {
+6 -4
View File
@@ -860,13 +860,15 @@ fn page(app: &mut SolveApp, ui: &mut egui::Ui, t: &Tokens) {
);
crate::scenario::publish_rect("prefs:scale", scale.rect);
ui.end_row();
ui.label("Feature history");
ui.label(app.tr("ui.feature_history"));
let timeline_bottom = app.tr("ui.timeline_bottom").to_string();
let timeline_left = app.tr("ui.timeline_left_sidebar").to_string();
ui.horizontal(|ui| {
ui.radio_value(&mut app.preferences.timeline_left, false, "Bottom timeline");
ui.radio_value(&mut app.preferences.timeline_left, true, "Left sidebar");
ui.radio_value(&mut app.preferences.timeline_left, false, timeline_bottom);
ui.radio_value(&mut app.preferences.timeline_left, true, timeline_left);
});
ui.end_row();
note(ui, "The left layout shows the rollback bar above the parts and scene browser.");
note(ui, app.tr("ui.timeline_left_note"));
ui.label(app.tr("ui.units_of_new_designs"));
egui::ComboBox::from_id_salt("pref_units").selected_text(app.preferences.default_units.clone()).show_ui(ui, |ui| {
for u in UNITS {
+3 -2
View File
@@ -296,7 +296,8 @@ pub fn app_bar(app: &mut SolveApp, ui: &mut egui::Ui) {
tabs_ui.set_clip_rect(tabs_rect.intersect(ui.clip_rect()));
crate::documents::tabs(app, &mut tabs_ui, r, tabs_start, tabs_end);
let response = ui.interact(report, ui.id().with("sc_report_button"), Sense::click());
response.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, ui.is_enabled(), "Report a bug"));
let report_text = crate::i18n::tr("ui.report_a_bug");
response.widget_info(|| egui::WidgetInfo::labeled(egui::WidgetType::Button, ui.is_enabled(), report_text));
crate::scenario::publish_handle("titlebar:report", report.center());
ui.painter().rect_filled(report, 4.0, if response.hovered() || response.has_focus() { t.hover } else { t.app_bar });
ui.painter().rect_stroke(report, 4.0, Stroke::new(1.0, t.border), egui::StrokeKind::Inside);
@@ -306,7 +307,7 @@ pub fn app_bar(app: &mut SolveApp, ui: &mut egui::Ui) {
ui.painter().text(
pos2(report.left() + 29.0, report.center().y),
Align2::LEFT_CENTER,
"Report a bug",
report_text,
FontId::proportional(13.0),
t.app_bar_text,
);
+1 -1
View File
@@ -123,7 +123,7 @@ unit regardless of the design, pass an expression with one: `"value": "50 mm"` o
| `ui.home` | `open?`: bool; `sample?`: index | the start page: show or hide it, open a built-in sample (once built); returns `open` and the recent designs |
| `ui.shortcut` | `command`, `key?`, `replace?` | a command's key, or rebinds it (`""` clears; a key another command uses is refused unless `replace`) |
| `ui.help` | `item?`: `about`, `shortcuts` (read only), `report` (copies diagnostics), `crashes` (the Crash Reports window) | the version, commit, build date and diagnostic text |
| `ui.prefs` | any of `default_units`, `nav` (`fusion`, `solidworks`, `inventor`, `alias`, `tinkercad`, `openscad`), `zoom_reverse`, `zoom_to_cursor`, `smooth_wheel_zoom` (default true), `trackpad_pan` (default true: two-finger scroll pans, pinch zooms), `orbit_cursor`, `look_at_anim`, `look_at_speed`, `middle_double_click` (`home` (default), `fit`, `off`), `msaa`, `length_decimals`, `angle_decimals`, `theme` (`dark`, `light`, `system`), `language` (`en`, `ja`; see [localization](localization.md)), `ui_scale`, `up_axis` (`z`, `y`), `offer_stand_up`; `open` (a page: General, Navigation, Keyboard Shortcuts, Design, Graphics, Sketch, Selection) opens the Preferences dialog there; `button`: `ok`, `cancel`, `apply`, `defaults`; `stand_up: true` stands up a just-opened Y-up file | sets preferences (kept between runs), returns them all plus `dialog` (the open page or null), `dark` and `stand_up_offer` |
| `ui.prefs` | any of `default_units`, `nav` (`fusion`, `solidworks`, `inventor`, `alias`, `tinkercad`, `openscad`), `zoom_reverse`, `zoom_to_cursor`, `smooth_wheel_zoom` (default true), `trackpad_pan` (default true: two-finger scroll pans, pinch zooms), `orbit_cursor`, `look_at_anim`, `look_at_speed`, `middle_double_click` (`home` (default), `fit`, `off`), `msaa`, `length_decimals`, `angle_decimals`, `theme` (`dark`, `light`, `system`), `language` (`en`, `ja`, `de`, `ko`, `zh`; see [localization](localization.md)), `ui_scale`, `up_axis` (`z`, `y`), `offer_stand_up`; `open` (a page: General, Navigation, Keyboard Shortcuts, Design, Graphics, Sketch, Selection) opens the Preferences dialog there; `button`: `ok`, `cancel`, `apply`, `defaults`; `stand_up: true` stands up a just-opened Y-up file | sets preferences (kept between runs), returns them all plus `dialog` (the open page or null), `dark` and `stand_up_offer` |
| `ui.capture` | `action?`: `capture`, `revert`, `cancel` | answers the Capture Position question (asked when a command starts or the design is saved while components were moved without capturing); without `action`, what waits |
| `ui.window` | `action`: minimize, maximize, restore, toggle, close | what the title bar's caption buttons do (on Windows and Linux the application bar is the title bar); close asks about unsaved designs first |
| `ui.agent_cursor` | `show` (bool), `speed`: a number from 1 to 5 (times the normal speed) or `"instant"` (no animation: the command runs at once and the pointer jumps to where it acted), `follow_camera` (bool); all optional | the settings. While the cursor is shown, `engine.execute` first glides to the command's toolbar button and to each pick, then runs and replies; later requests wait their turn. `"animate": false` on a call skips it |
+47 -10
View File
@@ -1,8 +1,9 @@
# UI localization
SolidCraft embeds its translations and works offline. English and Japanese are currently
registered in `crates/ui-egui/src/i18n.rs`. Adding a language requires an embedded catalog and
one registration there; the preferences selector and validation use the same registry.
SolidCraft embeds its translations and works offline. English, Japanese, German, Korean and
Chinese are currently registered in `crates/ui-egui/src/i18n.rs`. Adding a language requires an
embedded catalog and one registration there; the preferences selector and validation use the same
registry.
## Messages
@@ -23,6 +24,37 @@ Catalogs are parsed once and looked up through ordered maps. This is offline loc
not a claim of zero runtime overhead. The catalog tests check registered locale IDs,
translation keys, and placeholder consistency. Run `cargo xtask ci` before submitting changes.
## Coverage
A message a locale never received falls back to English silently, so a gap shows up only as a row
that looks untranslated. Two guards catch that in the build:
- `every_complete_catalog_carries_every_english_message` — adding a key to `en.json`
without giving it to a complete catalog fails the tests. English is the source catalog,
Japanese and Chinese are delivered complete; German and Korean are still partial — their
gaps are reported by `cargo xtask i18n` without failing the build.
- `every_toolbar_tab_and_panel_is_in_the_english_catalog` — tabs and panels reach the UI as bare
source strings, resolved only by the English-label adapter, so a heading missing from `en.json`
can never translate.
Command labels are the same case on a larger scale: every label in the engine's registry now has
an entry under `cmd.<command id>`, and `every_command_label_is_in_the_english_catalog` fails if a
command is added without one.
The context menu and the browser are the same case again, and they carry the most labels of all:
`every_menu_label_is_in_the_english_catalog` opens every menu the app can reach, flips the state
each conditional label branches on (origin shown, bodies locked, bodies hidden) so both branches
are seen, and fails on any label the catalog has never seen. Unit symbols are left out of the
sweep: `mm` is `mm` in every language, so they are not prose to translate. The sweep also asserts
it keeps reaching a broad set of labels, so it cannot pass by finding nothing.
`cargo xtask i18n` prints the same picture across every locale — which messages each one is
missing and which command labels English cannot translate. `--check` turns it into a non-zero exit
for CI. `--add-missing` writes each uncovered label into `en.json` under `cmd.<command id>`, with
the English label as its text, so the label adapter can find it and only the translations are left
to do. One key per distinct label: two commands that share a label (`Trim`, `Extend`) must not both
claim it, or the English-text lookup would silently pick one.
## Rendering and coverage
One immutable `Locale` type handles all translations. Table widgets without an app reference
@@ -31,18 +63,23 @@ Standalone translated panels enter the same scope. Measure rendered text to size
widgets; UTF-8 byte lengths do not describe their displayed width.
The desktop host tries system CJK fonts across Windows, macOS and Linux, as well as an optional
`CRAFT_FONTS_DIR` font pack, and skips files that cannot be parsed. No fonts are redistributed
in native desktop distribution packages; native builds rely entirely on existing operating system fonts
or craft-fonts.
`CRAFT_FONTS_DIR` font pack, and skips files that cannot be parsed. Chinese uses its own fallback
chain after the general CJK font: many Japanese CJK fonts (Hiragino Gothic, Meiryo, Yu Gothic)
match the CJK font search but lack simplified characters, so a second fallback found by the
Chinese font-name list (`PingFang`, `Microsoft YaHei`, `Noto Sans CJK SC`, …) covers them per
glyph. No fonts are redistributed in native desktop distribution packages; native builds rely
entirely on existing operating system fonts or craft-fonts.
In the browser, `solidcraft-web` bundles a self-hosted Japanese font (`BIZUDPGothic-Regular.ttf`, licensed
under SIL OFL 1.1) within the web distribution artifacts only. The font is loaded asynchronously from the same
origin (`./fonts/BIZUDPGothic-Regular.ttf`) on-demand when the interface language is set to Japanese, or, with
origin (`./fonts/BIZUDPGothic-Regular.ttf`) on-demand when the interface language is a CJK one, or, with
any other interface language, the first time Japanese text (kana, kanji or full-width forms in a design name,
file name, body name or typed text) is drawn, without contacting any external CDNs or third-party servers.
A session that never shows such text downloads no font. If font loading fails with the Japanese interface,
the web interface shows English for that session only to prevent missing glyphs (tofu); the saved language
preference is kept, so the next visit tries again. This bundled font specifically targets Japanese; Korean (Hangul) and Chinese scripts are not covered.
A session that never shows such text downloads no font. If font loading fails with a CJK interface, the web
interface shows English for that session only to prevent missing glyphs (tofu); the saved language
preference is kept, so the next visit tries again. The bundled font specifically targets Japanese; it also
renders the kanji Chinese shares with Japanese, while Korean (Hangul) and simplified-only Chinese characters
are not covered, so a self-hosted SC/Korean font bundle remains follow-up work for full web coverage.
The current messages support named substitution, not locale-specific plural selection,
number/date formatting, or right-to-left layout and shaping. Add those capabilities when
+232
View File
@@ -0,0 +1,232 @@
//! `cargo xtask i18n`: the message catalogs' coverage report, and a way to repair it.
//!
//! The catalogs under `crates/ui-egui/src/locales` are plain JSON maps from a stable message id
//! to one translation. The English catalog is also the lookup table for `Locale::label()`, which
//! translates source strings coming from the engine (command labels, toolbar tabs and panels) by
//! matching their English text. A label the English catalog does not carry therefore stays English
//! in *every* locale, silently — nothing fails, the row just looks untranslated.
//!
//! That is the failure this command exists to make visible. `--check` turns the report into a
//! non-zero exit for CI; `--add-missing` writes the uncovered command labels into the English
//! catalog under `cmd.<command id>` so a translator only has to fill in the other catalogs.
//!
//! German and Korean predate the coverage guards and are still partial, so their gaps are
//! reported but do not fail `--check`; the catalogs delivered complete (`COMPLETE`) may not
//! regress.
use std::collections::BTreeMap;
use std::path::Path;
use serde_json::{Map, Value};
/// Where the catalogs live, and the file the English one must lead.
const DIR: &str = "crates/ui-egui/src/locales";
/// Catalogs delivered complete: a missing message here fails `--check`. English is the source
/// catalog and is checked implicitly; keep this in step with `COMPLETE` in `ui-egui::i18n`.
const COMPLETE: &[&str] = &["ja", "zh"];
/// What `run` found.
#[derive(Default)]
struct Report {
/// Locale id → the English message ids it has not translated.
missing: BTreeMap<String, Vec<String>>,
/// Command label → the command ids that use it, for labels English does not carry.
untranslated: BTreeMap<String, Vec<String>>,
}
impl Report {
/// Gaps that must be repaired (complete catalogs only; partial catalogs are reported).
fn problems(&self) -> usize {
self.missing.iter().filter(|(id, _)| COMPLETE.contains(&id.as_str())).map(|(_, m)| m.len()).sum::<usize>() + self.untranslated.len()
}
/// Gaps in catalogs that are still allowed to be partial.
fn reported_only(&self) -> usize {
self.missing.iter().filter(|(id, _)| !COMPLETE.contains(&id.as_str())).map(|(_, m)| m.len()).sum()
}
}
pub fn run(root: &Path, args: &[&str]) -> Result<(), String> {
let english = read(root, "en")?;
let mut catalogs: Vec<(String, Map<String, Value>)> = Vec::new();
for id in locales(root)? {
let messages = read(root, &id)?;
catalogs.push((id, messages));
}
let mut report = Report::default();
for (id, messages) in &catalogs {
if id == "en" {
continue;
}
let missing: Vec<String> = english.keys().filter(|k| !messages.contains_key(*k)).cloned().collect();
if !missing.is_empty() {
report.missing.insert(id.clone(), missing);
}
}
let known: Vec<&str> = english.values().filter_map(Value::as_str).collect();
for (label, ids) in labels_needing_translation(&known) {
report.untranslated.insert(label, ids);
}
if args.contains(&"--add-missing") {
let added = add_missing(root, &mut report)?;
println!("i18n: wrote {added} new English message(s) into {DIR}/en.json");
return Ok(());
}
print_report(&report);
if args.contains(&"--check") {
if report.problems() > 0 {
return Err(format!(
"{} message(s) missing from a complete catalog and {} command label(s) with no English entry \
(see above); `cargo xtask i18n --add-missing` writes the labels into en.json",
report.missing.iter().filter(|(id, _)| COMPLETE.contains(&id.as_str())).map(|(_, m)| m.len()).sum::<usize>(),
report.untranslated.len()
));
}
if report.reported_only() > 0 {
println!(
"i18n: every complete catalog ({}) carries every English message and every command label is translatable; \
{} message(s) are still missing from the partial catalogs (de, ko)",
COMPLETE.join(", "),
report.reported_only()
);
} else {
println!("i18n: every catalog carries every English message; every command label is translatable");
}
}
Ok(())
}
/// Locale ids other than English: every catalog file that sits beside `en.json`, so a newly
/// added locale is picked up without editing this command.
fn locales(root: &Path) -> Result<Vec<String>, String> {
let dir = root.join(DIR);
let entries = std::fs::read_dir(&dir).map_err(|e| format!("{}: {e}", dir.display()))?;
let mut ids: Vec<String> = entries
.filter_map(Result::ok)
.map(|e| e.path())
.filter(|p| p.extension().and_then(|x| x.to_str()) == Some("json"))
.filter_map(|p| p.file_stem().map(|s| s.to_string_lossy().into_owned()))
.filter(|id| id != "en")
.collect();
ids.sort();
Ok(ids)
}
fn read(root: &Path, locale: &str) -> Result<Map<String, Value>, String> {
let path = root.join(DIR).join(format!("{locale}.json"));
let text = std::fs::read_to_string(&path).map_err(|e| format!("{}: {e}", path.display()))?;
match serde_json::from_str(&text) {
Ok(Value::Object(map)) => Ok(map),
Ok(_) => Err(format!("{}: a catalog must be a JSON object", path.display())),
Err(e) => Err(format!("{}: {e}", path.display())),
}
}
/// Command labels the English catalog cannot translate, mapped to the commands that use them.
///
/// The registry is read through `solidcraft-cli commands` so the report comes from the real
/// command table, never from a copy of it.
fn labels_needing_translation(known: &[&str]) -> BTreeMap<String, Vec<String>> {
let mut out: BTreeMap<String, Vec<String>> = BTreeMap::new();
let Ok(commands) = registry() else {
return out;
};
for command in commands {
let (Some(id), Some(label)) = (command["id"].as_str(), command["label"].as_str()) else {
continue;
};
if known.contains(&label) {
continue;
}
let ids = out.entry(label.to_string()).or_default();
if !ids.iter().any(|x| x == id) {
ids.push(id.to_string());
}
}
out
}
fn registry() -> Result<Vec<Value>, String> {
let out = crate::cargo()
.args(["run", "-q", "--release", "-p", "solidcraft-cli", "--", "commands"])
.output()
.map_err(|e| format!("solidcraft-cli: {e}"))?;
if !out.status.success() {
return Err(format!("solidcraft-cli commands failed:\n{}", String::from_utf8_lossy(&out.stderr)));
}
serde_json::from_slice(&out.stdout).map_err(|e| format!("commands JSON: {e}"))
}
/// Write one `cmd.<command id>` entry per still-untranslated label into the English catalog and
/// drop the newly covered labels from the report.
fn add_missing(root: &Path, report: &mut Report) -> Result<usize, String> {
if report.untranslated.is_empty() {
return Ok(0);
}
let path = root.join(DIR).join("en.json");
let mut english = read(root, "en")?;
// One key per label, so two commands sharing a label cannot collide in `label()`'s
// English-text → id table. The lowest command id wins, keeping the entry stable.
let mut chosen: BTreeMap<String, String> = BTreeMap::new();
for (label, ids) in &report.untranslated {
if let Some(id) = ids.iter().min() {
chosen.insert(label.clone(), format!("cmd.{id}"));
}
}
for (label, key) in &chosen {
if english.contains_key(key) {
continue;
}
english.insert(key.clone(), Value::String(label.clone()));
}
english.sort_keys();
std::fs::write(&path, serde_json::to_string_pretty(&Value::Object(english)).map_err(|e| e.to_string())? + "\n")
.map_err(|e| format!("{}: {e}", path.display()))?;
let added = chosen.len();
report.untranslated.clear();
Ok(added)
}
fn print_report(report: &Report) {
for (locale, missing) in &report.missing {
println!("i18n: {locale} is missing {} English message(s):", missing.len());
for id in missing {
println!(" {id}");
}
}
if !report.untranslated.is_empty() {
println!("i18n: {} command label(s) have no English catalog entry, so they stay English in every locale:", report.untranslated.len());
for (label, ids) in &report.untranslated {
println!(" {label:<42} {}", ids.join(", "));
}
println!("i18n: run `cargo xtask i18n --add-missing` to add them to en.json, then translate them.");
}
if report.problems() == 0 {
println!("i18n: catalogs complete; every command label is translatable");
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn report_counts_both_kinds_of_gap() {
let report = Report {
missing: BTreeMap::from([("zh".into(), vec!["a".into(), "b".into()])]),
untranslated: BTreeMap::from([("Flange".into(), vec!["sheet.flange".into()])]),
};
assert_eq!(report.problems(), 3);
}
#[test]
fn an_empty_report_has_no_problems() {
assert_eq!(Report::default().problems(), 0);
}
}
+8
View File
@@ -6,6 +6,7 @@
mod assets;
mod book;
mod features;
mod i18n;
mod layers;
mod licences;
mod test;
@@ -20,6 +21,12 @@ commands:
layers enforce the crate dependency layering (plan/architecture.md §3)
assets check that every non-code asset file is attributed in ATTRIBUTION.md
features list SolidCraft's commands by area in docs/features.md (from the registry)
i18n [--check | --add-missing]
report how complete the message catalogs in crates/ui-egui/src/locales are:
which messages a locale has not translated and which command labels the English
catalog cannot translate (so they stay English everywhere). --check fails when
there is a gap, for CI; --add-missing writes the uncovered command labels into
en.json under cmd.<command id> so only the translations are left to do
oracle [--cli BIN]
replay the reference tests (tests/oracle/*/recipe.json), compare with each
case's expected.json and write docs/oracle.md (--cli: a solidcraft-cli
@@ -49,6 +56,7 @@ fn main() -> ExitCode {
Some("layers") => cmd_layers(),
Some("assets") => assets::run(&root()),
Some("features") => features::run(&root()),
Some("i18n") => i18n::run(&root(), &rest),
Some("oracle") => cmd_oracle(rest.iter().position(|a| *a == "--cli").and_then(|i| rest.get(i + 1)).copied()),
Some("action-matrix") => {
cmd_action_matrix(rest.contains(&"--bless"), rest.iter().position(|a| *a == "--results").and_then(|i| rest.get(i + 1)).copied())