You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

2492 lines
132 KiB

"use client";
import { createContext, useContext, useEffect, useMemo, useState } from "react";
export type Language = "en" | "zh-CN" | "zh-TW" | "ja";
type Dictionary = typeof en;
export type TranslationKey = keyof Dictionary;
const STORAGE_KEY = "popiart-node-language";
export const LANGUAGE_OPTIONS: { value: Language; label: string }[] = [
{ value: "en", label: "English" },
{ value: "zh-CN", label: "简体中文" },
{ value: "zh-TW", label: "繁體中文" },
{ value: "ja", label: "日本語" },
];
const en = {
"language.label": "Language",
"brand.name": "popiart-node",
"common.back": "Back",
"common.next": "Next",
"common.cancel": "Cancel",
"common.close": "Close",
"common.save": "Save",
"common.create": "Create",
"common.browse": "Browse",
"common.change": "Change",
"common.clear": "Clear",
"common.select": "Select",
"common.selectModel": "Select Model",
"common.skip": "Skip",
"common.show": "Show",
"common.hide": "Hide",
"common.override": "Override",
"common.configuredViaEnv": "Configured via .env",
"common.recommended": "Recommended",
"common.optional": "Optional",
"common.required": "Required",
"common.download": "Download",
"common.remove": "Remove",
"common.disconnect": "Disconnect",
"common.play": "Play",
"common.pause": "Pause",
"common.set": "Set",
"common.previous": "Previous",
"common.nextItem": "Next",
"common.processing": "Processing...",
"error.providerOverloaded": "{model}: provider is temporarily overloaded. Please retry in a moment or switch models.",
"node.optionalTitle": "This input is optional - empty inputs will be skipped",
"node.markOptionalTitle": "Mark as optional - empty inputs will skip this branch",
"header.openWelcome": "Open welcome screen",
"header.untitled": "Untitled",
"header.saving": "Saving...",
"header.savedAt": "Saved {time}",
"header.notSaved": "Not saved",
"header.saveProject": "Save project",
"header.configureSaveLocation": "Configure save location",
"header.openProject": "Open project",
"header.openProjectFolder": "Open Project Folder",
"header.projectSettings": "Project settings",
"header.revertAIChanges": "Revert AI Changes",
"header.revertAIChangesTitle": "Restore workflow from before AI changes",
"header.revertConfirm": "Are you sure? This will restore your previous workflow.",
"header.shortcuts": "Keyboard shortcuts (?)",
"header.support": "Support",
"header.madeBy": "Made by Willie",
"header.commentsTitle": "{unviewed} unviewed comments ({total} total)",
"header.openFolderFailed": "Failed to open project folder: {error}",
"header.openFolderFailedRetry": "Failed to open project folder. Please try again.",
"header.saveFailedRetry": "Failed to save project. Please try again.",
"quickstart.description": "A node based workflow editor for generative AI pipelines. Connect nodes to build pipelines that transform and generate images, video, audio and 3D assets.",
"quickstart.docs": "Docs",
"quickstart.discord": "Discord",
"quickstart.waitlist": "NB Pro Waitlist",
"quickstart.newProject": "New project",
"quickstart.newProjectDesc": "Start a new workflow",
"quickstart.loadWorkflow": "Load workflow",
"quickstart.loadWorkflowDesc": "Open existing file",
"quickstart.templates": "Templates",
"quickstart.templatesDesc": "Pre-built workflows",
"quickstart.promptWorkflow": "Prompt a workflow",
"quickstart.promptWorkflowDesc": "Get Gemini to build it",
"quickstart.beta": "Beta",
"quickstart.templateExplorerTitle": "Template Explorer",
"quickstart.workflowTemplatesTitle": "Workflow Templates",
"quickstart.templatesIntro": "Pre-built workflows to help you get started quickly. Select a template to load it into the canvas.",
"quickstart.quickStart": "Quick Start",
"quickstart.searchTemplates": "Search templates",
"quickstart.searchTemplatesPlaceholder": "Search templates...",
"quickstart.category": "Category",
"quickstart.provider": "Provider",
"quickstart.filterAll": "All",
"quickstart.categorySimple": "Simple",
"quickstart.categoryAdvanced": "Advanced",
"quickstart.clearFilters": "Clear filters",
"quickstart.clearAllFilters": "Clear all filters",
"quickstart.noTemplatesMatch": "No templates match your filters",
"quickstart.adjustSearchFilters": "Try adjusting your search or filters",
"quickstart.useWorkflow": "Use workflow",
"quickstart.loading": "Loading...",
"quickstart.nodeCount": "{count} nodes",
"quickstart.dismiss": "Dismiss",
"quickstart.loadTemplateFailed": "Failed to load template",
"quickstart.template.productShot.name": "Product Shot",
"quickstart.template.productShot.description": "Place product in a new scene or environment",
"quickstart.template.modelProduct.name": "Model + Product",
"quickstart.template.modelProduct.description": "Combine model, product, and scene",
"quickstart.template.colorVariations.name": "Color Variations",
"quickstart.template.colorVariations.description": "Generate product color variants from references",
"quickstart.template.backgroundSwap.name": "Background Swap",
"quickstart.template.backgroundSwap.description": "Place subject in a new background",
"quickstart.template.styleTransfer.name": "Style Transfer",
"quickstart.template.styleTransfer.description": "Apply style from one image to another",
"quickstart.template.sceneComposite.name": "Scene Composite",
"quickstart.template.sceneComposite.description": "Combine elements from multiple scenes",
"ftux.welcomeTo": "Welcome to popiart-node",
"ftux.stepWelcome": "Welcome",
"ftux.stepApiKeys": "API Keys",
"ftux.stepModelDefaults": "Model Defaults",
"ftux.stepReady": "Ready",
"ftux.getStarted": "Get Started",
"ftux.skipSetup": "Skip setup?",
"ftux.skipSetupDesc": "You can configure API keys and model defaults later in settings.",
"ftux.welcomeTitle": "Let's get started.",
"ftux.welcomeDesc": "Connect AI models like building blocks to generate images, videos, and more.",
"ftux.apiKeysTitle": "API Keys",
"ftux.apiKeysDesc": "Add keys here to use AI providers (stored in browser), or save them to your .env file for better security and persistence.",
"ftux.getApiKey": "Get {provider} API key",
"ftux.getApiKeyTip": "Get API key",
"ftux.llmOnlyTip": "Used for LLM nodes only",
"ftux.enterKey": "Enter key...",
"ftux.modelsTitle": "Choose Your Models",
"ftux.modelsDesc": "Pick your default AI models for images and videos. You can change these later.",
"ftux.defaultImageModel": "Default Image Model",
"ftux.defaultVideoModel": "Default Video Model",
"ftux.noneSet": "None set",
"ftux.readyTitle": "You're ready!",
"ftux.readyDesc": "Want a quick tutorial?",
"ftux.startTutorial": "Start tutorial",
"ftux.tutorial.welcome": "Let's go over the basics.",
"ftux.tutorial.addImage": "Click the Image button to add an image node.",
"ftux.tutorial.explainNode": "This is a node. Each node has a specific function.\n\nThis node adds images.",
"ftux.tutorial.explainNodeInputs": "Inputs always go in on the left side of the node.",
"ftux.tutorial.explainNodeOutputs": "Outputs always come from the right side of the node.",
"ftux.tutorial.dragAndDrop": "Now drag from the output handle and drop into empty space.",
"ftux.tutorial.selectGenerateImage": "This menu will show all available connections for the node.\n\nSelect 'Generate Image' to add an AI image generation node.",
"ftux.tutorial.addPromptNode": "Click the Prompt button to add a prompt node.",
"ftux.tutorial.connectPromptToGenerate": "Drag from the Prompt's output handle to the Generate Image's input handle.",
"ftux.tutorial.populateContent": "Let me just add some stuff here 🎨",
"ftux.tutorial.explainGenerateNode": "This is the Generate Image node. It uses AI to create or modify images based on your prompt and reference image.",
"ftux.tutorial.explainRunButton": "Clicking this Run button will run your workflow. You can also press Cmd+Enter (Ctrl+Enter on Windows).",
"ftux.tutorial.explainRunOptions": "You can also click the dropdown to run from a specific node, or run only selected nodes.",
"ftux.tutorial.runWorkflow": "Now let's run your workflow! Click the Run button to generate your image.",
"ftux.tutorial.demonstrateDownstream": "Now let me show you the possibilities... 🎬✨",
"ftux.tutorial.demonstrateComplete": "Connect more nodes downstream to build generative pipelines, or just use it as an infinite creative canvas.",
"ftux.tutorial.saveProject": "Save your project to keep all your work and generations locally.",
"ftux.tutorial.resources": "Check out the resources below for help and inspiration:",
"ftux.tutorial.discord": "Join our Discord community",
"ftux.tutorial.complete": "You're all set! Happy creating.",
"ftux.tutorial.clickToContinue": "Click anywhere to continue",
"ftux.tutorial.skip": "Skip tutorial",
"toolbar.categoryInput": "Input",
"toolbar.categoryText": "Text",
"toolbar.categoryGenerate": "Generate",
"toolbar.categoryProcess": "Process",
"toolbar.categoryRoute": "Route",
"toolbar.categoryOutput": "Output",
"toolbar.image": "Image",
"toolbar.video": "Video",
"toolbar.prompt": "Prompt",
"toolbar.generate": "Generate",
"toolbar.output": "Output",
"toolbar.allNodes": "All nodes",
"toolbar.allModels": "All models",
"toolbar.browseModels": "Browse Models",
"toolbar.switchConnectors": "Switch to {style} connectors",
"toolbar.curved": "curved",
"toolbar.angular": "angular",
"toolbar.run": "Run",
"toolbar.stop": "Stop",
"toolbar.running": "Running...",
"toolbar.runningNode": "Running {node}...",
"toolbar.runningNodes": "Running {count} nodes...",
"toolbar.nodesCount": "{count} nodes",
"toolbar.runOptions": "Run options",
"toolbar.runEntire": "Run entire workflow",
"toolbar.runFromSelected": "Run from selected node",
"toolbar.runSelectedOnly": "Run selected node only",
"toolbar.runSelectedNodes": "Run selected nodes",
"toolbar.runSelectedNodesCount": "Run {count} selected nodes",
"toolbar.selectSingleNode": "Select a single node first",
"toolbar.selectOneOrMoreNodes": "Select one or more nodes first",
"node.imageInput": "Image Input",
"node.audioInput": "Audio Input",
"node.videoInput": "Video Input",
"node.glbViewer": "3D Viewer",
"node.prompt": "Prompt",
"node.promptConstructor": "Prompt Constructor",
"node.array": "Array",
"node.generateImage": "Generate Image",
"node.generateVideo": "Generate Video",
"node.generate3d": "Generate 3D",
"node.generateAudio": "Generate Audio",
"node.llmGenerate": "LLM Generate",
"node.annotation": "Annotate",
"annotation.tool.select": "Select",
"annotation.tool.rectangle": "Rect",
"annotation.tool.circle": "Circle",
"annotation.tool.arrow": "Arrow",
"annotation.tool.draw": "Draw",
"annotation.tool.text": "Text",
"annotation.undo": "Undo",
"annotation.redo": "Redo",
"annotation.clear": "Clear",
"annotation.cancel": "Cancel",
"annotation.done": "Done",
"annotation.color": "Color",
"annotation.size": "Size",
"annotation.fill": "Fill",
"node.splitGrid": "Split Grid",
"node.videoStitch": "Video Stitch",
"node.videoTrim": "Video Trim",
"node.easeCurve": "Ease Curve",
"node.frameGrab": "Frame Grab",
"node.imageCompare": "Image Compare",
"imageCompare.connectTwo": "Connect 2 images to compare",
"imageCompare.connectAnother": "Connect another image to compare",
"imageCompare.imageAConnected": "Image A connected",
"imageCompare.imageBConnected": "Image B connected",
"imageCompare.imageAAlt": "Image A",
"imageCompare.imageBAlt": "Image B",
"upload.imageUnsupported": "Unsupported format. Use PNG, JPG, or WebP.",
"upload.imageTooLarge": "Image too large. Maximum size is 10MB.",
"upload.videoUnsupported": "Unsupported format. Use MP4, WebM, or QuickTime video files.",
"upload.videoTooLarge": "Video file too large. Maximum size is 200MB.",
"upload.audioUnsupported": "Unsupported format. Use MP3, WAV, OGG, AAC, or other audio formats.",
"upload.audioTooLarge": "Audio file too large. Maximum size is 50MB.",
"imageInput.uploadedAlt": "Uploaded image",
"imageInput.download": "Download image",
"imageInput.remove": "Remove image",
"videoInput.upload": "Upload video file",
"videoInput.dropVideo": "Drop video or click",
"videoInput.download": "Download video",
"videoInput.remove": "Remove video",
"audioInput.upload": "Upload audio file",
"audioInput.dropAudio": "Drop audio or click",
"audioInput.download": "Download audio",
"audioInput.remove": "Remove audio",
"audioInput.clear": "Clear audio",
"audioInput.loadingWaveform": "Loading waveform...",
"generateAudio.fallbackUsed": "Fallback used",
"generateAudio.fallbackUsedTitle": "Primary failed: {error}\nUsed fallback: {model}",
"generateAudio.generating": "Generating audio...",
"annotation.noImage": "No image available. Connect an image or load one manually.",
"annotation.annotatedAlt": "Annotated image",
"annotation.downloadImage": "Download image",
"annotation.removeImage": "Remove image",
"annotation.editCount": "Edit ({count})",
"annotation.addAnnotations": "Add annotations",
"annotation.dropClickConnect": "Drop, click, or connect",
"array.split": "Split",
"array.delimiter": "Delimiter",
"array.newline": "Newline",
"array.regexAdvanced": "Regex (Advanced)",
"array.batch": "Batch",
"array.batchModeTitle": "Batch mode: all items sent to one downstream node",
"array.enableBatchMode": "Enable batch mode",
"array.autoRouteToPrompts": "Auto-route to Prompts",
"array.by": "By",
"array.advanced": "Advanced",
"array.trim": "Trim",
"array.removeEmpty": "Remove empty",
"array.parsedItems": "Parsed Items ({count})",
"array.noItemsParsed": "No items parsed",
"array.selectedForNextConnection": "Selected for next connection (click to unselect)",
"array.selectForNextConnection": "Click to select for next connection",
"array.batchFooter": "Batch: all items sent to downstream node",
"array.nextWireUsesItem": "Next wire uses item {index}",
"array.noSelection": "No selection: wires advance in order from item 1",
"videoCommon.encoderUnsupported": "Your browser doesn't support video encoding.",
"videoCommon.encoderHelp": "Doesn't seem right? Message Willie on Discord.",
"videoCommon.checkingEncoder": "Checking encoder...",
"videoCommon.processingPercent": "Processing... {progress}%",
"videoTrim.videoIn": "Video In",
"videoTrim.videoOut": "Video Out",
"videoTrim.connectVideo": "Connect a video to trim",
"videoTrim.source": "Source",
"videoTrim.trimmed": "Trimmed",
"videoTrim.clearTrimmedVideo": "Clear trimmed video",
"videoTrim.start": "Start",
"videoTrim.end": "End",
"videoTrim.duration": "Duration",
"videoTrim.trimStartTime": "Trim start time",
"videoTrim.trimEndTime": "Trim end time",
"videoTrim.setStartToCurrent": "Set start to current playback time",
"videoTrim.setEndToCurrent": "Set end to current playback time",
"videoTrim.trim": "Trim",
"videoStitch.videoInput": "Video {index}",
"videoStitch.audioInput": "Audio",
"videoStitch.output": "Output",
"videoStitch.connectVideos": "Connect videos to stitch",
"videoStitch.clipAlt": "Clip {id}",
"videoStitch.clearVideo": "Clear video",
"videoStitch.loop": "Loop",
"videoStitch.stitch": "Stitch",
"multiAngle.editorTitle": "Multi-Angle Editor",
"multiAngle.imageEditorTitle": "Image Multi-Angle Editor",
"multiAngle.imageTitle": "Image Multi-Angle",
"multiAngle.closeEditor": "Close multi-angle editor",
"multiAngle.generate": "Generate multi-angle",
"multiAngle.noImageToast": "No usable image found. Cannot generate multi-angle image.",
"multiAngle.sightControl": "Multi-angle sight control",
"multiAngle.noImage": "No image",
"multiAngle.horizontal": "Horizontal orbit",
"multiAngle.vertical": "Vertical pitch",
"multiAngle.zoom": "Shot scale",
"multiAngle.prompt": "Prompt",
"multiAngle.enableCustomPrompt": "Enable custom prompt",
"multiAngle.promptDialog": "Multi-angle prompt",
"multiAngle.promptInput": "Multi-angle prompt input",
"multiAngle.promptPlaceholder": "Enter prompt...",
"multiAngle.reset": "Reset parameters",
"multiAngle.resetAria": "Reset multi-angle parameters",
"multiAngle.adjustVerticalUp": "Adjust vertical pitch up",
"multiAngle.adjustVerticalDown": "Adjust vertical pitch down",
"multiAngle.adjustHorizontalLeft": "Adjust horizontal orbit left",
"multiAngle.adjustHorizontalRight": "Adjust horizontal orbit right",
"multiAngle.preset.custom": "Custom",
"multiAngle.preset.fisheye": "Fisheye",
"multiAngle.preset.tilt": "Tilt",
"multiAngle.preset.frontOverhead": "Front overhead",
"multiAngle.preset.frontLow": "Front low angle",
"multiAngle.preset.panoramicOverhead": "Panoramic overhead",
"multiAngle.preset.back": "Back view",
"multiAngle.zoom.wide": "Wide",
"multiAngle.zoom.medium": "Medium",
"multiAngle.zoom.close": "Close-up",
"workflow.splitGrid.noImage": "No image available to split. Generate or load an image first.",
"workflow.splitGrid.detectFailed": "Could not detect grid in image.",
"workflow.splitGrid.failed": "Failed to split image grid: {error}",
"workflow.generatedSuccess": "Workflow generated successfully",
"workflow.generatedFailed": "Failed to generate workflow",
"workflow.generatedFailedRetry": "Failed to generate workflow. Please try again.",
"workflow.appliedEdits": "Applied {count} edit(s)",
"chat.title": "Canvas Assistant",
"chat.beta": "Beta",
"chat.clear": "Clear chat",
"chat.close": "Close chat",
"chat.dismiss": "Dismiss",
"chat.emptyTitle": "Ask about this canvas or ask me to prepare edits.",
"chat.diagnoseSelected": "Diagnose selected",
"chat.makeVariants": "Make variants",
"chat.promptDiagnose": "Diagnose the selected nodes and suggest the smallest useful fix.",
"chat.promptVariants": "Prepare edits to create four visual variants from the selected image or generate node.",
"chat.proposalReady": "Proposal ready",
"chat.candidateReady": "Candidate workflow ready to apply.",
"chat.runReady": "Run action ready to apply.",
"chat.candidateWorkflow": "Candidate workflow",
"chat.applyWorkflow": "Apply workflow",
"chat.operationPreview": "Operation preview",
"chat.applyEdits": "Apply edits",
"chat.runPreview": "Run preview",
"chat.runNow": "Run now",
"chat.focusedNodes": "Focused on {count} selected node(s)",
"chat.runSelected": "Run selected",
"chat.runAffected": "Run affected ({count})",
"chat.placeholder": "Type a message...",
"chat.building": "Building...",
"chat.buildWorkflow": "Build Workflow",
"chat.open": "Assistant",
"chat.noSelection": "Select one or more nodes first.",
"workflow.invalidWorkflowFile": "Invalid workflow file format",
"workflow.parseWorkflowFileFailed": "Failed to parse workflow file",
"splitGridNode.sourceGridAlt": "Source grid",
"splitGridNode.connectImage": "Connect image",
"splitGridNode.gridSummary": "{rows}x{cols} grid ({count} images)",
"splitGridNode.generateSetsCreated": "{count} generate sets created",
"splitGridNode.notConfigured": "Not configured - click Settings",
"splitGridNode.configureFirst": "Configure node first",
"splitGridNode.connectImageFirst": "Connect an image first",
"splitGridNode.splitGrid": "Split grid",
"splitGridNode.split": "Split",
"node.router": "Router",
"node.switch": "Switch",
"node.conditionalSwitch": "Conditional Switch",
"node.output": "Output",
"node.outputGallery": "Output Gallery",
"output.downloadCurrent": "Download current {type}",
"output.downloadAll": "Download all outputs",
"node.settings": "Settings",
"node.runToGenerate": "Run to generate",
"node.selectModel": "Select model...",
"node.primary": "Primary",
"node.text": "Text",
"node.image": "Image",
"node.notUsedByModel": "Not used by this model",
"node.generationFailed": "Generation failed",
"node.videoGenerationFailed": "Video generation failed",
"node.loadingParameters": "Loading parameters...",
"node.noParameters": "No parameters available",
"node.default": "Default",
"node.model": "Model",
"node.size": "Size",
"node.quality": "Quality",
"node.voice": "Voice",
"node.sound": "Sound",
"node.duration": "Duration",
"node.seconds": "{count}s",
"node.aspectRatio": "Aspect Ratio",
"node.resolution": "Resolution",
"node.googleSearch": "Google Search",
"node.imageSearch": "Image Search",
"node.provider": "Provider",
"node.temperature": "Temperature: {value}",
"node.maxTokens": "Max Tokens: {value}",
"node.generic": "Node",
"splitGridSettings.title": "Split Grid Settings",
"splitGridSettings.gridLayout": "Grid Layout",
"splitGridSettings.gridSummary": "Grid will be split into {rows}x{cols} = {count} images",
"splitGridSettings.defaultPrompt": "Default Prompt",
"splitGridSettings.promptPlaceholder": "Enter prompt that will be applied to all generated images...",
"splitGridSettings.promptHelp": "Each prompt node can be edited individually after creation",
"splitGridSettings.generateNodeSettings": "Generate Node Settings",
"splitGridSettings.createGenerateSets": "Create {count} Generate Sets",
"imageInput.upload": "Upload image",
"imageInput.dropImage": "Drop image",
"dropOverlay.workflow": "Drop to load workflow",
"dropOverlay.node": "Drop to create node",
"dropOverlay.audio": "Drop audio to create node",
"dropOverlay.image": "Drop image to create node",
"dropOverlay.splittingImageGrid": "Splitting image grid...",
"connectionMenu.addNode": "Add {type} node",
"connectionMenu.type.image": "image",
"connectionMenu.type.text": "text",
"connectionMenu.type.audio": "audio",
"connectionMenu.type.video": "video",
"connectionMenu.type.3d": "3D",
"connectionMenu.type.easeCurve": "settings",
"connectionMenu.splitGridNode": "Split Grid Node",
"connectionMenu.splitGridNow": "Split Grid Now",
"connectionMenu.multiAngleImage": "Image Multi-Angle",
"connectionMenu.navigate": "navigate",
"connectionMenu.select": "select",
"prompt.placeholder": "Describe what to generate...",
"prompt.connectedPlaceholder": "Text from connected node (editable)...",
"prompt.optionalPlaceholder": "Optional prompt (leave empty to skip)...",
"prompt.addVariable": "Add variable",
"prompt.setVariableName": "Set Variable Name",
"prompt.variableHelp": "Use this prompt as a variable in PromptConstructor nodes",
"prompt.variableName": "Variable name",
"prompt.variablePlaceholder": "e.g. color, style, subject",
"prompt.preview": "Preview: {value}",
"composer.promptProvidedByUpstream": "Prompt is provided by an upstream text node.",
"composer.videoStitchClipCount": "{count} video clips",
"composer.videoStitchAudio": "Audio connected",
"composer.videoStitchNoAudio": "No audio",
"composer.videoStitchInputs": "Video inputs",
"composer.videoStitchInputHint": "Reorder clips on the node",
"composer.videoStitchNeedTwo": "Connect at least 2 video clips to stitch.",
"composer.videoStitchClip": "Clip {index}",
"composer.videoStitchLoop": "Loop",
"composer.videoStitchOutputReady": "Output ready",
"composer.videoStitchNoOutput": "No output yet",
"composer.videoStitchReady": "Ready to stitch current node",
"composer.videoStitchRun": "Stitch current video node",
"composer.easeCurveVideoConnected": "Video connected",
"composer.easeCurveNoVideo": "Connect a video input to apply ease curve.",
"composer.easeCurveInherited": "Inherited settings",
"composer.easeCurveLocal": "Local settings",
"composer.easeCurveSettings": "Curve settings",
"composer.easeCurvePreset": "Preset",
"composer.easeCurveCustom": "Custom bezier",
"composer.easeCurveHandles": "Bezier handles",
"composer.easeCurveInput": "Input",
"composer.easeCurveDuration": "Output duration",
"composer.easeCurveOutputReady": "Output ready",
"composer.easeCurveNoOutput": "No output yet",
"composer.easeCurveReady": "Ready to apply current curve",
"composer.easeCurveRun": "Apply current ease curve node",
"composer.selectModel": "Select model",
"composer.chooseModelTitle": "Choose generation model",
"composer.chooseImageModel": "Choose image model",
"composer.chooseVideoModel": "Choose video model",
"composer.chooseAudioModel": "Choose audio model",
"composer.regenerateImageNode": "Regenerate current image node",
"composer.regenerateVideoNode": "Regenerate current video node",
"composer.regenerateAudioNode": "Regenerate current audio node",
"composer.imageNode": "Image node",
"composer.videoNode": "Video node",
"composer.audioNode": "Audio node",
"composer.imageCount": "Image count",
"composer.imageCountOption": "{count} image(s)",
"composer.newGeneration": "New generation",
"composer.selectedNodes": "{count} nodes selected",
"composer.currentNode": "Current node",
"composer.createAndGenerate": "Create and generate",
"composer.dragFromPort": "Drag from a node port to create the next step",
"composer.multiSelectNoSingleGenerate": "Multi-select does not support single-node generation yet",
"composer.retryCurrentNode": "Retry current node",
"composer.generate": "Generate",
"composer.describeContent": "Describe what you want to generate",
"composer.mainPlaceholder": "Describe what you want to generate, press / for commands, @ to reference assets",
"composer.uploadReferenceImage": "Upload reference image",
"composer.expand": "Expand composer",
"composer.collapse": "Collapse composer",
"composer.console": "Console",
"composer.style": "Style",
"composer.mark": "Mark",
"composer.focus": "Focus",
"composer.addReferenceImage": "Add reference image",
"composer.referenceFromUpstream": "Reference images come from upstream connections",
"composer.reference": "Reference",
"composer.referenceImage": "Reference image {index}",
"composer.removeReferenceImage": "Remove reference image {index}",
"composer.commands": "Commands",
"composer.referenceMaterials": "Reference assets",
"composer.commandCharacter": "Character image",
"composer.commandCharacterValue": "Generate a character image with consistent styling and clear composition.",
"composer.commandTurnaround": "Turnaround sheet",
"composer.commandTurnaroundValue": "Generate a character turnaround sheet with front, side, and back views.",
"composer.commandVideoShot": "Video shot",
"composer.commandVideoShotValue": "Turn the current image into a short video shot with natural motion.",
"composer.currentReference": "Current reference asset",
"composer.canvasAssets": "Canvas assets",
"composer.multiSelectUnsupported": "{count} nodes selected. Batch editing is not supported yet.",
"composer.unsupportedNodeHint": "Create the next step by dragging from a node port. The composer only edits the selected generation node.",
"composer.videoSchemaHint": "Video parameters follow the selected model schema",
"composer.translate": "Translate",
"composer.settings": "Settings",
"composer.selectModelTitle": "Select model: {model}",
"shortcuts.title": "Keyboard Shortcuts",
"shortcuts.general": "General",
"shortcuts.addNodes": "Add Nodes",
"shortcuts.layout": "Layout (select 2+ nodes first)",
"shortcuts.canvas": "Canvas",
"shortcuts.runWorkflow": "Run workflow",
"shortcuts.copyNodes": "Copy selected nodes",
"shortcuts.paste": "Paste nodes / image / text",
"shortcuts.undo": "Undo",
"shortcuts.redo": "Redo",
"shortcuts.showShortcuts": "Show keyboard shortcuts",
"shortcuts.addPrompt": "Add Prompt node",
"shortcuts.addImage": "Add Image Input node",
"shortcuts.addGenerateImage": "Add Generate Image node",
"shortcuts.addGenerateVideo": "Add Generate Video node",
"shortcuts.addLLM": "Add LLM Text node",
"shortcuts.addAnnotation": "Add Annotation node",
"shortcuts.addAudio": "Add Audio node",
"shortcuts.addVideoInput": "Add Video Input node",
"shortcuts.addArray": "Add Array node",
"shortcuts.stackVertical": "Stack selected vertically",
"shortcuts.stackHorizontal": "Stack selected horizontally",
"shortcuts.arrangeGrid": "Arrange selected as grid",
"shortcuts.zoom": "Zoom in / out",
"shortcuts.pan": "Pan (macOS)",
"shortcuts.delete": "Delete selected nodes",
"project.newProject": "New Project",
"project.settings": "Project Settings",
"project.tabProject": "Project",
"project.tabProviders": "Providers",
"project.tabNodeDefaults": "Node Defaults",
"project.tabCanvas": "Canvas",
"project.name": "Project Name",
"project.directory": "Project Directory",
"project.localFolderPlaceholder": "Choose a local folder on this device",
"project.directoryHelp": "Workflow files and images will be saved here. Subfolders for inputs and generations will be auto-created.",
"project.embedImages": "Embed images as base64",
"project.embedImagesDesc": "Embeds all images in workflow, larger workflow files. Can hit memory limits on very large workflows.",
"project.inlineSettings": "Show model settings on nodes",
"project.inlineSettingsDesc": "Show model parameters inside generation nodes instead of the side panel",
"project.envHelp": "Add API keys via .env.local for better security. Keys added here override .env and are stored in your browser.",
"project.newapiwgDesc": "Popi unified model gateway",
"project.baseUrl": "Base URL",
"project.systemImageDefault": "System default (Popi Models)",
"project.noneSetFirstUse": "None set (select on first use)",
"project.defaultLLM": "Default LLM Settings",
"project.systemLLMDefault": "Using system defaults (Popi Models Doubao Seed 2.0 Lite)",
"project.provider": "Provider",
"project.model": "Model",
"project.temp": "Temp: {value}",
"project.tokens": "Tokens: {value}",
"project.executionSettings": "Execution Settings",
"project.maxParallel": "Max Parallel Calls: {count}",
"project.executionHelp": "Maximum number of nodes to execute in parallel during workflow execution. Higher values may improve speed but increase API rate limit risk.",
"project.defaultsHelp": "These defaults are applied when creating nodes via keyboard shortcuts (Shift+G, Shift+L, etc).",
"project.canvasHelp": "Configure how you navigate and interact with the canvas.",
"project.canvasAssistant": "Canvas Assistant",
"project.canvasAssistantShort": "Assistant",
"project.panMode": "Pan Mode",
"project.panSpace": "Hold Space and drag to pan",
"project.panMiddle": "Click and drag with middle mouse button",
"project.panAlways": "Pan without holding any keys",
"project.panSpaceLabel": "Space + Drag",
"project.panMiddleLabel": "Middle Mouse",
"project.panAlwaysLabel": "Always On",
"project.zoomMode": "Zoom Mode",
"project.zoomAlt": "Hold Alt and scroll to zoom",
"project.zoomCtrl": "Hold Ctrl/Cmd and scroll to zoom",
"project.zoomScroll": "Scroll to zoom without modifier keys",
"project.zoomAltLabel": "Alt + Scroll",
"project.zoomCtrlLabel": "Ctrl + Scroll",
"project.zoomScrollLabel": "Scroll",
"project.selectionMode": "Selection Mode",
"project.selectClick": "Click to select nodes",
"project.selectAlt": "Hold Alt and drag to select",
"project.selectShift": "Hold Shift and drag to select",
"project.selectClickLabel": "Click",
"project.selectAltLabel": "Alt + Drag",
"project.selectShiftLabel": "Shift + Drag",
"project.validating": "Validating...",
"project.errorOpenDir": "Failed to open directory picker",
"project.errorOpenDirWithReason": "Failed to open directory picker: {error}",
"project.errorNameRequired": "Project name is required",
"project.errorDirectoryRequired": "Project directory is required",
"project.errorChooseLocalFolder": "Choose a local folder from this browser so the project is saved on this device.",
"project.errorAbsolutePath": "Project directory must be an absolute path (starting with /, a drive letter, or a UNC path)",
"project.errorNotDirectory": "Project path is not a directory",
"project.errorValidateDir": "Failed to validate directory: {error}",
"modelSearch.search": "Search models...",
"modelSearch.allProviders": "All Providers",
"modelSearch.all": "All",
"modelSearch.allTypes": "All Types",
"modelSearch.image": "Image",
"modelSearch.video": "Video",
"modelSearch.audio": "Audio",
"modelSearch.refresh": "Refresh models & schemas",
"modelSearch.loading": "Loading models...",
"modelSearch.tryAgain": "Try Again",
"modelSearch.removeFallback": "Remove fallback",
"modelSearch.clearSelection": "Clear current selection",
"modelSearch.noModels": "No models found",
"modelSearch.adjustFilters": "Try adjusting your search or filters",
"modelSearch.recent": "Recently Used",
"promptWorkflow.title": "Prompt a Workflow",
"promptWorkflow.describe": "Describe your workflow",
"promptWorkflow.placeholder": "e.g., Create product photography with consistent lighting and style from reference images...",
"promptWorkflow.help": "Describe what you want your workflow to accomplish. Be specific about inputs, outputs, and any transformations.",
"promptWorkflow.note": "Note: This feature currently only works with Gemini models.",
"promptWorkflow.generating": "Generating...",
"promptWorkflow.generate": "Generate Workflow",
"promptWorkflow.dismiss": "Dismiss",
"promptWorkflow.validation": "Please describe your workflow (at least 3 characters)",
"promptWorkflow.failed": "Failed to generate workflow",
"workflowBrowser.noWorkflows": "No workflows found",
"workflowBrowser.noWorkflowsDesc": "This folder doesn't contain any workflow projects",
"workflowBrowser.title": "Your Workflows",
"workflowBrowser.chooseFolderDesc": "Choose the folder that contains your workflow projects. You can change this later.",
"workflowBrowser.chooseFolder": "Choose folder",
"workflowBrowser.projectCount": "{count} projects",
"workflowBrowser.openFromDirectory": "Open from directory",
"workflowBrowser.changeFolder": "Change folder",
"workflowBrowser.justNow": "just now",
"workflowBrowser.minutesAgo": "{count}m ago",
"workflowBrowser.hoursAgo": "{count}h ago",
"workflowBrowser.daysAgo": "{count}d ago",
"workflowBrowser.monthsAgo": "{count}mo ago",
"workflowBrowser.errorNoWorkflows": "No workflows found in this folder",
"workflowBrowser.errorList": "Failed to list workflows",
"workflowBrowser.errorFetch": "Failed to fetch workflows",
"multiSelect.stackHorizontal": "Stack horizontally (H)",
"multiSelect.stackVertical": "Stack vertically (V)",
"multiSelect.arrangeGrid": "Arrange as grid (G)",
"multiSelect.removeGroup": "Remove from group",
"multiSelect.createGroup": "Create group",
"multiSelect.downloadZip": "Download images as ZIP",
"cost.viewDetails": "View cost details",
};
const zhCN: Dictionary = {
...en,
"language.label": "语言",
"common.back": "返回",
"common.next": "下一步",
"common.cancel": "取消",
"common.close": "关闭",
"common.save": "保存",
"common.create": "创建",
"common.browse": "浏览",
"common.change": "更改",
"common.clear": "清除",
"common.select": "选择",
"common.selectModel": "选择模型",
"common.skip": "跳过",
"common.show": "显示",
"common.hide": "隐藏",
"common.override": "覆盖",
"common.configuredViaEnv": "已通过 .env 配置",
"common.recommended": "推荐",
"common.optional": "可选",
"common.required": "必填",
"common.download": "下载",
"common.remove": "移除",
"common.disconnect": "断开连接",
"common.play": "播放",
"common.pause": "暂停",
"common.set": "设置",
"common.previous": "上一个",
"common.nextItem": "下一个",
"common.processing": "处理中...",
"error.providerOverloaded": "{model}:服务商暂时过载。请稍后重试,或切换到其他模型。",
"node.optionalTitle": "此输入为可选,空输入会被跳过",
"node.markOptionalTitle": "标记为可选,空输入会跳过这个分支",
"header.openWelcome": "打开欢迎页",
"header.untitled": "未命名",
"header.saving": "保存中...",
"header.savedAt": "已保存 {time}",
"header.notSaved": "未保存",
"header.saveProject": "保存项目",
"header.configureSaveLocation": "配置保存位置",
"header.openProject": "打开项目",
"header.openProjectFolder": "打开项目文件夹",
"header.projectSettings": "项目设置",
"header.revertAIChanges": "还原 AI 改动",
"header.revertAIChangesTitle": "恢复到 AI 改动前的工作流",
"header.revertConfirm": "确定吗?这会恢复到之前的工作流。",
"header.shortcuts": "快捷键 (?)",
"header.support": "支持",
"header.commentsTitle": "{unviewed} 条未读评论(共 {total} 条)",
"header.openFolderFailed": "打开项目文件夹失败:{error}",
"header.openFolderFailedRetry": "打开项目文件夹失败,请重试。",
"header.saveFailedRetry": "保存项目失败,请重试。",
"quickstart.description": "一个面向生成式 AI 流水线的节点式工作流编辑器。连接节点即可构建生成与转换图片、视频、音频和 3D 资产的流程。",
"quickstart.docs": "文档",
"quickstart.waitlist": "NB Pro 候补名单",
"quickstart.newProject": "新建项目",
"quickstart.newProjectDesc": "开始新的工作流",
"quickstart.loadWorkflow": "加载工作流",
"quickstart.loadWorkflowDesc": "打开已有文件",
"quickstart.templates": "模板",
"quickstart.templatesDesc": "预置工作流",
"quickstart.promptWorkflow": "用提示生成工作流",
"quickstart.promptWorkflowDesc": "让 Gemini 帮你构建",
"quickstart.beta": "测试版",
"quickstart.templateExplorerTitle": "模板浏览器",
"quickstart.workflowTemplatesTitle": "工作流模板",
"quickstart.templatesIntro": "使用预置工作流快速开始。选择一个模板即可加载到画布。",
"quickstart.quickStart": "快速开始",
"quickstart.searchTemplates": "搜索模板",
"quickstart.searchTemplatesPlaceholder": "搜索模板...",
"quickstart.category": "分类",
"quickstart.provider": "服务商",
"quickstart.filterAll": "全部",
"quickstart.categorySimple": "简单",
"quickstart.categoryAdvanced": "高级",
"quickstart.clearFilters": "清除筛选",
"quickstart.clearAllFilters": "清除全部筛选",
"quickstart.noTemplatesMatch": "没有匹配的模板",
"quickstart.adjustSearchFilters": "尝试调整搜索或筛选条件",
"quickstart.useWorkflow": "使用工作流",
"quickstart.loading": "加载中...",
"quickstart.nodeCount": "{count} 个节点",
"quickstart.dismiss": "关闭",
"quickstart.loadTemplateFailed": "加载模板失败",
"quickstart.template.productShot.name": "产品图",
"quickstart.template.productShot.description": "将产品放入新的场景或环境",
"quickstart.template.modelProduct.name": "模特 + 产品",
"quickstart.template.modelProduct.description": "组合模特、产品和场景",
"quickstart.template.colorVariations.name": "颜色变体",
"quickstart.template.colorVariations.description": "基于参考图生成产品配色变体",
"quickstart.template.backgroundSwap.name": "替换背景",
"quickstart.template.backgroundSwap.description": "将主体放入新的背景",
"quickstart.template.styleTransfer.name": "风格迁移",
"quickstart.template.styleTransfer.description": "将一张图的风格应用到另一张图",
"quickstart.template.sceneComposite.name": "场景合成",
"quickstart.template.sceneComposite.description": "组合多个场景中的元素",
"ftux.welcomeTo": "欢迎使用 popiart-node",
"ftux.stepWelcome": "欢迎",
"ftux.stepApiKeys": "API 密钥",
"ftux.stepModelDefaults": "模型默认值",
"ftux.stepReady": "就绪",
"ftux.getStarted": "开始使用",
"ftux.skipSetup": "跳过设置?",
"ftux.skipSetupDesc": "稍后可在设置中配置 API 密钥和模型默认值。",
"ftux.welcomeTitle": "开始吧。",
"ftux.welcomeDesc": "像搭积木一样连接 AI 模型,生成图片、视频等内容。",
"ftux.apiKeysTitle": "API 密钥",
"ftux.apiKeysDesc": "在这里添加密钥以使用 AI 服务商(存储在浏览器),也可以写入 .env 文件以获得更好的安全性和持久性。",
"ftux.getApiKey": "获取 {provider} API 密钥",
"ftux.getApiKeyTip": "获取 API 密钥",
"ftux.llmOnlyTip": "仅用于 LLM 节点",
"ftux.enterKey": "输入密钥...",
"ftux.modelsTitle": "选择你的模型",
"ftux.modelsDesc": "选择图片和视频的默认 AI 模型,之后可以随时更改。",
"ftux.defaultImageModel": "默认图片模型",
"ftux.defaultVideoModel": "默认视频模型",
"ftux.noneSet": "未设置",
"ftux.readyTitle": "准备好了!",
"ftux.readyDesc": "要快速看一遍教程吗?",
"ftux.startTutorial": "开始教程",
"ftux.tutorial.welcome": "我们先快速了解基础操作。",
"ftux.tutorial.addImage": "点击“图片”按钮,添加一个图片节点。",
"ftux.tutorial.explainNode": "这是一个节点。每个节点都有特定功能。\n\n这个节点用于添加图片。",
"ftux.tutorial.explainNodeInputs": "输入端口始终在节点左侧。",
"ftux.tutorial.explainNodeOutputs": "输出端口始终在节点右侧。",
"ftux.tutorial.dragAndDrop": "现在从输出端口拖拽,并释放到画布空白处。",
"ftux.tutorial.selectGenerateImage": "这个菜单会显示该节点可连接的所有节点。\n\n选择“生成图片”,添加一个 AI 图片生成节点。",
"ftux.tutorial.addPromptNode": "点击“提示词”按钮,添加一个提示词节点。",
"ftux.tutorial.connectPromptToGenerate": "从提示词节点的输出端口拖到生成图片节点的输入端口。",
"ftux.tutorial.populateContent": "我来帮你填充一些示例内容 🎨",
"ftux.tutorial.explainGenerateNode": "这是生成图片节点。它会根据提示词和参考图,用 AI 创建或修改图片。",
"ftux.tutorial.explainRunButton": "点击这个“运行”按钮会执行工作流。你也可以按 Cmd+Enter(Windows 上为 Ctrl+Enter)。",
"ftux.tutorial.explainRunOptions": "你也可以点击下拉菜单,从指定节点开始运行,或只运行选中的节点。",
"ftux.tutorial.runWorkflow": "现在运行你的工作流!点击“运行”按钮生成图片。",
"ftux.tutorial.demonstrateDownstream": "现在看看还能继续做什么... 🎬✨",
"ftux.tutorial.demonstrateComplete": "继续向下游连接更多节点来构建生成式流水线,也可以把它当作无限创意画布使用。",
"ftux.tutorial.saveProject": "保存项目后,你的工作和生成结果都会保存在本地。",
"ftux.tutorial.resources": "下面这些资源可以提供帮助和灵感:",
"ftux.tutorial.discord": "加入我们的 Discord 社区",
"ftux.tutorial.complete": "全部设置好了!开始创作吧。",
"ftux.tutorial.clickToContinue": "点击任意位置继续",
"ftux.tutorial.skip": "跳过教程",
"toolbar.categoryInput": "输入",
"toolbar.categoryText": "文本",
"toolbar.categoryGenerate": "生成",
"toolbar.categoryProcess": "处理",
"toolbar.categoryRoute": "路由",
"toolbar.categoryOutput": "输出",
"toolbar.image": "图片",
"toolbar.video": "视频",
"toolbar.prompt": "提示词",
"toolbar.generate": "生成",
"toolbar.output": "输出",
"toolbar.allNodes": "所有节点",
"toolbar.allModels": "所有模型",
"toolbar.browseModels": "浏览模型",
"toolbar.switchConnectors": "切换为{style}连线",
"toolbar.curved": "曲线",
"toolbar.angular": "折线",
"toolbar.run": "运行",
"toolbar.stop": "停止",
"toolbar.running": "运行中...",
"toolbar.runningNode": "正在运行 {node}...",
"toolbar.runningNodes": "正在运行 {count} 个节点...",
"toolbar.nodesCount": "{count} 个节点",
"toolbar.runOptions": "运行选项",
"toolbar.runEntire": "运行整个工作流",
"toolbar.runFromSelected": "从选中节点开始运行",
"toolbar.runSelectedOnly": "仅运行选中节点",
"toolbar.runSelectedNodes": "运行选中节点",
"toolbar.runSelectedNodesCount": "运行 {count} 个选中节点",
"toolbar.selectSingleNode": "请先选择一个节点",
"toolbar.selectOneOrMoreNodes": "请先选择一个或多个节点",
"node.imageInput": "图片输入",
"node.audioInput": "音频输入",
"node.videoInput": "视频输入",
"node.glbViewer": "3D 查看器",
"node.prompt": "提示词",
"node.promptConstructor": "提示词构造器",
"node.array": "数组",
"node.generateImage": "生成图片",
"node.generateVideo": "生成视频",
"node.generate3d": "生成 3D",
"node.generateAudio": "生成音频",
"node.llmGenerate": "LLM 生成",
"node.annotation": "标注",
"annotation.tool.select": "选择",
"annotation.tool.rectangle": "矩形",
"annotation.tool.circle": "圆形",
"annotation.tool.arrow": "箭头",
"annotation.tool.draw": "画笔",
"annotation.tool.text": "文字",
"annotation.undo": "撤销",
"annotation.redo": "重做",
"annotation.clear": "清空",
"annotation.cancel": "取消",
"annotation.done": "完成",
"annotation.color": "颜色",
"annotation.size": "大小",
"annotation.fill": "填充",
"node.splitGrid": "拆分网格",
"node.videoStitch": "视频拼接",
"node.videoTrim": "视频裁剪",
"node.easeCurve": "缓动曲线",
"node.frameGrab": "抓取帧",
"node.imageCompare": "图片对比",
"imageCompare.connectTwo": "连接 2 张图片进行对比",
"imageCompare.connectAnother": "再连接一张图片进行对比",
"imageCompare.imageAConnected": "图片 A 已连接",
"imageCompare.imageBConnected": "图片 B 已连接",
"imageCompare.imageAAlt": "图片 A",
"imageCompare.imageBAlt": "图片 B",
"upload.imageUnsupported": "格式不支持。请使用 PNG、JPG 或 WebP。",
"upload.imageTooLarge": "图片过大。最大支持 10MB。",
"upload.videoUnsupported": "格式不支持。请使用 MP4、WebM 或 QuickTime 视频文件。",
"upload.videoTooLarge": "视频文件过大。最大支持 200MB。",
"upload.audioUnsupported": "格式不支持。请使用 MP3、WAV、OGG、AAC 或其他音频格式。",
"upload.audioTooLarge": "音频文件过大。最大支持 50MB。",
"imageInput.uploadedAlt": "已上传图片",
"imageInput.download": "下载图片",
"imageInput.remove": "移除图片",
"videoInput.upload": "上传视频文件",
"videoInput.dropVideo": "拖入视频或点击",
"videoInput.download": "下载视频",
"videoInput.remove": "移除视频",
"audioInput.upload": "上传音频文件",
"audioInput.dropAudio": "拖入音频或点击",
"audioInput.download": "下载音频",
"audioInput.remove": "移除音频",
"audioInput.clear": "清除音频",
"audioInput.loadingWaveform": "正在加载波形...",
"generateAudio.fallbackUsed": "已使用备用模型",
"generateAudio.fallbackUsedTitle": "主模型失败:{error}\n已使用备用模型:{model}",
"generateAudio.generating": "正在生成音频...",
"annotation.noImage": "没有可用图片。请连接图片或手动加载一张。",
"annotation.annotatedAlt": "已标注图片",
"annotation.downloadImage": "下载图片",
"annotation.removeImage": "移除图片",
"annotation.editCount": "编辑({count})",
"annotation.addAnnotations": "添加标注",
"annotation.dropClickConnect": "拖入、点击或连接",
"array.split": "拆分",
"array.delimiter": "分隔符",
"array.newline": "换行",
"array.regexAdvanced": "正则(高级)",
"array.batch": "批量",
"array.batchModeTitle": "批量模式:所有条目发送到同一个下游节点",
"array.enableBatchMode": "启用批量模式",
"array.autoRouteToPrompts": "自动路由到提示词",
"array.by": "按",
"array.advanced": "高级",
"array.trim": "去除空白",
"array.removeEmpty": "移除空项",
"array.parsedItems": "解析条目({count})",
"array.noItemsParsed": "尚未解析出条目",
"array.selectedForNextConnection": "已选为下一条连接输出(点击取消)",
"array.selectForNextConnection": "点击选择为下一条连接输出",
"array.batchFooter": "批量:所有条目发送到下游节点",
"array.nextWireUsesItem": "下一条连线使用第 {index} 条",
"array.noSelection": "未选择:连线会从第 1 条开始依次使用",
"videoCommon.encoderUnsupported": "当前浏览器不支持视频编码。",
"videoCommon.encoderHelp": "看起来不对?请在 Discord 联系 Willie。",
"videoCommon.checkingEncoder": "正在检查编码器...",
"videoCommon.processingPercent": "处理中... {progress}%",
"videoTrim.videoIn": "视频输入",
"videoTrim.videoOut": "视频输出",
"videoTrim.connectVideo": "连接一个视频进行裁剪",
"videoTrim.source": "源视频",
"videoTrim.trimmed": "已裁剪",
"videoTrim.clearTrimmedVideo": "清除裁剪后视频",
"videoTrim.start": "开始",
"videoTrim.end": "结束",
"videoTrim.duration": "时长",
"videoTrim.trimStartTime": "裁剪开始时间",
"videoTrim.trimEndTime": "裁剪结束时间",
"videoTrim.setStartToCurrent": "将开始时间设为当前播放时间",
"videoTrim.setEndToCurrent": "将结束时间设为当前播放时间",
"videoTrim.trim": "裁剪",
"videoStitch.videoInput": "视频 {index}",
"videoStitch.audioInput": "音频",
"videoStitch.output": "输出",
"videoStitch.connectVideos": "连接视频进行拼接",
"videoStitch.clipAlt": "片段 {id}",
"videoStitch.clearVideo": "清除视频",
"videoStitch.loop": "循环",
"videoStitch.stitch": "拼接",
"multiAngle.editorTitle": "多角度编辑器",
"multiAngle.imageEditorTitle": "图片多角度编辑器",
"multiAngle.imageTitle": "图片多角度",
"multiAngle.closeEditor": "关闭多角度编辑器",
"multiAngle.generate": "生成多角度",
"multiAngle.noImageToast": "未找到可用图片,无法生成多角度图片",
"multiAngle.sightControl": "多角度视线控制",
"multiAngle.noImage": "无图片",
"multiAngle.horizontal": "水平环绕",
"multiAngle.vertical": "垂直俯仰",
"multiAngle.zoom": "景别缩放",
"multiAngle.prompt": "提示词",
"multiAngle.enableCustomPrompt": "开启自定义提示词",
"multiAngle.promptDialog": "多角度提示词",
"multiAngle.promptInput": "多角度提示词输入",
"multiAngle.promptPlaceholder": "输入提示词...",
"multiAngle.reset": "重置参数",
"multiAngle.resetAria": "重置多角度参数",
"multiAngle.adjustVerticalUp": "向上调整垂直俯仰",
"multiAngle.adjustVerticalDown": "向下调整垂直俯仰",
"multiAngle.adjustHorizontalLeft": "向左调整水平环绕",
"multiAngle.adjustHorizontalRight": "向右调整水平环绕",
"multiAngle.preset.custom": "自定义",
"multiAngle.preset.fisheye": "鱼眼视角",
"multiAngle.preset.tilt": "倾斜视角",
"multiAngle.preset.frontOverhead": "正面俯拍",
"multiAngle.preset.frontLow": "正面仰拍",
"multiAngle.preset.panoramicOverhead": "全景俯拍",
"multiAngle.preset.back": "背面视角",
"multiAngle.zoom.wide": "全景",
"multiAngle.zoom.medium": "中景",
"multiAngle.zoom.close": "特写",
"workflow.splitGrid.noImage": "没有可拆分的图片。请先生成或加载一张图片。",
"workflow.splitGrid.detectFailed": "无法识别图片网格。",
"workflow.splitGrid.failed": "拆分图片网格失败:{error}",
"workflow.generatedSuccess": "工作流生成成功",
"workflow.generatedFailed": "生成工作流失败",
"workflow.generatedFailedRetry": "生成工作流失败,请重试。",
"workflow.appliedEdits": "已应用 {count} 个编辑",
"chat.title": "画布助手",
"chat.beta": "测试版",
"chat.clear": "清空对话",
"chat.close": "关闭对话",
"chat.dismiss": "关闭",
"chat.emptyTitle": "可以询问当前画布,也可以让我准备修改。",
"chat.diagnoseSelected": "诊断选中节点",
"chat.makeVariants": "生成变体",
"chat.promptDiagnose": "诊断选中的节点,并给出最小可用修复建议。",
"chat.promptVariants": "准备一组编辑:基于选中的图片或生成节点创建四个视觉变体。",
"chat.proposalReady": "修改方案已准备",
"chat.candidateReady": "候选工作流已准备好应用。",
"chat.runReady": "运行操作已准备好应用。",
"chat.candidateWorkflow": "候选工作流",
"chat.applyWorkflow": "应用工作流",
"chat.operationPreview": "操作预览",
"chat.applyEdits": "应用编辑",
"chat.runPreview": "运行预览",
"chat.runNow": "立即运行",
"chat.focusedNodes": "聚焦 {count} 个选中节点",
"chat.runSelected": "运行选中",
"chat.runAffected": "运行影响范围({count})",
"chat.placeholder": "输入消息...",
"chat.building": "正在构建...",
"chat.buildWorkflow": "构建工作流",
"chat.open": "助手",
"chat.noSelection": "请先选择一个或多个节点。",
"workflow.invalidWorkflowFile": "工作流文件格式无效",
"workflow.parseWorkflowFileFailed": "解析工作流文件失败",
"splitGridNode.sourceGridAlt": "源网格",
"splitGridNode.connectImage": "连接图片",
"splitGridNode.gridSummary": "{rows}x{cols} 网格({count} 张图片)",
"splitGridNode.generateSetsCreated": "已创建 {count} 组生成节点",
"splitGridNode.notConfigured": "未配置 - 点击设置",
"splitGridNode.configureFirst": "请先配置节点",
"splitGridNode.connectImageFirst": "请先连接图片",
"splitGridNode.splitGrid": "拆分网格",
"splitGridNode.split": "拆分",
"node.router": "路由器",
"node.switch": "开关",
"node.conditionalSwitch": "条件开关",
"node.output": "输出",
"node.outputGallery": "输出画廊",
"output.downloadCurrent": "下载当前{type}",
"output.downloadAll": "下载全部输出",
"node.settings": "设置",
"node.runToGenerate": "运行以生成",
"node.selectModel": "选择模型...",
"node.primary": "主模型",
"node.text": "文本",
"node.image": "图片",
"node.notUsedByModel": "此模型不使用",
"node.generationFailed": "生成失败",
"node.videoGenerationFailed": "视频生成失败",
"node.loadingParameters": "正在加载参数...",
"node.noParameters": "无可用参数",
"node.default": "默认",
"node.model": "模型",
"node.size": "尺寸",
"node.quality": "质量",
"node.voice": "声音",
"node.sound": "声音",
"node.duration": "时长",
"node.seconds": "{count}秒",
"node.aspectRatio": "宽高比",
"node.resolution": "分辨率",
"node.googleSearch": "Google 搜索",
"node.imageSearch": "图片搜索",
"node.provider": "服务商",
"node.temperature": "温度:{value}",
"node.maxTokens": "最大 Token:{value}",
"node.generic": "节点",
"splitGridSettings.title": "拆分网格设置",
"splitGridSettings.gridLayout": "网格布局",
"splitGridSettings.gridSummary": "网格将拆分为 {rows}x{cols} = {count} 张图片",
"splitGridSettings.defaultPrompt": "默认提示词",
"splitGridSettings.promptPlaceholder": "输入将应用到所有生成图片的提示词...",
"splitGridSettings.promptHelp": "创建后,每个提示词节点都可以单独编辑",
"splitGridSettings.generateNodeSettings": "生成节点设置",
"splitGridSettings.createGenerateSets": "创建 {count} 组生成节点",
"imageInput.upload": "上传图片",
"imageInput.dropImage": "拖入图片",
"dropOverlay.workflow": "拖入以加载工作流",
"dropOverlay.node": "拖入以创建节点",
"dropOverlay.audio": "拖入音频以创建节点",
"dropOverlay.image": "拖入图片以创建节点",
"dropOverlay.splittingImageGrid": "正在拆分图片网格...",
"connectionMenu.addNode": "添加 {type} 节点",
"connectionMenu.type.image": "图片",
"connectionMenu.type.text": "文本",
"connectionMenu.type.audio": "音频",
"connectionMenu.type.video": "视频",
"connectionMenu.type.3d": "3D",
"connectionMenu.type.easeCurve": "设置",
"connectionMenu.splitGridNode": "拆分网格节点",
"connectionMenu.splitGridNow": "立即拆分网格",
"connectionMenu.multiAngleImage": "图片多角度",
"connectionMenu.navigate": "导航",
"connectionMenu.select": "选择",
"prompt.placeholder": "描述你想生成的内容...",
"prompt.connectedPlaceholder": "来自连接节点的文本(可编辑)...",
"prompt.optionalPlaceholder": "可选提示词(留空则跳过)...",
"prompt.addVariable": "添加变量",
"prompt.setVariableName": "设置变量名",
"prompt.variableHelp": "将此提示词作为 PromptConstructor 节点中的变量使用",
"prompt.variableName": "变量名",
"prompt.variablePlaceholder": "例如 color、style、subject",
"prompt.preview": "预览:{value}",
"composer.promptProvidedByUpstream": "提示词由上游文本节点提供。",
"composer.videoStitchClipCount": "{count} 个视频片段",
"composer.videoStitchAudio": "已连接音频",
"composer.videoStitchNoAudio": "无音频",
"composer.videoStitchInputs": "视频输入",
"composer.videoStitchInputHint": "在节点上调整片段顺序",
"composer.videoStitchNeedTwo": "至少连接 2 个视频片段才能拼接。",
"composer.videoStitchClip": "片段 {index}",
"composer.videoStitchLoop": "循环",
"composer.videoStitchOutputReady": "输出已就绪",
"composer.videoStitchNoOutput": "尚未输出",
"composer.videoStitchReady": "当前节点可拼接",
"composer.videoStitchRun": "拼接当前视频节点",
"composer.easeCurveVideoConnected": "已连接视频",
"composer.easeCurveNoVideo": "连接一个视频输入后可应用缓动曲线。",
"composer.easeCurveInherited": "继承设置",
"composer.easeCurveLocal": "本地设置",
"composer.easeCurveSettings": "曲线设置",
"composer.easeCurvePreset": "预设",
"composer.easeCurveCustom": "自定义贝塞尔",
"composer.easeCurveHandles": "贝塞尔控制点",
"composer.easeCurveInput": "输入",
"composer.easeCurveDuration": "输出时长",
"composer.easeCurveOutputReady": "输出已就绪",
"composer.easeCurveNoOutput": "尚未输出",
"composer.easeCurveReady": "当前曲线可应用",
"composer.easeCurveRun": "应用当前缓动曲线节点",
"composer.selectModel": "选择模型",
"composer.chooseModelTitle": "选择生成模型",
"composer.chooseImageModel": "选择图像模型",
"composer.chooseVideoModel": "选择视频模型",
"composer.chooseAudioModel": "选择声音模型",
"composer.regenerateImageNode": "重新生成当前图片节点",
"composer.regenerateVideoNode": "重新生成当前视频节点",
"composer.regenerateAudioNode": "重新生成当前音频节点",
"composer.imageNode": "图片节点",
"composer.videoNode": "视频节点",
"composer.audioNode": "声音节点",
"composer.imageCount": "生成张数",
"composer.imageCountOption": "{count}张",
"composer.newGeneration": "新建生成",
"composer.selectedNodes": "已选择 {count} 个节点",
"composer.currentNode": "当前节点",
"composer.createAndGenerate": "创建并生成",
"composer.dragFromPort": "从节点端口拖拽以创建下一步",
"composer.multiSelectNoSingleGenerate": "多选暂不支持单节点生成",
"composer.retryCurrentNode": "重试当前节点",
"composer.generate": "生成",
"composer.describeContent": "描述你想生成的内容",
"composer.mainPlaceholder": "描述你想生成的内容,按 / 呼出指令,@ 引用素材",
"composer.uploadReferenceImage": "上传参考图片",
"composer.expand": "展开底部栏",
"composer.collapse": "收起底部栏",
"composer.console": "控制台",
"composer.style": "风格",
"composer.mark": "标记",
"composer.focus": "聚焦",
"composer.addReferenceImage": "添加参考图片",
"composer.referenceFromUpstream": "参考图片来自上游连接",
"composer.reference": "参考",
"composer.referenceImage": "参考图片 {index}",
"composer.removeReferenceImage": "移除参考图片 {index}",
"composer.commands": "指令",
"composer.referenceMaterials": "引用素材",
"composer.commandCharacter": "生成角色图",
"composer.commandCharacterValue": "生成角色图,保持造型统一,画面清晰。",
"composer.commandTurnaround": "生成三视图",
"composer.commandTurnaroundValue": "生成角色三视图,包含正面、侧面、背面。",
"composer.commandVideoShot": "转视频镜头",
"composer.commandVideoShotValue": "将当前画面转成短视频镜头,动作自然。",
"composer.currentReference": "当前引用素材",
"composer.canvasAssets": "画布素材",
"composer.multiSelectUnsupported": "已选择 {count} 个节点。当前版本暂不支持批量编辑。",
"composer.unsupportedNodeHint": "下一步需要从节点端口拖拽创建,底部框只编辑当前选中的生成节点。",
"composer.videoSchemaHint": "视频参数随模型 schema 生效",
"composer.translate": "翻译",
"composer.settings": "设置",
"composer.selectModelTitle": "选择模型:{model}",
"shortcuts.title": "快捷键",
"shortcuts.general": "通用",
"shortcuts.addNodes": "添加节点",
"shortcuts.layout": "布局(先选择 2 个以上节点)",
"shortcuts.canvas": "画布",
"shortcuts.runWorkflow": "运行工作流",
"shortcuts.copyNodes": "复制选中节点",
"shortcuts.paste": "粘贴节点 / 图片 / 文本",
"shortcuts.undo": "撤销",
"shortcuts.redo": "重做",
"shortcuts.showShortcuts": "显示快捷键",
"shortcuts.addPrompt": "添加提示词节点",
"shortcuts.addImage": "添加图片输入节点",
"shortcuts.addGenerateImage": "添加图片生成节点",
"shortcuts.addGenerateVideo": "添加视频生成节点",
"shortcuts.addLLM": "添加 LLM 文本节点",
"shortcuts.addAnnotation": "添加标注节点",
"shortcuts.addAudio": "添加音频节点",
"shortcuts.addVideoInput": "添加视频输入节点",
"shortcuts.addArray": "添加数组节点",
"shortcuts.stackVertical": "垂直排列选中节点",
"shortcuts.stackHorizontal": "水平排列选中节点",
"shortcuts.arrangeGrid": "将选中节点排成网格",
"shortcuts.zoom": "放大 / 缩小",
"shortcuts.pan": "平移(macOS)",
"shortcuts.delete": "删除选中节点",
"project.newProject": "新建项目",
"project.settings": "项目设置",
"project.tabProject": "项目",
"project.tabProviders": "服务商",
"project.tabNodeDefaults": "节点默认值",
"project.tabCanvas": "画布",
"project.name": "项目名称",
"project.directory": "项目目录",
"project.localFolderPlaceholder": "选择这台设备上的本地文件夹",
"project.directoryHelp": "工作流文件和图片会保存在这里,并自动创建 inputs 与 generations 子文件夹。",
"project.embedImages": "将图片嵌入为 base64",
"project.embedImagesDesc": "把所有图片嵌入工作流文件,文件会变大;超大工作流可能触达内存限制。",
"project.inlineSettings": "在节点上显示模型设置",
"project.inlineSettingsDesc": "在生成节点内部显示模型参数,而不是侧边面板",
"project.envHelp": "建议通过 .env.local 添加 API 密钥以提升安全性;这里添加的密钥会覆盖 .env,并存储在浏览器中。",
"project.newapiwgDesc": "Popi 统一模型网关",
"project.baseUrl": "Base URL",
"project.systemImageDefault": "系统默认(Popi Models)",
"project.noneSetFirstUse": "未设置(首次使用时选择)",
"project.defaultLLM": "默认 LLM 设置",
"project.systemLLMDefault": "使用系统默认值(Popi Models Doubao Seed 2.0 Lite)",
"project.provider": "服务商",
"project.model": "模型",
"project.temp": "温度:{value}",
"project.tokens": "Token:{value}",
"project.executionSettings": "执行设置",
"project.maxParallel": "最大并行调用:{count}",
"project.executionHelp": "工作流执行时最多并行运行的节点数量。数值更高可能更快,但也更容易触发 API 限流。",
"project.defaultsHelp": "这些默认值会在通过快捷键创建节点时应用(Shift+G、Shift+L 等)。",
"project.canvasHelp": "配置画布导航和交互方式。",
"project.canvasAssistant": "画布助手",
"project.canvasAssistantShort": "助手",
"project.panMode": "平移模式",
"project.panSpace": "按住 Space 并拖拽平移",
"project.panMiddle": "按住鼠标中键并拖拽",
"project.panAlways": "无需按键即可平移",
"project.panSpaceLabel": "Space + 拖拽",
"project.panMiddleLabel": "鼠标中键",
"project.panAlwaysLabel": "始终开启",
"project.zoomMode": "缩放模式",
"project.zoomAlt": "按住 Alt 并滚动缩放",
"project.zoomCtrl": "按住 Ctrl/Cmd 并滚动缩放",
"project.zoomScroll": "直接滚动缩放",
"project.zoomAltLabel": "Alt + 滚动",
"project.zoomCtrlLabel": "Ctrl + 滚动",
"project.zoomScrollLabel": "滚动",
"project.selectionMode": "选择模式",
"project.selectClick": "点击选择节点",
"project.selectAlt": "按住 Alt 并拖拽选择",
"project.selectShift": "按住 Shift 并拖拽选择",
"project.selectClickLabel": "点击",
"project.selectAltLabel": "Alt + 拖拽",
"project.selectShiftLabel": "Shift + 拖拽",
"project.validating": "验证中...",
"project.errorOpenDir": "打开目录选择器失败",
"project.errorOpenDirWithReason": "打开目录选择器失败:{error}",
"project.errorNameRequired": "项目名称必填",
"project.errorDirectoryRequired": "项目目录必填",
"project.errorChooseLocalFolder": "请从浏览器选择本地文件夹,这样项目会保存在当前操作者的设备上。",
"project.errorAbsolutePath": "项目目录必须是绝对路径(以 /、盘符或 UNC 路径开头)",
"project.errorNotDirectory": "项目路径不是目录",
"project.errorValidateDir": "验证目录失败:{error}",
"modelSearch.search": "搜索模型...",
"modelSearch.allProviders": "所有服务商",
"modelSearch.all": "全部",
"modelSearch.allTypes": "所有类型",
"modelSearch.image": "图片",
"modelSearch.video": "视频",
"modelSearch.audio": "音频",
"modelSearch.refresh": "刷新模型和参数",
"modelSearch.loading": "正在加载模型...",
"modelSearch.tryAgain": "重试",
"modelSearch.removeFallback": "移除备用模型",
"modelSearch.clearSelection": "清除当前选择",
"modelSearch.noModels": "未找到模型",
"modelSearch.adjustFilters": "尝试调整搜索或筛选条件",
"modelSearch.recent": "最近使用",
"promptWorkflow.title": "用提示生成工作流",
"promptWorkflow.describe": "描述你的工作流",
"promptWorkflow.placeholder": "例如:基于参考图创建光照和风格一致的产品摄影...",
"promptWorkflow.help": "描述你希望工作流完成什么。请具体说明输入、输出和任何转换步骤。",
"promptWorkflow.note": "注意:此功能目前仅适用于 Gemini 模型。",
"promptWorkflow.generating": "生成中...",
"promptWorkflow.generate": "生成工作流",
"promptWorkflow.dismiss": "关闭提示",
"promptWorkflow.validation": "请描述你的工作流(至少 3 个字符)",
"promptWorkflow.failed": "生成工作流失败",
"workflowBrowser.noWorkflows": "未找到工作流",
"workflowBrowser.noWorkflowsDesc": "此文件夹不包含任何工作流项目",
"workflowBrowser.title": "你的工作流",
"workflowBrowser.chooseFolderDesc": "选择包含工作流项目的文件夹。你可以稍后再更改。",
"workflowBrowser.chooseFolder": "选择文件夹",
"workflowBrowser.projectCount": "{count} 个项目",
"workflowBrowser.openFromDirectory": "从目录打开",
"workflowBrowser.changeFolder": "更改文件夹",
"workflowBrowser.justNow": "刚刚",
"workflowBrowser.minutesAgo": "{count} 分钟前",
"workflowBrowser.hoursAgo": "{count} 小时前",
"workflowBrowser.daysAgo": "{count} 天前",
"workflowBrowser.monthsAgo": "{count} 个月前",
"workflowBrowser.errorNoWorkflows": "此文件夹中未找到工作流",
"workflowBrowser.errorList": "列出工作流失败",
"workflowBrowser.errorFetch": "获取工作流失败",
"multiSelect.stackHorizontal": "水平排列 (H)",
"multiSelect.stackVertical": "垂直排列 (V)",
"multiSelect.arrangeGrid": "排列为网格 (G)",
"multiSelect.removeGroup": "从分组中移除",
"multiSelect.createGroup": "创建分组",
"multiSelect.downloadZip": "下载图片 ZIP",
"cost.viewDetails": "查看费用详情",
};
const zhTW: Dictionary = {
...zhCN,
"language.label": "語言",
"common.back": "返回",
"common.next": "下一步",
"common.cancel": "取消",
"common.close": "關閉",
"common.save": "儲存",
"common.create": "建立",
"workflowBrowser.title": "你的工作流程",
"workflowBrowser.chooseFolderDesc": "選擇包含工作流程專案的資料夾。你可以稍後再變更。",
"workflowBrowser.chooseFolder": "選擇資料夾",
"workflowBrowser.projectCount": "{count} 個專案",
"workflowBrowser.openFromDirectory": "從目錄開啟",
"workflowBrowser.changeFolder": "變更資料夾",
"workflowBrowser.justNow": "剛剛",
"workflowBrowser.minutesAgo": "{count} 分鐘前",
"workflowBrowser.hoursAgo": "{count} 小時前",
"workflowBrowser.daysAgo": "{count} 天前",
"workflowBrowser.monthsAgo": "{count} 個月前",
"workflowBrowser.errorNoWorkflows": "此資料夾中找不到工作流程",
"workflowBrowser.errorList": "列出工作流程失敗",
"workflowBrowser.errorFetch": "取得工作流程失敗",
"common.browse": "瀏覽",
"common.change": "變更",
"common.clear": "清除",
"common.select": "選擇",
"common.selectModel": "選擇模型",
"common.skip": "略過",
"common.show": "顯示",
"common.hide": "隱藏",
"common.override": "覆寫",
"common.configuredViaEnv": "已透過 .env 設定",
"common.recommended": "推薦",
"common.optional": "可選",
"common.required": "必填",
"common.download": "下載",
"common.remove": "移除",
"common.disconnect": "斷開連接",
"common.play": "播放",
"common.pause": "暫停",
"common.set": "設定",
"common.previous": "上一個",
"common.nextItem": "下一個",
"common.processing": "處理中...",
"error.providerOverloaded": "{model}:服務商暫時過載。請稍後重試,或切換到其他模型。",
"node.optionalTitle": "此輸入為可選,空輸入會被略過",
"node.markOptionalTitle": "標記為可選,空輸入會略過這個分支",
"header.openWelcome": "開啟歡迎頁",
"header.untitled": "未命名",
"header.saving": "儲存中...",
"header.savedAt": "已儲存 {time}",
"header.notSaved": "未儲存",
"header.saveProject": "儲存專案",
"header.configureSaveLocation": "設定儲存位置",
"header.openProject": "開啟專案",
"header.openProjectFolder": "開啟專案資料夾",
"header.projectSettings": "專案設定",
"header.revertAIChanges": "還原 AI 變更",
"header.revertAIChangesTitle": "恢復到 AI 變更前的工作流程",
"header.revertConfirm": "確定嗎?這會恢復先前的工作流程。",
"header.shortcuts": "鍵盤快捷鍵 (?)",
"header.commentsTitle": "{unviewed} 則未讀評論(共 {total} 則)",
"quickstart.description": "一個面向生成式 AI 流程的節點式工作流程編輯器。連接節點即可建立生成與轉換圖片、影片、音訊和 3D 資產的流程。",
"quickstart.docs": "文件",
"quickstart.waitlist": "NB Pro 候補名單",
"quickstart.newProject": "新增專案",
"quickstart.newProjectDesc": "開始新的工作流程",
"quickstart.loadWorkflow": "載入工作流程",
"quickstart.loadWorkflowDesc": "開啟既有檔案",
"quickstart.templates": "範本",
"quickstart.templatesDesc": "預建工作流程",
"quickstart.promptWorkflow": "用提示生成工作流程",
"quickstart.promptWorkflowDesc": "讓 Gemini 幫你建立",
"quickstart.beta": "測試版",
"quickstart.templateExplorerTitle": "範本瀏覽器",
"quickstart.workflowTemplatesTitle": "工作流程範本",
"quickstart.templatesIntro": "使用預建工作流程快速開始。選擇一個範本即可載入畫布。",
"quickstart.quickStart": "快速開始",
"quickstart.searchTemplates": "搜尋範本",
"quickstart.searchTemplatesPlaceholder": "搜尋範本...",
"quickstart.category": "分類",
"quickstart.provider": "服務商",
"quickstart.filterAll": "全部",
"quickstart.categorySimple": "簡單",
"quickstart.categoryAdvanced": "進階",
"quickstart.clearFilters": "清除篩選",
"quickstart.clearAllFilters": "清除全部篩選",
"quickstart.noTemplatesMatch": "沒有符合條件的範本",
"quickstart.adjustSearchFilters": "嘗試調整搜尋或篩選條件",
"quickstart.useWorkflow": "使用工作流程",
"quickstart.loading": "載入中...",
"quickstart.nodeCount": "{count} 個節點",
"quickstart.dismiss": "關閉",
"quickstart.loadTemplateFailed": "載入範本失敗",
"quickstart.template.productShot.name": "產品圖",
"quickstart.template.productShot.description": "將產品放入新的場景或環境",
"quickstart.template.modelProduct.name": "模特 + 產品",
"quickstart.template.modelProduct.description": "組合模特、產品和場景",
"quickstart.template.colorVariations.name": "顏色變體",
"quickstart.template.colorVariations.description": "基於參考圖生成產品配色變體",
"quickstart.template.backgroundSwap.name": "替換背景",
"quickstart.template.backgroundSwap.description": "將主體放入新的背景",
"quickstart.template.styleTransfer.name": "風格轉換",
"quickstart.template.styleTransfer.description": "將一張圖的風格套用到另一張圖",
"quickstart.template.sceneComposite.name": "場景合成",
"quickstart.template.sceneComposite.description": "組合多個場景中的元素",
"ftux.welcomeTo": "歡迎使用 popiart-node",
"ftux.stepApiKeys": "API 金鑰",
"ftux.stepModelDefaults": "模型預設值",
"ftux.stepReady": "就緒",
"ftux.getStarted": "開始使用",
"ftux.skipSetup": "略過設定?",
"ftux.skipSetupDesc": "稍後可在設定中配置 API 金鑰和模型預設值。",
"ftux.welcomeTitle": "開始吧。",
"ftux.welcomeDesc": "像積木一樣連接 AI 模型,生成圖片、影片等內容。",
"ftux.apiKeysDesc": "在這裡新增金鑰以使用 AI 服務商(儲存在瀏覽器),也可以寫入 .env 檔案以獲得更好的安全性與持久性。",
"ftux.enterKey": "輸入金鑰...",
"ftux.modelsTitle": "選擇你的模型",
"ftux.modelsDesc": "選擇圖片和影片的預設 AI 模型,之後可以隨時變更。",
"ftux.defaultImageModel": "預設圖片模型",
"ftux.defaultVideoModel": "預設影片模型",
"ftux.noneSet": "未設定",
"ftux.readyTitle": "準備好了!",
"ftux.readyDesc": "要快速看一遍教學嗎?",
"ftux.startTutorial": "開始教學",
"ftux.tutorial.welcome": "我們先快速了解基本操作。",
"ftux.tutorial.addImage": "點擊「圖片」按鈕,新增一個圖片節點。",
"ftux.tutorial.explainNode": "這是一個節點。每個節點都有特定功能。\n\n這個節點用於新增圖片。",
"ftux.tutorial.explainNodeInputs": "輸入端口一律在節點左側。",
"ftux.tutorial.explainNodeOutputs": "輸出端口一律在節點右側。",
"ftux.tutorial.dragAndDrop": "現在從輸出端口拖曳,並釋放到畫布空白處。",
"ftux.tutorial.selectGenerateImage": "這個選單會顯示該節點可連接的所有節點。\n\n選擇「生成圖片」,新增一個 AI 圖片生成節點。",
"ftux.tutorial.addPromptNode": "點擊「提示詞」按鈕,新增一個提示詞節點。",
"ftux.tutorial.connectPromptToGenerate": "從提示詞節點的輸出端口拖到生成圖片節點的輸入端口。",
"ftux.tutorial.populateContent": "我來幫你填入一些範例內容 🎨",
"ftux.tutorial.explainGenerateNode": "這是生成圖片節點。它會根據提示詞和參考圖,用 AI 建立或修改圖片。",
"ftux.tutorial.explainRunButton": "點擊這個「執行」按鈕會執行工作流程。你也可以按 Cmd+Enter(Windows 上為 Ctrl+Enter)。",
"ftux.tutorial.explainRunOptions": "你也可以點擊下拉選單,從指定節點開始執行,或只執行選中的節點。",
"ftux.tutorial.runWorkflow": "現在執行你的工作流程!點擊「執行」按鈕生成圖片。",
"ftux.tutorial.demonstrateDownstream": "現在看看還能繼續做什麼... 🎬✨",
"ftux.tutorial.demonstrateComplete": "繼續向下游連接更多節點來建立生成式流程,也可以把它當作無限創意畫布使用。",
"ftux.tutorial.saveProject": "儲存專案後,你的工作和生成結果都會保存在本機。",
"ftux.tutorial.resources": "下面這些資源可以提供幫助和靈感:",
"ftux.tutorial.discord": "加入我們的 Discord 社群",
"ftux.tutorial.complete": "全部設定好了!開始創作吧。",
"ftux.tutorial.clickToContinue": "點擊任意位置繼續",
"ftux.tutorial.skip": "略過教學",
"toolbar.categoryInput": "輸入",
"toolbar.categoryText": "文字",
"toolbar.categoryGenerate": "生成",
"toolbar.categoryProcess": "處理",
"toolbar.categoryRoute": "路由",
"toolbar.categoryOutput": "輸出",
"toolbar.image": "圖片",
"toolbar.video": "影片",
"toolbar.prompt": "提示詞",
"toolbar.allNodes": "所有節點",
"toolbar.allModels": "所有模型",
"toolbar.browseModels": "瀏覽模型",
"toolbar.switchConnectors": "切換為{style}連線",
"toolbar.curved": "曲線",
"toolbar.angular": "折線",
"toolbar.runningNodes": "正在執行 {count} 個節點...",
"toolbar.nodesCount": "{count} 個節點",
"toolbar.runEntire": "執行整個工作流程",
"toolbar.runFromSelected": "從選中節點開始執行",
"toolbar.runSelectedOnly": "僅執行選中節點",
"toolbar.runSelectedNodes": "執行選中節點",
"toolbar.runSelectedNodesCount": "執行 {count} 個選中節點",
"node.imageInput": "圖片輸入",
"node.audioInput": "音訊輸入",
"node.videoInput": "影片輸入",
"node.generateImage": "生成圖片",
"node.generateVideo": "生成影片",
"node.generateAudio": "生成音訊",
"node.annotation": "標註",
"annotation.tool.select": "選擇",
"annotation.tool.rectangle": "矩形",
"annotation.tool.circle": "圓形",
"annotation.tool.arrow": "箭頭",
"annotation.tool.draw": "繪製",
"annotation.tool.text": "文字",
"annotation.undo": "復原",
"annotation.redo": "重做",
"annotation.clear": "清除",
"annotation.cancel": "取消",
"annotation.done": "完成",
"annotation.color": "顏色",
"annotation.size": "大小",
"annotation.fill": "填充",
"node.outputGallery": "輸出圖庫",
"imageCompare.connectTwo": "連接 2 張圖片進行對比",
"imageCompare.connectAnother": "再連接一張圖片進行對比",
"imageCompare.imageAConnected": "圖片 A 已連接",
"imageCompare.imageBConnected": "圖片 B 已連接",
"imageCompare.imageAAlt": "圖片 A",
"imageCompare.imageBAlt": "圖片 B",
"upload.imageUnsupported": "格式不支援。請使用 PNG、JPG 或 WebP。",
"upload.imageTooLarge": "圖片過大。最大支援 10MB。",
"upload.videoUnsupported": "格式不支援。請使用 MP4、WebM 或 QuickTime 影片檔。",
"upload.videoTooLarge": "影片檔過大。最大支援 200MB。",
"upload.audioUnsupported": "格式不支援。請使用 MP3、WAV、OGG、AAC 或其他音訊格式。",
"upload.audioTooLarge": "音訊檔過大。最大支援 50MB。",
"imageInput.uploadedAlt": "已上傳圖片",
"imageInput.download": "下載圖片",
"imageInput.remove": "移除圖片",
"videoInput.upload": "上傳影片檔",
"videoInput.dropVideo": "拖入影片或點擊",
"videoInput.download": "下載影片",
"videoInput.remove": "移除影片",
"audioInput.upload": "上傳音訊檔",
"audioInput.dropAudio": "拖入音訊或點擊",
"audioInput.download": "下載音訊",
"audioInput.remove": "移除音訊",
"audioInput.clear": "清除音訊",
"audioInput.loadingWaveform": "正在載入波形...",
"generateAudio.fallbackUsed": "已使用備用模型",
"generateAudio.fallbackUsedTitle": "主模型失敗:{error}\n已使用備用模型:{model}",
"generateAudio.generating": "正在生成音訊...",
"annotation.noImage": "沒有可用圖片。請連接圖片或手動載入一張。",
"annotation.annotatedAlt": "已標註圖片",
"annotation.downloadImage": "下載圖片",
"annotation.removeImage": "移除圖片",
"annotation.editCount": "編輯({count})",
"annotation.addAnnotations": "新增標註",
"annotation.dropClickConnect": "拖入、點擊或連接",
"array.split": "拆分",
"array.delimiter": "分隔符號",
"array.newline": "換行",
"array.regexAdvanced": "正則(進階)",
"array.batch": "批次",
"array.batchModeTitle": "批次模式:所有項目傳送到同一個下游節點",
"array.enableBatchMode": "啟用批次模式",
"array.autoRouteToPrompts": "自動路由到提示詞",
"array.by": "依",
"array.advanced": "進階",
"array.trim": "去除空白",
"array.removeEmpty": "移除空項",
"array.parsedItems": "解析項目({count})",
"array.noItemsParsed": "尚未解析出項目",
"array.selectedForNextConnection": "已選為下一條連接輸出(點擊取消)",
"array.selectForNextConnection": "點擊選擇為下一條連接輸出",
"array.batchFooter": "批次:所有項目傳送到下游節點",
"array.nextWireUsesItem": "下一條連線使用第 {index} 項",
"array.noSelection": "未選擇:連線會從第 1 項開始依序使用",
"videoCommon.encoderUnsupported": "目前瀏覽器不支援影片編碼。",
"videoCommon.encoderHelp": "看起來不對?請在 Discord 聯絡 Willie。",
"videoCommon.checkingEncoder": "正在檢查編碼器...",
"videoCommon.processingPercent": "處理中... {progress}%",
"videoTrim.videoIn": "影片輸入",
"videoTrim.videoOut": "影片輸出",
"videoTrim.connectVideo": "連接一個影片進行裁剪",
"videoTrim.source": "來源影片",
"videoTrim.trimmed": "已裁剪",
"videoTrim.clearTrimmedVideo": "清除裁剪後影片",
"videoTrim.start": "開始",
"videoTrim.end": "結束",
"videoTrim.duration": "時長",
"videoTrim.trimStartTime": "裁剪開始時間",
"videoTrim.trimEndTime": "裁剪結束時間",
"videoTrim.setStartToCurrent": "將開始時間設為目前播放時間",
"videoTrim.setEndToCurrent": "將結束時間設為目前播放時間",
"videoTrim.trim": "裁剪",
"videoStitch.videoInput": "影片 {index}",
"videoStitch.audioInput": "音訊",
"videoStitch.output": "輸出",
"videoStitch.connectVideos": "連接影片進行拼接",
"videoStitch.clipAlt": "片段 {id}",
"videoStitch.clearVideo": "清除影片",
"videoStitch.loop": "循環",
"videoStitch.stitch": "拼接",
"multiAngle.editorTitle": "多角度編輯器",
"multiAngle.imageEditorTitle": "圖片多角度編輯器",
"multiAngle.imageTitle": "圖片多角度",
"multiAngle.closeEditor": "關閉多角度編輯器",
"multiAngle.generate": "生成多角度",
"multiAngle.noImageToast": "未找到可用圖片,無法生成多角度圖片",
"multiAngle.sightControl": "多角度視線控制",
"multiAngle.noImage": "無圖片",
"multiAngle.horizontal": "水平環繞",
"multiAngle.vertical": "垂直俯仰",
"multiAngle.zoom": "景別縮放",
"multiAngle.prompt": "提示詞",
"multiAngle.enableCustomPrompt": "開啟自訂提示詞",
"multiAngle.promptDialog": "多角度提示詞",
"multiAngle.promptInput": "多角度提示詞輸入",
"multiAngle.promptPlaceholder": "輸入提示詞...",
"multiAngle.reset": "重置參數",
"multiAngle.resetAria": "重置多角度參數",
"multiAngle.adjustVerticalUp": "向上調整垂直俯仰",
"multiAngle.adjustVerticalDown": "向下調整垂直俯仰",
"multiAngle.adjustHorizontalLeft": "向左調整水平環繞",
"multiAngle.adjustHorizontalRight": "向右調整水平環繞",
"multiAngle.preset.custom": "自訂",
"multiAngle.preset.fisheye": "魚眼視角",
"multiAngle.preset.tilt": "傾斜視角",
"multiAngle.preset.frontOverhead": "正面俯拍",
"multiAngle.preset.frontLow": "正面仰拍",
"multiAngle.preset.panoramicOverhead": "全景俯拍",
"multiAngle.preset.back": "背面視角",
"multiAngle.zoom.wide": "全景",
"multiAngle.zoom.medium": "中景",
"multiAngle.zoom.close": "特寫",
"workflow.splitGrid.noImage": "沒有可拆分的圖片。請先生成或載入一張圖片。",
"workflow.splitGrid.detectFailed": "無法識別圖片網格。",
"workflow.splitGrid.failed": "拆分圖片網格失敗:{error}",
"workflow.generatedSuccess": "工作流程生成成功",
"workflow.generatedFailed": "生成工作流程失敗",
"workflow.generatedFailedRetry": "生成工作流程失敗,請重試。",
"workflow.appliedEdits": "已套用 {count} 個編輯",
"chat.title": "畫布助手",
"chat.beta": "測試版",
"chat.clear": "清空對話",
"chat.close": "關閉對話",
"chat.dismiss": "關閉",
"chat.emptyTitle": "可以詢問目前畫布,也可以讓我準備修改。",
"chat.diagnoseSelected": "診斷選中節點",
"chat.makeVariants": "生成變體",
"chat.promptDiagnose": "診斷選中的節點,並給出最小可用修復建議。",
"chat.promptVariants": "準備一組編輯:基於選中的圖片或生成節點建立四個視覺變體。",
"chat.proposalReady": "修改方案已準備",
"chat.candidateReady": "候選工作流程已準備好套用。",
"chat.runReady": "執行操作已準備好套用。",
"chat.candidateWorkflow": "候選工作流程",
"chat.applyWorkflow": "套用工作流程",
"chat.operationPreview": "操作預覽",
"chat.applyEdits": "套用編輯",
"chat.runPreview": "執行預覽",
"chat.runNow": "立即執行",
"chat.focusedNodes": "聚焦 {count} 個選中節點",
"chat.runSelected": "執行選中",
"chat.runAffected": "執行影響範圍({count})",
"chat.placeholder": "輸入訊息...",
"chat.building": "正在建立...",
"chat.buildWorkflow": "建立工作流程",
"chat.open": "助手",
"chat.noSelection": "請先選擇一個或多個節點。",
"workflow.invalidWorkflowFile": "工作流程檔案格式無效",
"workflow.parseWorkflowFileFailed": "解析工作流程檔案失敗",
"splitGridNode.sourceGridAlt": "來源網格",
"splitGridNode.connectImage": "連接圖片",
"splitGridNode.gridSummary": "{rows}x{cols} 網格({count} 張圖片)",
"splitGridNode.generateSetsCreated": "已建立 {count} 組生成節點",
"splitGridNode.notConfigured": "未設定 - 點擊設定",
"splitGridNode.configureFirst": "請先設定節點",
"splitGridNode.connectImageFirst": "請先連接圖片",
"splitGridNode.splitGrid": "拆分網格",
"splitGridNode.split": "拆分",
"output.downloadCurrent": "下載目前{type}",
"output.downloadAll": "下載全部輸出",
"node.settings": "設定",
"node.runToGenerate": "執行以生成",
"node.selectModel": "選擇模型...",
"node.primary": "主模型",
"node.text": "文字",
"node.image": "圖片",
"node.notUsedByModel": "此模型不使用",
"node.generationFailed": "生成失敗",
"node.videoGenerationFailed": "影片生成失敗",
"node.loadingParameters": "正在載入參數...",
"node.noParameters": "無可用參數",
"node.default": "預設",
"node.model": "模型",
"node.size": "尺寸",
"node.quality": "品質",
"node.voice": "聲音",
"node.sound": "聲音",
"node.duration": "時長",
"node.seconds": "{count}秒",
"node.aspectRatio": "寬高比",
"node.resolution": "解析度",
"node.googleSearch": "Google 搜尋",
"node.imageSearch": "圖片搜尋",
"node.provider": "服務商",
"node.temperature": "溫度:{value}",
"node.maxTokens": "最大 Token:{value}",
"node.generic": "節點",
"splitGridSettings.title": "拆分網格設定",
"splitGridSettings.gridLayout": "網格版面",
"splitGridSettings.gridSummary": "網格將拆分為 {rows}x{cols} = {count} 張圖片",
"splitGridSettings.defaultPrompt": "預設提示詞",
"splitGridSettings.promptPlaceholder": "輸入將套用到所有生成圖片的提示詞...",
"splitGridSettings.promptHelp": "建立後,每個提示詞節點都可以個別編輯",
"splitGridSettings.generateNodeSettings": "生成節點設定",
"splitGridSettings.createGenerateSets": "建立 {count} 組生成節點",
"imageInput.upload": "上傳圖片",
"imageInput.dropImage": "拖入圖片",
"dropOverlay.workflow": "拖入以載入工作流程",
"dropOverlay.node": "拖入以建立節點",
"dropOverlay.audio": "拖入音訊以建立節點",
"dropOverlay.image": "拖入圖片以建立節點",
"dropOverlay.splittingImageGrid": "正在拆分圖片網格...",
"connectionMenu.addNode": "新增 {type} 節點",
"connectionMenu.type.image": "圖片",
"connectionMenu.type.text": "文字",
"connectionMenu.type.audio": "音訊",
"connectionMenu.type.video": "影片",
"connectionMenu.type.3d": "3D",
"connectionMenu.type.easeCurve": "設定",
"connectionMenu.splitGridNode": "拆分網格節點",
"connectionMenu.splitGridNow": "立即拆分網格",
"connectionMenu.multiAngleImage": "圖片多角度",
"connectionMenu.navigate": "導覽",
"connectionMenu.select": "選擇",
"prompt.placeholder": "描述你想生成的內容...",
"prompt.connectedPlaceholder": "來自連接節點的文字(可編輯)...",
"prompt.optionalPlaceholder": "可選提示詞(留空則略過)...",
"prompt.addVariable": "新增變數",
"prompt.setVariableName": "設定變數名稱",
"prompt.variableHelp": "將此提示詞作為 PromptConstructor 節點中的變數使用",
"prompt.variableName": "變數名稱",
"prompt.variablePlaceholder": "例如 color、style、subject",
"prompt.preview": "預覽:{value}",
"composer.promptProvidedByUpstream": "提示詞由上游文字節點提供。",
"composer.videoStitchClipCount": "{count} 個影片片段",
"composer.videoStitchAudio": "已連接音訊",
"composer.videoStitchNoAudio": "無音訊",
"composer.videoStitchInputs": "影片輸入",
"composer.videoStitchInputHint": "在節點上調整片段順序",
"composer.videoStitchNeedTwo": "至少連接 2 個影片片段才能拼接。",
"composer.videoStitchClip": "片段 {index}",
"composer.videoStitchLoop": "循環",
"composer.videoStitchOutputReady": "輸出已就緒",
"composer.videoStitchNoOutput": "尚未輸出",
"composer.videoStitchReady": "目前節點可拼接",
"composer.videoStitchRun": "拼接目前影片節點",
"composer.easeCurveVideoConnected": "已連接影片",
"composer.easeCurveNoVideo": "連接一個影片輸入後可套用緩動曲線。",
"composer.easeCurveInherited": "繼承設定",
"composer.easeCurveLocal": "本機設定",
"composer.easeCurveSettings": "曲線設定",
"composer.easeCurvePreset": "預設",
"composer.easeCurveCustom": "自訂貝塞爾",
"composer.easeCurveHandles": "貝塞爾控制點",
"composer.easeCurveInput": "輸入",
"composer.easeCurveDuration": "輸出時長",
"composer.easeCurveOutputReady": "輸出已就緒",
"composer.easeCurveNoOutput": "尚未輸出",
"composer.easeCurveReady": "目前曲線可套用",
"composer.easeCurveRun": "套用目前緩動曲線節點",
"shortcuts.title": "鍵盤快捷鍵",
"shortcuts.layout": "版面(先選擇 2 個以上節點)",
"shortcuts.addNodes": "新增節點",
"shortcuts.runWorkflow": "執行工作流程",
"shortcuts.copyNodes": "複製選中節點",
"shortcuts.paste": "貼上節點 / 圖片 / 文字",
"shortcuts.undo": "復原",
"shortcuts.redo": "重做",
"shortcuts.addPrompt": "新增提示詞節點",
"shortcuts.addImage": "新增圖片輸入節點",
"shortcuts.addGenerateImage": "新增圖片生成節點",
"shortcuts.addGenerateVideo": "新增影片生成節點",
"shortcuts.addAudio": "新增音訊節點",
"shortcuts.addVideoInput": "新增影片輸入節點",
"shortcuts.delete": "刪除選中節點",
"project.newProject": "新增專案",
"project.settings": "專案設定",
"project.tabProject": "專案",
"project.tabProviders": "服務商",
"project.tabNodeDefaults": "節點預設值",
"project.name": "專案名稱",
"project.directory": "專案目錄",
"project.localFolderPlaceholder": "選擇這台裝置上的本機資料夾",
"project.directoryHelp": "工作流程檔案和圖片會儲存在這裡,並自動建立 inputs 與 generations 子資料夾。",
"project.embedImages": "將圖片嵌入為 base64",
"project.inlineSettings": "在節點上顯示模型設定",
"project.newapiwgDesc": "Popi 統一模型閘道",
"project.baseUrl": "Base URL",
"project.defaultLLM": "預設 LLM 設定",
"project.systemLLMDefault": "使用系統預設值(Popi Models Doubao Seed 2.0 Lite)",
"project.executionSettings": "執行設定",
"project.maxParallel": "最大平行呼叫:{count}",
"project.canvasHelp": "設定畫布導覽和互動方式。",
"project.canvasAssistant": "畫布助手",
"project.canvasAssistantShort": "助手",
"project.panMode": "平移模式",
"project.zoomMode": "縮放模式",
"project.selectionMode": "選擇模式",
"project.validating": "驗證中...",
"project.errorChooseLocalFolder": "請從瀏覽器選擇本機資料夾,這樣專案會儲存在目前操作者的裝置上。",
"modelSearch.search": "搜尋模型...",
"modelSearch.allProviders": "所有服務商",
"modelSearch.all": "全部",
"modelSearch.allTypes": "所有類型",
"modelSearch.image": "圖片",
"modelSearch.video": "影片",
"modelSearch.audio": "音訊",
"modelSearch.refresh": "重新整理模型和參數",
"modelSearch.loading": "正在載入模型...",
"modelSearch.tryAgain": "重試",
"modelSearch.removeFallback": "移除備用模型",
"modelSearch.clearSelection": "清除目前選擇",
"modelSearch.noModels": "找不到模型",
"modelSearch.adjustFilters": "嘗試調整搜尋或篩選條件",
"modelSearch.recent": "最近使用",
"promptWorkflow.title": "用提示生成工作流程",
"promptWorkflow.describe": "描述你的工作流程",
"promptWorkflow.placeholder": "例如:基於參考圖建立光線和風格一致的產品攝影...",
"promptWorkflow.help": "描述你希望工作流程完成什麼。請具體說明輸入、輸出和任何轉換步驟。",
"promptWorkflow.note": "注意:此功能目前僅適用於 Gemini 模型。",
"promptWorkflow.generating": "生成中...",
"promptWorkflow.generate": "生成工作流程",
"promptWorkflow.dismiss": "關閉提示",
"promptWorkflow.validation": "請描述你的工作流程(至少 3 個字元)",
"promptWorkflow.failed": "生成工作流程失敗",
"workflowBrowser.noWorkflows": "找不到工作流程",
"workflowBrowser.noWorkflowsDesc": "此資料夾不包含任何工作流程專案",
"multiSelect.stackHorizontal": "水平排列 (H)",
"multiSelect.stackVertical": "垂直排列 (V)",
"multiSelect.arrangeGrid": "排列為網格 (G)",
"multiSelect.removeGroup": "從群組中移除",
"multiSelect.createGroup": "建立群組",
"multiSelect.downloadZip": "下載圖片 ZIP",
"cost.viewDetails": "查看費用詳情",
};
const ja: Dictionary = {
...en,
"language.label": "言語",
"common.back": "戻る",
"common.next": "次へ",
"common.cancel": "キャンセル",
"common.close": "閉じる",
"common.save": "保存",
"common.create": "作成",
"common.browse": "参照",
"common.change": "変更",
"common.clear": "クリア",
"common.select": "選択",
"common.selectModel": "モデルを選択",
"common.skip": "スキップ",
"common.show": "表示",
"common.hide": "非表示",
"common.override": "上書き",
"common.configuredViaEnv": ".env で設定済み",
"common.recommended": "推奨",
"common.optional": "任意",
"common.required": "必須",
"common.download": "ダウンロード",
"common.remove": "削除",
"common.disconnect": "接続解除",
"common.play": "再生",
"common.pause": "一時停止",
"common.set": "設定",
"common.previous": "前へ",
"common.nextItem": "次へ",
"common.processing": "処理中...",
"error.providerOverloaded": "{model}: プロバイダーが一時的に混雑しています。少し待って再試行するか、別のモデルに切り替えてください。",
"node.optionalTitle": "この入力は任意です。空の入力はスキップされます",
"node.markOptionalTitle": "任意に設定します。空の入力はこの分岐をスキップします",
"header.openWelcome": "ウェルカム画面を開く",
"header.untitled": "無題",
"header.saving": "保存中...",
"header.savedAt": "{time} に保存済み",
"header.notSaved": "未保存",
"header.saveProject": "プロジェクトを保存",
"header.configureSaveLocation": "保存先を設定",
"header.openProject": "プロジェクトを開く",
"header.openProjectFolder": "プロジェクトフォルダを開く",
"header.projectSettings": "プロジェクト設定",
"header.revertAIChanges": "AI の変更を戻す",
"header.revertAIChangesTitle": "AI 変更前のワークフローに戻す",
"header.revertConfirm": "よろしいですか?以前のワークフローに戻します。",
"header.shortcuts": "キーボードショートカット (?)",
"header.support": "サポート",
"header.commentsTitle": "未読コメント {unviewed} 件(合計 {total} 件)",
"quickstart.description": "生成 AI パイプライン向けのノードベースのワークフローエディタです。ノードを接続して、画像、動画、音声、3D アセットを生成・変換するパイプラインを構築できます。",
"quickstart.docs": "ドキュメント",
"quickstart.waitlist": "NB Pro ウェイトリスト",
"quickstart.newProject": "新規プロジェクト",
"quickstart.newProjectDesc": "新しいワークフローを開始",
"quickstart.loadWorkflow": "ワークフローを読み込み",
"quickstart.loadWorkflowDesc": "既存ファイルを開く",
"quickstart.templates": "テンプレート",
"quickstart.templatesDesc": "事前作成済みワークフロー",
"quickstart.promptWorkflow": "プロンプトで作成",
"quickstart.promptWorkflowDesc": "Gemini に構築してもらう",
"quickstart.beta": "ベータ",
"quickstart.templateExplorerTitle": "テンプレート一覧",
"quickstart.workflowTemplatesTitle": "ワークフローテンプレート",
"quickstart.templatesIntro": "すぐに始められる事前作成済みワークフローです。テンプレートを選ぶとキャンバスに読み込まれます。",
"quickstart.quickStart": "クイックスタート",
"quickstart.searchTemplates": "テンプレートを検索",
"quickstart.searchTemplatesPlaceholder": "テンプレートを検索...",
"quickstart.category": "カテゴリ",
"quickstart.provider": "プロバイダー",
"quickstart.filterAll": "すべて",
"quickstart.categorySimple": "シンプル",
"quickstart.categoryAdvanced": "高度",
"quickstart.clearFilters": "フィルターをクリア",
"quickstart.clearAllFilters": "すべてのフィルターをクリア",
"quickstart.noTemplatesMatch": "条件に一致するテンプレートがありません",
"quickstart.adjustSearchFilters": "検索条件またはフィルターを調整してください",
"quickstart.useWorkflow": "ワークフローを使用",
"quickstart.loading": "読み込み中...",
"quickstart.nodeCount": "{count} ノード",
"quickstart.dismiss": "閉じる",
"quickstart.loadTemplateFailed": "テンプレートの読み込みに失敗しました",
"quickstart.template.productShot.name": "商品撮影",
"quickstart.template.productShot.description": "商品を新しいシーンや環境に配置",
"quickstart.template.modelProduct.name": "モデル + 商品",
"quickstart.template.modelProduct.description": "モデル、商品、シーンを組み合わせる",
"quickstart.template.colorVariations.name": "カラーバリエーション",
"quickstart.template.colorVariations.description": "参照画像から商品の色違いを生成",
"quickstart.template.backgroundSwap.name": "背景差し替え",
"quickstart.template.backgroundSwap.description": "被写体を新しい背景に配置",
"quickstart.template.styleTransfer.name": "スタイル変換",
"quickstart.template.styleTransfer.description": "ある画像のスタイルを別の画像に適用",
"quickstart.template.sceneComposite.name": "シーン合成",
"quickstart.template.sceneComposite.description": "複数のシーンの要素を組み合わせる",
"ftux.welcomeTo": "popiart-node へようこそ",
"ftux.stepWelcome": "ようこそ",
"ftux.stepApiKeys": "API キー",
"ftux.stepModelDefaults": "モデル既定値",
"ftux.stepReady": "準備完了",
"ftux.getStarted": "開始",
"ftux.skipSetup": "セットアップをスキップしますか?",
"ftux.skipSetupDesc": "API キーとモデル既定値は後で設定から変更できます。",
"ftux.welcomeTitle": "始めましょう。",
"ftux.welcomeDesc": "AI モデルをブロックのように接続して、画像や動画などを生成します。",
"ftux.apiKeysTitle": "API キー",
"ftux.apiKeysDesc": "AI プロバイダーを使うためのキーをここに追加します(ブラウザに保存)。より安全に保持するには .env ファイルに保存してください。",
"ftux.getApiKey": "{provider} の API キーを取得",
"ftux.getApiKeyTip": "API キーを取得",
"ftux.llmOnlyTip": "LLM ノードのみで使用",
"ftux.enterKey": "キーを入力...",
"ftux.modelsTitle": "モデルを選択",
"ftux.modelsDesc": "画像と動画の既定 AI モデルを選びます。後から変更できます。",
"ftux.defaultImageModel": "既定の画像モデル",
"ftux.defaultVideoModel": "既定の動画モデル",
"ftux.noneSet": "未設定",
"ftux.readyTitle": "準備できました!",
"ftux.readyDesc": "クイックチュートリアルを見ますか?",
"ftux.startTutorial": "チュートリアルを開始",
"ftux.tutorial.welcome": "まず基本操作を見ていきましょう。",
"ftux.tutorial.addImage": "「画像」ボタンをクリックして画像ノードを追加します。",
"ftux.tutorial.explainNode": "これはノードです。各ノードには決まった役割があります。\n\nこのノードは画像を追加します。",
"ftux.tutorial.explainNodeInputs": "入力端子は常にノードの左側にあります。",
"ftux.tutorial.explainNodeOutputs": "出力端子は常にノードの右側にあります。",
"ftux.tutorial.dragAndDrop": "出力端子からドラッグして、キャンバスの空いている場所にドロップします。",
"ftux.tutorial.selectGenerateImage": "このメニューには、このノードから接続できる項目が表示されます。\n\n「画像生成」を選択して AI 画像生成ノードを追加します。",
"ftux.tutorial.addPromptNode": "「プロンプト」ボタンをクリックしてプロンプトノードを追加します。",
"ftux.tutorial.connectPromptToGenerate": "プロンプトノードの出力端子から、画像生成ノードの入力端子へドラッグします。",
"ftux.tutorial.populateContent": "サンプル内容を少し追加します 🎨",
"ftux.tutorial.explainGenerateNode": "これは画像生成ノードです。プロンプトと参照画像をもとに、AI が画像を作成または編集します。",
"ftux.tutorial.explainRunButton": "この「実行」ボタンをクリックするとワークフローが実行されます。Cmd+Enter(Windows では Ctrl+Enter)でも実行できます。",
"ftux.tutorial.explainRunOptions": "ドロップダウンから、特定のノードから実行したり、選択中のノードだけを実行したりできます。",
"ftux.tutorial.runWorkflow": "ワークフローを実行しましょう!「実行」ボタンをクリックして画像を生成します。",
"ftux.tutorial.demonstrateDownstream": "次に、広げられる可能性を見てみましょう... 🎬✨",
"ftux.tutorial.demonstrateComplete": "下流にさらにノードを接続して生成パイプラインを作ることも、無限のクリエイティブキャンバスとして使うこともできます。",
"ftux.tutorial.saveProject": "プロジェクトを保存すると、作業内容と生成結果をローカルに残せます。",
"ftux.tutorial.resources": "ヘルプやアイデアには以下のリソースをご覧ください:",
"ftux.tutorial.discord": "Discord コミュニティに参加",
"ftux.tutorial.complete": "準備完了です!制作を始めましょう。",
"ftux.tutorial.clickToContinue": "任意の場所をクリックして続行",
"ftux.tutorial.skip": "チュートリアルをスキップ",
"toolbar.categoryInput": "入力",
"toolbar.categoryText": "テキスト",
"toolbar.categoryGenerate": "生成",
"toolbar.categoryProcess": "処理",
"toolbar.categoryRoute": "ルート",
"toolbar.categoryOutput": "出力",
"toolbar.image": "画像",
"toolbar.video": "動画",
"toolbar.prompt": "プロンプト",
"toolbar.generate": "生成",
"toolbar.output": "出力",
"toolbar.allNodes": "すべてのノード",
"toolbar.allModels": "すべてのモデル",
"toolbar.browseModels": "モデルを参照",
"toolbar.switchConnectors": "{style}コネクタに切り替え",
"toolbar.curved": "曲線",
"toolbar.angular": "直角",
"toolbar.run": "実行",
"toolbar.stop": "停止",
"toolbar.running": "実行中...",
"toolbar.runningNode": "{node} を実行中...",
"toolbar.runningNodes": "{count} 個のノードを実行中...",
"toolbar.nodesCount": "{count} 個のノード",
"toolbar.runOptions": "実行オプション",
"toolbar.runEntire": "ワークフロー全体を実行",
"toolbar.runFromSelected": "選択ノードから実行",
"toolbar.runSelectedOnly": "選択ノードのみ実行",
"toolbar.runSelectedNodes": "選択ノードを実行",
"toolbar.runSelectedNodesCount": "選択した {count} ノードを実行",
"toolbar.selectSingleNode": "先に 1 つのノードを選択してください",
"toolbar.selectOneOrMoreNodes": "先に 1 つ以上のノードを選択してください",
"node.imageInput": "画像入力",
"node.audioInput": "音声入力",
"node.videoInput": "動画入力",
"node.glbViewer": "3D ビューア",
"node.prompt": "プロンプト",
"node.promptConstructor": "プロンプト構築",
"node.array": "配列",
"node.generateImage": "画像生成",
"node.generateVideo": "動画生成",
"node.generate3d": "3D 生成",
"node.generateAudio": "音声生成",
"node.llmGenerate": "LLM 生成",
"node.annotation": "注釈",
"annotation.tool.select": "選択",
"annotation.tool.rectangle": "矩形",
"annotation.tool.circle": "円形",
"annotation.tool.arrow": "矢印",
"annotation.tool.draw": "描画",
"annotation.tool.text": "テキスト",
"annotation.undo": "元に戻す",
"annotation.redo": "やり直し",
"annotation.clear": "クリア",
"annotation.cancel": "キャンセル",
"annotation.done": "完了",
"annotation.color": "色",
"annotation.size": "サイズ",
"annotation.fill": "塗りつぶし",
"node.splitGrid": "グリッド分割",
"node.videoStitch": "動画結合",
"node.videoTrim": "動画トリム",
"node.easeCurve": "イーズ曲線",
"node.frameGrab": "フレーム取得",
"node.imageCompare": "画像比較",
"imageCompare.connectTwo": "比較する画像を 2 枚接続してください",
"imageCompare.connectAnother": "比較するもう 1 枚の画像を接続してください",
"imageCompare.imageAConnected": "画像 A が接続済み",
"imageCompare.imageBConnected": "画像 B が接続済み",
"imageCompare.imageAAlt": "画像 A",
"imageCompare.imageBAlt": "画像 B",
"upload.imageUnsupported": "未対応の形式です。PNG、JPG、WebP を使用してください。",
"upload.imageTooLarge": "画像が大きすぎます。最大サイズは 10MB です。",
"upload.videoUnsupported": "未対応の形式です。MP4、WebM、QuickTime 動画ファイルを使用してください。",
"upload.videoTooLarge": "動画ファイルが大きすぎます。最大サイズは 200MB です。",
"upload.audioUnsupported": "未対応の形式です。MP3、WAV、OGG、AAC、またはその他の音声形式を使用してください。",
"upload.audioTooLarge": "音声ファイルが大きすぎます。最大サイズは 50MB です。",
"imageInput.uploadedAlt": "アップロード済み画像",
"imageInput.download": "画像をダウンロード",
"imageInput.remove": "画像を削除",
"videoInput.upload": "動画ファイルをアップロード",
"videoInput.dropVideo": "動画をドロップまたはクリック",
"videoInput.download": "動画をダウンロード",
"videoInput.remove": "動画を削除",
"audioInput.upload": "音声ファイルをアップロード",
"audioInput.dropAudio": "音声をドロップまたはクリック",
"audioInput.download": "音声をダウンロード",
"audioInput.remove": "音声を削除",
"audioInput.clear": "音声をクリア",
"audioInput.loadingWaveform": "波形を読み込み中...",
"generateAudio.fallbackUsed": "フォールバックを使用",
"generateAudio.fallbackUsedTitle": "メインが失敗: {error}\n使用したフォールバック: {model}",
"generateAudio.generating": "音声を生成中...",
"annotation.noImage": "利用可能な画像がありません。画像を接続するか手動で読み込んでください。",
"annotation.annotatedAlt": "注釈付き画像",
"annotation.downloadImage": "画像をダウンロード",
"annotation.removeImage": "画像を削除",
"annotation.editCount": "編集({count})",
"annotation.addAnnotations": "注釈を追加",
"annotation.dropClickConnect": "ドロップ、クリック、または接続",
"array.split": "分割",
"array.delimiter": "区切り文字",
"array.newline": "改行",
"array.regexAdvanced": "正規表現(詳細)",
"array.batch": "一括",
"array.batchModeTitle": "一括モード:すべての項目を 1 つの下流ノードへ送信",
"array.enableBatchMode": "一括モードを有効化",
"array.autoRouteToPrompts": "プロンプトへ自動ルート",
"array.by": "方法",
"array.advanced": "詳細",
"array.trim": "空白を削除",
"array.removeEmpty": "空項目を削除",
"array.parsedItems": "解析済み項目({count})",
"array.noItemsParsed": "解析済み項目はありません",
"array.selectedForNextConnection": "次の接続に選択済み(クリックで解除)",
"array.selectForNextConnection": "クリックして次の接続に選択",
"array.batchFooter": "一括:すべての項目を下流ノードへ送信",
"array.nextWireUsesItem": "次のワイヤーは項目 {index} を使用",
"array.noSelection": "未選択:ワイヤーは項目 1 から順に使用",
"videoCommon.encoderUnsupported": "このブラウザは動画エンコードに対応していません。",
"videoCommon.encoderHelp": "問題がある場合は Discord で Willie に連絡してください。",
"videoCommon.checkingEncoder": "エンコーダーを確認中...",
"videoCommon.processingPercent": "処理中... {progress}%",
"videoTrim.videoIn": "動画入力",
"videoTrim.videoOut": "動画出力",
"videoTrim.connectVideo": "トリムする動画を接続してください",
"videoTrim.source": "元動画",
"videoTrim.trimmed": "トリム済み",
"videoTrim.clearTrimmedVideo": "トリム済み動画をクリア",
"videoTrim.start": "開始",
"videoTrim.end": "終了",
"videoTrim.duration": "長さ",
"videoTrim.trimStartTime": "トリム開始時間",
"videoTrim.trimEndTime": "トリム終了時間",
"videoTrim.setStartToCurrent": "開始時間を現在の再生位置に設定",
"videoTrim.setEndToCurrent": "終了時間を現在の再生位置に設定",
"videoTrim.trim": "トリム",
"videoStitch.videoInput": "動画 {index}",
"videoStitch.audioInput": "音声",
"videoStitch.output": "出力",
"videoStitch.connectVideos": "結合する動画を接続してください",
"videoStitch.clipAlt": "クリップ {id}",
"videoStitch.clearVideo": "動画をクリア",
"videoStitch.loop": "ループ",
"videoStitch.stitch": "結合",
"multiAngle.editorTitle": "マルチアングルエディタ",
"multiAngle.imageEditorTitle": "画像マルチアングルエディタ",
"multiAngle.imageTitle": "画像マルチアングル",
"multiAngle.closeEditor": "マルチアングルエディタを閉じる",
"multiAngle.generate": "マルチアングルを生成",
"multiAngle.noImageToast": "利用可能な画像が見つかりません。マルチアングル画像を生成できません。",
"multiAngle.sightControl": "マルチアングル視線コントロール",
"multiAngle.noImage": "画像なし",
"multiAngle.horizontal": "水平オービット",
"multiAngle.vertical": "垂直ピッチ",
"multiAngle.zoom": "ショットスケール",
"multiAngle.prompt": "プロンプト",
"multiAngle.enableCustomPrompt": "カスタムプロンプトを有効化",
"multiAngle.promptDialog": "マルチアングルプロンプト",
"multiAngle.promptInput": "マルチアングルプロンプト入力",
"multiAngle.promptPlaceholder": "プロンプトを入力...",
"multiAngle.reset": "パラメータをリセット",
"multiAngle.resetAria": "マルチアングルパラメータをリセット",
"multiAngle.adjustVerticalUp": "垂直ピッチを上げる",
"multiAngle.adjustVerticalDown": "垂直ピッチを下げる",
"multiAngle.adjustHorizontalLeft": "水平オービットを左へ調整",
"multiAngle.adjustHorizontalRight": "水平オービットを右へ調整",
"multiAngle.preset.custom": "カスタム",
"multiAngle.preset.fisheye": "魚眼",
"multiAngle.preset.tilt": "傾き",
"multiAngle.preset.frontOverhead": "正面俯瞰",
"multiAngle.preset.frontLow": "正面ローアングル",
"multiAngle.preset.panoramicOverhead": "パノラマ俯瞰",
"multiAngle.preset.back": "背面",
"multiAngle.zoom.wide": "ワイド",
"multiAngle.zoom.medium": "ミディアム",
"multiAngle.zoom.close": "クローズアップ",
"workflow.splitGrid.noImage": "分割できる画像がありません。先に画像を生成または読み込んでください。",
"workflow.splitGrid.detectFailed": "画像内のグリッドを検出できませんでした。",
"workflow.splitGrid.failed": "画像グリッドの分割に失敗しました: {error}",
"workflow.generatedSuccess": "ワークフローを生成しました",
"workflow.generatedFailed": "ワークフローの生成に失敗しました",
"workflow.generatedFailedRetry": "ワークフローの生成に失敗しました。再試行してください。",
"workflow.appliedEdits": "{count} 件の編集を適用しました",
"chat.title": "キャンバスアシスタント",
"chat.beta": "ベータ",
"chat.clear": "チャットをクリア",
"chat.close": "チャットを閉じる",
"chat.dismiss": "閉じる",
"chat.emptyTitle": "このキャンバスについて質問したり、編集案を作成できます。",
"chat.diagnoseSelected": "選択を診断",
"chat.makeVariants": "バリエーション作成",
"chat.promptDiagnose": "選択したノードを診断し、最小限の有用な修正を提案してください。",
"chat.promptVariants": "選択した画像または生成ノードから、4つの視覚バリエーションを作る編集案を準備してください。",
"chat.proposalReady": "提案を準備しました",
"chat.candidateReady": "候補ワークフローを適用できます。",
"chat.runReady": "実行アクションを適用できます。",
"chat.candidateWorkflow": "候補ワークフロー",
"chat.applyWorkflow": "ワークフローを適用",
"chat.operationPreview": "操作プレビュー",
"chat.applyEdits": "編集を適用",
"chat.runPreview": "実行プレビュー",
"chat.runNow": "今すぐ実行",
"chat.focusedNodes": "選択中の {count} ノードにフォーカス",
"chat.runSelected": "選択を実行",
"chat.runAffected": "影響範囲を実行({count})",
"chat.placeholder": "メッセージを入力...",
"chat.building": "構築中...",
"chat.buildWorkflow": "ワークフローを構築",
"chat.open": "アシスタント",
"chat.noSelection": "先に1つ以上のノードを選択してください。",
"workflow.invalidWorkflowFile": "ワークフローファイル形式が無効です",
"workflow.parseWorkflowFileFailed": "ワークフローファイルの解析に失敗しました",
"splitGridNode.sourceGridAlt": "元グリッド",
"splitGridNode.connectImage": "画像を接続",
"splitGridNode.gridSummary": "{rows}x{cols} グリッド({count} 枚の画像)",
"splitGridNode.generateSetsCreated": "{count} 個の生成セットを作成済み",
"splitGridNode.notConfigured": "未設定 - 設定をクリック",
"splitGridNode.configureFirst": "先にノードを設定してください",
"splitGridNode.connectImageFirst": "先に画像を接続してください",
"splitGridNode.splitGrid": "グリッドを分割",
"splitGridNode.split": "分割",
"node.router": "ルーター",
"node.switch": "スイッチ",
"node.conditionalSwitch": "条件スイッチ",
"node.output": "出力",
"node.outputGallery": "出力ギャラリー",
"output.downloadCurrent": "現在の{type}をダウンロード",
"output.downloadAll": "すべての出力をダウンロード",
"node.settings": "設定",
"node.runToGenerate": "実行して生成",
"node.selectModel": "モデルを選択...",
"node.primary": "メイン",
"node.text": "テキスト",
"node.image": "画像",
"node.notUsedByModel": "このモデルでは未使用",
"node.generationFailed": "生成に失敗しました",
"node.videoGenerationFailed": "動画生成に失敗しました",
"node.loadingParameters": "パラメータを読み込み中...",
"node.noParameters": "利用可能なパラメータはありません",
"node.default": "既定",
"node.model": "モデル",
"node.size": "サイズ",
"node.quality": "品質",
"node.voice": "音声",
"node.sound": "音声",
"node.duration": "長さ",
"node.seconds": "{count}秒",
"node.aspectRatio": "アスペクト比",
"node.resolution": "解像度",
"node.googleSearch": "Google 検索",
"node.imageSearch": "画像検索",
"node.provider": "プロバイダー",
"node.temperature": "温度:{value}",
"node.maxTokens": "最大トークン:{value}",
"node.generic": "ノード",
"splitGridSettings.title": "グリッド分割設定",
"splitGridSettings.gridLayout": "グリッドレイアウト",
"splitGridSettings.gridSummary": "グリッドは {rows}x{cols} = {count} 枚の画像に分割されます",
"splitGridSettings.defaultPrompt": "既定のプロンプト",
"splitGridSettings.promptPlaceholder": "生成されるすべての画像に適用するプロンプトを入力...",
"splitGridSettings.promptHelp": "作成後、各プロンプトノードは個別に編集できます",
"splitGridSettings.generateNodeSettings": "生成ノード設定",
"splitGridSettings.createGenerateSets": "{count} 個の生成セットを作成",
"imageInput.upload": "画像をアップロード",
"imageInput.dropImage": "画像をドロップ",
"dropOverlay.workflow": "ドロップしてワークフローを読み込み",
"dropOverlay.node": "ドロップしてノードを作成",
"dropOverlay.audio": "音声をドロップしてノードを作成",
"dropOverlay.image": "画像をドロップしてノードを作成",
"dropOverlay.splittingImageGrid": "画像グリッドを分割中...",
"connectionMenu.addNode": "{type} ノードを追加",
"connectionMenu.type.image": "画像",
"connectionMenu.type.text": "テキスト",
"connectionMenu.type.audio": "音声",
"connectionMenu.type.video": "動画",
"connectionMenu.type.3d": "3D",
"connectionMenu.type.easeCurve": "設定",
"connectionMenu.splitGridNode": "グリッド分割ノード",
"connectionMenu.splitGridNow": "今すぐグリッド分割",
"connectionMenu.multiAngleImage": "画像マルチアングル",
"connectionMenu.navigate": "移動",
"connectionMenu.select": "選択",
"prompt.placeholder": "生成したい内容を入力...",
"prompt.connectedPlaceholder": "接続ノードからのテキスト(編集可)...",
"prompt.optionalPlaceholder": "任意のプロンプト(空ならスキップ)...",
"prompt.addVariable": "変数を追加",
"prompt.setVariableName": "変数名を設定",
"prompt.variableHelp": "このプロンプトを PromptConstructor ノードの変数として使用します",
"prompt.variableName": "変数名",
"prompt.variablePlaceholder": "例: color, style, subject",
"prompt.preview": "プレビュー:{value}",
"composer.promptProvidedByUpstream": "プロンプトは上流のテキストノードから提供されています。",
"composer.videoStitchClipCount": "{count} 本の動画クリップ",
"composer.videoStitchAudio": "音声接続済み",
"composer.videoStitchNoAudio": "音声なし",
"composer.videoStitchInputs": "動画入力",
"composer.videoStitchInputHint": "クリップ順序はノード上で調整",
"composer.videoStitchNeedTwo": "結合には動画クリップを 2 本以上接続してください。",
"composer.videoStitchClip": "クリップ {index}",
"composer.videoStitchLoop": "ループ",
"composer.videoStitchOutputReady": "出力準備完了",
"composer.videoStitchNoOutput": "出力はまだありません",
"composer.videoStitchReady": "現在のノードを結合できます",
"composer.videoStitchRun": "現在の動画ノードを結合",
"composer.easeCurveVideoConnected": "動画接続済み",
"composer.easeCurveNoVideo": "緩動曲線を適用するには動画入力を接続してください。",
"composer.easeCurveInherited": "継承設定",
"composer.easeCurveLocal": "ローカル設定",
"composer.easeCurveSettings": "曲線設定",
"composer.easeCurvePreset": "プリセット",
"composer.easeCurveCustom": "カスタムベジェ",
"composer.easeCurveHandles": "ベジェ制御点",
"composer.easeCurveInput": "入力",
"composer.easeCurveDuration": "出力時間",
"composer.easeCurveOutputReady": "出力準備完了",
"composer.easeCurveNoOutput": "出力はまだありません",
"composer.easeCurveReady": "現在の曲線を適用できます",
"composer.easeCurveRun": "現在の緩動曲線ノードを適用",
"shortcuts.title": "キーボードショートカット",
"shortcuts.general": "一般",
"shortcuts.addNodes": "ノード追加",
"shortcuts.layout": "レイアウト(先に 2 つ以上のノードを選択)",
"shortcuts.canvas": "キャンバス",
"shortcuts.runWorkflow": "ワークフローを実行",
"shortcuts.copyNodes": "選択ノードをコピー",
"shortcuts.paste": "ノード / 画像 / テキストを貼り付け",
"shortcuts.undo": "元に戻す",
"shortcuts.redo": "やり直し",
"shortcuts.showShortcuts": "ショートカットを表示",
"shortcuts.addPrompt": "プロンプトノードを追加",
"shortcuts.addImage": "画像入力ノードを追加",
"shortcuts.addGenerateImage": "画像生成ノードを追加",
"shortcuts.addGenerateVideo": "動画生成ノードを追加",
"shortcuts.addLLM": "LLM テキストノードを追加",
"shortcuts.addAnnotation": "注釈ノードを追加",
"shortcuts.addAudio": "音声ノードを追加",
"shortcuts.addVideoInput": "動画入力ノードを追加",
"shortcuts.addArray": "配列ノードを追加",
"shortcuts.stackVertical": "選択ノードを縦に並べる",
"shortcuts.stackHorizontal": "選択ノードを横に並べる",
"shortcuts.arrangeGrid": "選択ノードをグリッド配置",
"shortcuts.zoom": "ズームイン / アウト",
"shortcuts.pan": "パン(macOS)",
"shortcuts.delete": "選択ノードを削除",
"project.newProject": "新規プロジェクト",
"project.settings": "プロジェクト設定",
"project.tabProject": "プロジェクト",
"project.tabProviders": "プロバイダー",
"project.tabNodeDefaults": "ノード既定値",
"project.tabCanvas": "キャンバス",
"project.name": "プロジェクト名",
"project.directory": "プロジェクトディレクトリ",
"project.localFolderPlaceholder": "このデバイス上のローカルフォルダを選択",
"project.directoryHelp": "ワークフローファイルと画像はここに保存されます。inputs と generations のサブフォルダは自動作成されます。",
"project.embedImages": "画像を base64 として埋め込む",
"project.embedImagesDesc": "すべての画像をワークフローに埋め込みます。ファイルは大きくなり、非常に大きなワークフローではメモリ制限に達する場合があります。",
"project.inlineSettings": "ノード上にモデル設定を表示",
"project.inlineSettingsDesc": "生成ノード内にモデルパラメータを表示し、サイドパネルを使いません",
"project.envHelp": ".env.local に API キーを追加するとより安全です。ここで追加したキーは .env を上書きし、ブラウザに保存されます。",
"project.newapiwgDesc": "Popi 統合モデルゲートウェイ",
"project.baseUrl": "Base URL",
"project.systemImageDefault": "システム既定(Popi Models)",
"project.noneSetFirstUse": "未設定(初回使用時に選択)",
"project.defaultLLM": "既定の LLM 設定",
"project.systemLLMDefault": "システム既定値を使用(Popi Models Doubao Seed 2.0 Lite)",
"project.provider": "プロバイダー",
"project.model": "モデル",
"project.temp": "温度: {value}",
"project.tokens": "トークン: {value}",
"project.executionSettings": "実行設定",
"project.maxParallel": "最大並列呼び出し: {count}",
"project.executionHelp": "ワークフロー実行時に並列実行するノード数の上限です。値を上げると速くなる場合がありますが、API レート制限のリスクも上がります。",
"project.defaultsHelp": "これらの既定値はキーボードショートカット(Shift+G、Shift+L など)でノードを作成するときに適用されます。",
"project.canvasHelp": "キャンバスの移動と操作方法を設定します。",
"project.canvasAssistant": "キャンバスアシスタント",
"project.canvasAssistantShort": "アシスタント",
"project.panMode": "パンモード",
"project.panSpace": "Space を押しながらドラッグしてパン",
"project.panMiddle": "マウス中ボタンでクリックしてドラッグ",
"project.panAlways": "キーを押さずにパン",
"project.panSpaceLabel": "Space + ドラッグ",
"project.panMiddleLabel": "中ボタン",
"project.panAlwaysLabel": "常時オン",
"project.zoomMode": "ズームモード",
"project.zoomAlt": "Alt を押しながらスクロールでズーム",
"project.zoomCtrl": "Ctrl/Cmd を押しながらスクロールでズーム",
"project.zoomScroll": "修飾キーなしでスクロールズーム",
"project.zoomAltLabel": "Alt + スクロール",
"project.zoomCtrlLabel": "Ctrl + スクロール",
"project.zoomScrollLabel": "スクロール",
"project.selectionMode": "選択モード",
"project.selectClick": "クリックしてノードを選択",
"project.selectAlt": "Alt を押しながらドラッグして選択",
"project.selectShift": "Shift を押しながらドラッグして選択",
"project.selectClickLabel": "クリック",
"project.selectAltLabel": "Alt + ドラッグ",
"project.selectShiftLabel": "Shift + ドラッグ",
"project.validating": "検証中...",
"project.errorOpenDir": "ディレクトリ選択を開けませんでした",
"project.errorOpenDirWithReason": "ディレクトリ選択を開けませんでした: {error}",
"project.errorNameRequired": "プロジェクト名は必須です",
"project.errorDirectoryRequired": "プロジェクトディレクトリは必須です",
"project.errorChooseLocalFolder": "このデバイスに保存するため、ブラウザからローカルフォルダを選択してください。",
"project.errorAbsolutePath": "プロジェクトディレクトリは絶対パスである必要があります(/、ドライブ文字、UNC パスで始まる形式)",
"project.errorNotDirectory": "プロジェクトパスはディレクトリではありません",
"project.errorValidateDir": "ディレクトリ検証に失敗しました: {error}",
"modelSearch.search": "モデルを検索...",
"modelSearch.allProviders": "すべてのプロバイダー",
"modelSearch.all": "すべて",
"modelSearch.allTypes": "すべての種類",
"modelSearch.image": "画像",
"modelSearch.video": "動画",
"modelSearch.audio": "音声",
"modelSearch.refresh": "モデルとスキーマを更新",
"modelSearch.loading": "モデルを読み込み中...",
"modelSearch.tryAgain": "再試行",
"modelSearch.removeFallback": "フォールバックを削除",
"modelSearch.clearSelection": "現在の選択をクリア",
"modelSearch.noModels": "モデルが見つかりません",
"modelSearch.adjustFilters": "検索条件またはフィルターを調整してください",
"modelSearch.recent": "最近使用",
"promptWorkflow.title": "プロンプトでワークフロー作成",
"promptWorkflow.describe": "ワークフローを説明",
"promptWorkflow.placeholder": "例: 参考画像から一貫した照明とスタイルの商品写真を作成...",
"promptWorkflow.help": "ワークフローで実現したいことを説明してください。入力、出力、変換内容を具体的に書くと効果的です。",
"promptWorkflow.note": "注: この機能は現在 Gemini モデルでのみ動作します。",
"promptWorkflow.generating": "生成中...",
"promptWorkflow.generate": "ワークフローを生成",
"promptWorkflow.dismiss": "閉じる",
"promptWorkflow.validation": "ワークフローを説明してください(3 文字以上)",
"promptWorkflow.failed": "ワークフローの生成に失敗しました",
"workflowBrowser.noWorkflows": "ワークフローが見つかりません",
"workflowBrowser.noWorkflowsDesc": "このフォルダにはワークフロープロジェクトがありません",
"workflowBrowser.title": "ワークフロー",
"workflowBrowser.chooseFolderDesc": "ワークフロープロジェクトを含むフォルダを選択します。後で変更できます。",
"workflowBrowser.chooseFolder": "フォルダを選択",
"workflowBrowser.projectCount": "{count} 件のプロジェクト",
"workflowBrowser.openFromDirectory": "ディレクトリから開く",
"workflowBrowser.changeFolder": "フォルダを変更",
"workflowBrowser.justNow": "たった今",
"workflowBrowser.minutesAgo": "{count} 分前",
"workflowBrowser.hoursAgo": "{count} 時間前",
"workflowBrowser.daysAgo": "{count} 日前",
"workflowBrowser.monthsAgo": "{count} か月前",
"workflowBrowser.errorNoWorkflows": "このフォルダにワークフローが見つかりません",
"workflowBrowser.errorList": "ワークフロー一覧の取得に失敗しました",
"workflowBrowser.errorFetch": "ワークフローの取得に失敗しました",
"multiSelect.stackHorizontal": "横に並べる (H)",
"multiSelect.stackVertical": "縦に並べる (V)",
"multiSelect.arrangeGrid": "グリッド配置 (G)",
"multiSelect.removeGroup": "グループから削除",
"multiSelect.createGroup": "グループを作成",
"multiSelect.downloadZip": "画像を ZIP でダウンロード",
"cost.viewDetails": "コスト詳細を表示",
};
const dictionaries: Record<Language, Dictionary> = {
en,
"zh-CN": zhCN,
"zh-TW": zhTW,
ja,
};
function detectLanguage(): Language {
if (typeof navigator === "undefined") return "en";
const language = navigator.language.toLowerCase();
if (language.startsWith("ja")) return "ja";
if (language.includes("tw") || language.includes("hk") || language.includes("hant")) return "zh-TW";
if (language.startsWith("zh")) return "zh-CN";
return "en";
}
function interpolate(text: string, values?: Record<string, string | number>) {
if (!values) return text;
return text.replace(/\{(\w+)\}/g, (_, key) => String(values[key] ?? `{${key}}`));
}
interface I18nContextValue {
language: Language;
setLanguage: (language: Language) => void;
t: (key: TranslationKey, values?: Record<string, string | number>) => string;
}
const I18nContext = createContext<I18nContextValue | null>(null);
export function I18nProvider({ children }: { children: React.ReactNode }) {
const [language, setLanguageState] = useState<Language>("en");
useEffect(() => {
const stored = window.localStorage.getItem(STORAGE_KEY) as Language | null;
setLanguageState(stored && stored in dictionaries ? stored : detectLanguage());
}, []);
useEffect(() => {
document.documentElement.lang = language;
window.localStorage.setItem(STORAGE_KEY, language);
}, [language]);
const value = useMemo<I18nContextValue>(() => ({
language,
setLanguage: setLanguageState,
t: (key, values) => interpolate(dictionaries[language][key] ?? en[key], values),
}), [language]);
return <I18nContext.Provider value={value}>{children}</I18nContext.Provider>;
}
export function useI18n() {
const context = useContext(I18nContext);
return context ?? {
language: "en",
setLanguage: () => {},
t: (key, values) => interpolate(en[key], values),
};
}