diff --git a/.github/actions/start-comfyui-server/action.yml b/.github/actions/start-comfyui-server/action.yml new file mode 100644 index 000000000..2af727508 --- /dev/null +++ b/.github/actions/start-comfyui-server/action.yml @@ -0,0 +1,23 @@ +name: Start ComfyUI Server +description: 'Start ComfyUI server in a container environment (assumes ComfyUI is pre-installed)' + +inputs: + front_end_root: + description: 'Path to frontend dist directory' + required: false + default: '$GITHUB_WORKSPACE/dist' + timeout: + description: 'Timeout in seconds for server startup' + required: false + default: '600' + +runs: + using: 'composite' + steps: + - name: Copy devtools and start server + shell: bash + run: | + set -euo pipefail + cp -r ./tools/devtools/* /ComfyUI/custom_nodes/ComfyUI_devtools/ + cd /ComfyUI && python3 main.py --cpu --multi-user --front-end-root "${{ inputs.front_end_root }}" & + wait-for-it --service 127.0.0.1:8188 -t ${{ inputs.timeout }} diff --git a/.github/workflows/ci-tests-e2e.yaml b/.github/workflows/ci-tests-e2e.yaml index 5a2cc028b..12ccfae93 100644 --- a/.github/workflows/ci-tests-e2e.yaml +++ b/.github/workflows/ci-tests-e2e.yaml @@ -15,66 +15,56 @@ concurrency: jobs: setup: runs-on: ubuntu-latest - outputs: - cache-key: ${{ steps.cache-key.outputs.key }} steps: - name: Checkout repository uses: actions/checkout@v5 - - # Setup Test Environment, build frontend but do not start server yet - - name: Setup ComfyUI server - uses: ./.github/actions/setup-comfyui-server - name: Setup frontend uses: ./.github/actions/setup-frontend with: include_build_step: true - - name: Setup Playwright - uses: ./.github/actions/setup-playwright # Setup Playwright and cache browsers - # Save the entire workspace as cache for later test jobs to restore - - name: Generate cache key - id: cache-key - run: echo "key=$(date +%s)" >> $GITHUB_OUTPUT - - name: Save cache - uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 + # Upload only built dist/ (containerized test jobs will pnpm install without cache) + - name: Upload built frontend + uses: actions/upload-artifact@v4 with: - path: . - key: comfyui-setup-${{ steps.cache-key.outputs.key }} + name: frontend-dist + path: dist/ + retention-days: 1 # Sharded chromium tests playwright-tests-chromium-sharded: needs: setup runs-on: ubuntu-latest timeout-minutes: 60 + container: + image: ghcr.io/comfy-org/comfyui-ci-container:0.0.8 + credentials: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} permissions: contents: read + packages: read strategy: fail-fast: false matrix: shardIndex: [1, 2, 3, 4, 5, 6, 7, 8] shardTotal: [8] steps: - # download built frontend repo from setup job - - name: Wait for cache propagation - run: sleep 10 - - name: Restore cached setup - uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 + - name: Checkout repository + uses: actions/checkout@v5 + - name: Download built frontend + uses: actions/download-artifact@v4 with: - fail-on-cache-miss: true - path: . - key: comfyui-setup-${{ needs.setup.outputs.cache-key }} + name: frontend-dist + path: dist/ - # Setup Test Environment for this runner, start server, use cached built frontend ./dist from 'setup' job - - name: Setup ComfyUI server - uses: ./.github/actions/setup-comfyui-server - with: - launch_server: true - - name: Setup nodejs, pnpm, reuse built frontend - uses: ./.github/actions/setup-frontend - - name: Setup Playwright - uses: ./.github/actions/setup-playwright + - name: Start ComfyUI server + uses: ./.github/actions/start-comfyui-server - # Run sharded tests and upload sharded reports + - name: Install frontend deps + run: pnpm install --frozen-lockfile + + # Run sharded tests (browsers pre-installed in container) - name: Run Playwright tests (Shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}) id: playwright run: pnpm exec playwright test --project=chromium --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} --reporter=blob @@ -94,39 +84,37 @@ jobs: timeout-minutes: 15 needs: setup runs-on: ubuntu-latest + container: + image: ghcr.io/comfy-org/comfyui-ci-container:0.0.8 + credentials: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} permissions: contents: read + packages: read strategy: fail-fast: false matrix: browser: [chromium-2x, chromium-0.5x, mobile-chrome] steps: - # download built frontend repo from setup job - - name: Wait for cache propagation - run: sleep 10 - - name: Restore cached setup - uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 + - name: Checkout repository + uses: actions/checkout@v5 + - name: Download built frontend + uses: actions/download-artifact@v4 with: - fail-on-cache-miss: true - path: . - key: comfyui-setup-${{ needs.setup.outputs.cache-key }} + name: frontend-dist + path: dist/ - # Setup Test Environment for this runner, start server, use cached built frontend ./dist from 'setup' job - - name: Setup ComfyUI server - uses: ./.github/actions/setup-comfyui-server - with: - launch_server: true - - name: Setup nodejs, pnpm, reuse built frontend - uses: ./.github/actions/setup-frontend - - name: Setup Playwright - uses: ./.github/actions/setup-playwright + - name: Start ComfyUI server + uses: ./.github/actions/start-comfyui-server - # Run tests and upload reports + - name: Install frontend deps + run: pnpm install --frozen-lockfile + + # Run tests (browsers pre-installed in container) - name: Run Playwright tests (${{ matrix.browser }}) id: playwright - run: | - # Run tests with blob reporter first - pnpm exec playwright test --project=${{ matrix.browser }} --reporter=blob + run: pnpm exec playwright test --project=${{ matrix.browser }} --reporter=blob env: PLAYWRIGHT_BLOB_OUTPUT_DIR: ./blob-report @@ -147,7 +135,7 @@ jobs: path: ./playwright-report/ retention-days: 30 - # Merge sharded test reports + # Merge sharded test reports (no container needed - only runs CLI) merge-reports: needs: [playwright-tests-chromium-sharded] runs-on: ubuntu-latest @@ -156,11 +144,9 @@ jobs: - name: Checkout repository uses: actions/checkout@v5 - # Setup Test Environment, we only need playwright to merge reports + # Setup pnpm/node to run playwright merge-reports (no browsers needed) - name: Setup frontend uses: ./.github/actions/setup-frontend - - name: Setup Playwright - uses: ./.github/actions/setup-playwright - name: Download blob reports uses: actions/download-artifact@v4 diff --git a/.github/workflows/pr-update-playwright-expectations.yaml b/.github/workflows/pr-update-playwright-expectations.yaml index d78ad96bf..e1c51c546 100644 --- a/.github/workflows/pr-update-playwright-expectations.yaml +++ b/.github/workflows/pr-update-playwright-expectations.yaml @@ -25,7 +25,6 @@ jobs: ) && startsWith(github.event.comment.body, '/update-playwright') ) outputs: - cache-key: ${{ steps.cache-key.outputs.key }} pr-number: ${{ steps.pr-info.outputs.pr-number }} branch: ${{ steps.pr-info.outputs.branch }} comment-id: ${{ steps.find-update-comment.outputs.comment-id }} @@ -64,70 +63,63 @@ jobs: uses: ./.github/actions/setup-frontend with: include_build_step: true - # Save expensive build artifacts (Python env, built frontend, node_modules) - # Source code will be checked out fresh in sharded jobs - - name: Generate cache key - id: cache-key - run: echo "key=$(date +%s)" >> $GITHUB_OUTPUT - - name: Save cache - uses: actions/cache/save@5a3ec84eff668545956fd18022155c47e93e2684 + + # Upload built dist/ (containerized test jobs will pnpm install without cache) + - name: Upload built frontend + uses: actions/upload-artifact@v4 with: - path: | - ComfyUI - dist - key: comfyui-setup-${{ steps.cache-key.outputs.key }} + name: frontend-dist + path: dist/ + retention-days: 1 # Sharded snapshot updates update-snapshots-sharded: needs: setup runs-on: ubuntu-latest + container: + image: ghcr.io/comfy-org/comfyui-ci-container:0.0.8 + credentials: + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + permissions: + contents: read + packages: read strategy: fail-fast: false matrix: shardIndex: [1, 2, 3, 4] shardTotal: [4] steps: - # Checkout source code fresh (not cached) - name: Checkout repository uses: actions/checkout@v5 with: ref: ${{ needs.setup.outputs.branch }} - - # Restore expensive build artifacts from setup job - - name: Restore cached artifacts - uses: actions/cache/restore@5a3ec84eff668545956fd18022155c47e93e2684 + - name: Download built frontend + uses: actions/download-artifact@v4 with: - fail-on-cache-miss: true - path: | - ComfyUI - dist - key: comfyui-setup-${{ needs.setup.outputs.cache-key }} + name: frontend-dist + path: dist/ - - name: Setup ComfyUI server (from cache) - uses: ./.github/actions/setup-comfyui-server - with: - launch_server: true + - name: Start ComfyUI server + uses: ./.github/actions/start-comfyui-server - - name: Setup nodejs, pnpm, reuse built frontend - uses: ./.github/actions/setup-frontend + - name: Install frontend deps + run: pnpm install --frozen-lockfile - - name: Setup Playwright - uses: ./.github/actions/setup-playwright - - # Run sharded tests with snapshot updates + # Run sharded tests with snapshot updates (browsers pre-installed in container) - name: Update snapshots (Shard ${{ matrix.shardIndex }}/${{ matrix.shardTotal }}) id: playwright-tests run: pnpm exec playwright test --update-snapshots --shard=${{ matrix.shardIndex }}/${{ matrix.shardTotal }} continue-on-error: true - # Identify and stage only changed snapshot files - name: Stage changed snapshot files id: changed-snapshots + shell: bash run: | set -euo pipefail - echo "==========================================" - echo "STAGING CHANGED SNAPSHOTS (Shard ${{ matrix.shardIndex }})" - echo "==========================================" + + # Configure git safe.directory for container environment + git config --global --add safe.directory "$(pwd)" # Get list of changed snapshot files (including untracked/new files) changed_files=$( ( @@ -136,43 +128,25 @@ jobs: ) | sort -u | grep -E '\-snapshots/' || true ) if [ -z "$changed_files" ]; then - echo "No snapshot changes in this shard" + echo "No snapshot changes in shard ${{ matrix.shardIndex }}" echo "has-changes=false" >> $GITHUB_OUTPUT exit 0 fi - echo "✓ Found changed files:" - echo "$changed_files" file_count=$(echo "$changed_files" | wc -l) - echo "Count: $file_count" + echo "Shard ${{ matrix.shardIndex }}: $file_count changed snapshot(s):" + echo "$changed_files" echo "has-changes=true" >> $GITHUB_OUTPUT - echo "" - # Create staging directory + # Copy changed files to staging directory mkdir -p /tmp/changed_snapshots_shard - - # Copy only changed files, preserving directory structure - # Strip 'browser_tests/' prefix to avoid double nesting - echo "Copying changed files to staging directory..." while IFS= read -r file; do - # Skip paths that no longer exist (e.g. deletions) - if [ ! -f "$file" ]; then - echo " → (skipped; not a file) $file" - continue - fi - # Remove 'browser_tests/' prefix + [ -f "$file" ] || continue file_without_prefix="${file#browser_tests/}" - # Create parent directories mkdir -p "/tmp/changed_snapshots_shard/$(dirname "$file_without_prefix")" - # Copy file cp "$file" "/tmp/changed_snapshots_shard/$file_without_prefix" - echo " → $file_without_prefix" done <<< "$changed_files" - echo "" - echo "Staged files for upload:" - find /tmp/changed_snapshots_shard -type f - # Upload ONLY the changed files from this shard - name: Upload changed snapshots uses: actions/upload-artifact@v4 @@ -213,9 +187,15 @@ jobs: echo "==========================================" echo "DOWNLOADED SNAPSHOT FILES" echo "==========================================" - find ./downloaded-snapshots -type f - echo "" - echo "Total files: $(find ./downloaded-snapshots -type f | wc -l)" + if [ -d "./downloaded-snapshots" ]; then + find ./downloaded-snapshots -type f + echo "" + echo "Total files: $(find ./downloaded-snapshots -type f | wc -l)" + else + echo "No snapshot artifacts downloaded (no changes in any shard)" + echo "" + echo "Total files: 0" + fi # Merge only the changed files into browser_tests - name: Merge changed snapshots @@ -226,6 +206,16 @@ jobs: echo "MERGING CHANGED SNAPSHOTS" echo "==========================================" + # Check if any artifacts were downloaded + if [ ! -d "./downloaded-snapshots" ]; then + echo "No snapshot artifacts to merge" + echo "==========================================" + echo "MERGE COMPLETE" + echo "==========================================" + echo "Shards merged: 0" + exit 0 + fi + # Verify target directory exists if [ ! -d "browser_tests" ]; then echo "::error::Target directory 'browser_tests' does not exist" diff --git a/THIRD_PARTY_NOTICES.md b/THIRD_PARTY_NOTICES.md new file mode 100644 index 000000000..ff6a1191d --- /dev/null +++ b/THIRD_PARTY_NOTICES.md @@ -0,0 +1 @@ +AMD and the AMD Arrow logo are trademarks of Advanced Micro Devices, Inc. \ No newline at end of file diff --git a/apps/desktop-ui/package.json b/apps/desktop-ui/package.json index a3d36f1a5..ed65e99a5 100644 --- a/apps/desktop-ui/package.json +++ b/apps/desktop-ui/package.json @@ -1,6 +1,6 @@ { "name": "@comfyorg/desktop-ui", - "version": "0.0.4", + "version": "0.0.6", "type": "module", "nx": { "tags": [ diff --git a/apps/desktop-ui/public/assets/images/amd-rocm-logo.png b/apps/desktop-ui/public/assets/images/amd-rocm-logo.png new file mode 100644 index 000000000..82de495cd Binary files /dev/null and b/apps/desktop-ui/public/assets/images/amd-rocm-logo.png differ diff --git a/apps/desktop-ui/src/components/install/GpuPicker.stories.ts b/apps/desktop-ui/src/components/install/GpuPicker.stories.ts new file mode 100644 index 000000000..d49893c38 --- /dev/null +++ b/apps/desktop-ui/src/components/install/GpuPicker.stories.ts @@ -0,0 +1,84 @@ +// eslint-disable-next-line storybook/no-renderer-packages +import type { Meta, StoryObj } from '@storybook/vue3' +import type { + ElectronAPI, + TorchDeviceType +} from '@comfyorg/comfyui-electron-types' +import { ref } from 'vue' + +import GpuPicker from './GpuPicker.vue' + +type Platform = ReturnType +type ElectronAPIStub = Pick +type WindowWithElectron = Window & { electronAPI?: ElectronAPIStub } + +const meta: Meta = { + title: 'Desktop/Components/GpuPicker', + component: GpuPicker, + parameters: { + layout: 'padded', + backgrounds: { + default: 'dark', + values: [ + { name: 'dark', value: '#0a0a0a' }, + { name: 'neutral-900', value: '#171717' }, + { name: 'neutral-950', value: '#0a0a0a' } + ] + } + } +} + +export default meta +type Story = StoryObj + +function createElectronDecorator(platform: Platform) { + function getPlatform() { + return platform + } + + return function ElectronDecorator() { + const windowWithElectron = window as WindowWithElectron + windowWithElectron.electronAPI = { getPlatform } + return { template: '' } + } +} + +function renderWithDevice(device: TorchDeviceType | null) { + return function Render() { + return { + components: { GpuPicker }, + setup() { + const selected = ref(device) + return { selected } + }, + template: ` +
+ +
+ ` + } + } +} + +const windowsDecorator = createElectronDecorator('win32') +const macDecorator = createElectronDecorator('darwin') + +export const WindowsNvidiaSelected: Story = { + decorators: [windowsDecorator], + render: renderWithDevice('nvidia') +} + +export const WindowsAmdSelected: Story = { + decorators: [windowsDecorator], + render: renderWithDevice('amd') +} + +export const WindowsCpuSelected: Story = { + decorators: [windowsDecorator], + render: renderWithDevice('cpu') +} + +export const MacMpsSelected: Story = { + decorators: [macDecorator], + render: renderWithDevice('mps') +} diff --git a/apps/desktop-ui/src/components/install/GpuPicker.vue b/apps/desktop-ui/src/components/install/GpuPicker.vue index 98dddb762..217e99ce5 100644 --- a/apps/desktop-ui/src/components/install/GpuPicker.vue +++ b/apps/desktop-ui/src/components/install/GpuPicker.vue @@ -11,29 +11,32 @@ - + @@ -41,7 +44,6 @@ @@ -81,13 +83,15 @@ const selected = defineModel('device', { const electron = electronAPI() const platform = electron.getPlatform() -const showRecommendedBadge = computed( - () => selected.value === 'mps' || selected.value === 'nvidia' +const recommendedDevices: TorchDeviceType[] = ['mps', 'nvidia', 'amd'] +const showRecommendedBadge = computed(() => + selected.value ? recommendedDevices.includes(selected.value) : false ) const descriptionKeys = { mps: 'appleMetal', nvidia: 'nvidia', + amd: 'amd', cpu: 'cpu', unsupported: 'manual' } as const @@ -97,7 +101,7 @@ const descriptionText = computed(() => { return st(`install.gpuPicker.${key}Description`, '') }) -const pickGpu = (value: TorchDeviceType) => { +function pickGpu(value: TorchDeviceType) { selected.value = value } diff --git a/apps/desktop-ui/src/components/install/HardwareOption.stories.ts b/apps/desktop-ui/src/components/install/HardwareOption.stories.ts index d830af49f..fc0e56713 100644 --- a/apps/desktop-ui/src/components/install/HardwareOption.stories.ts +++ b/apps/desktop-ui/src/components/install/HardwareOption.stories.ts @@ -29,7 +29,6 @@ export const AppleMetalSelected: Story = { imagePath: '/assets/images/apple-mps-logo.png', placeholderText: 'Apple Metal', subtitle: 'Apple Metal', - value: 'mps', selected: true } } @@ -39,7 +38,6 @@ export const AppleMetalUnselected: Story = { imagePath: '/assets/images/apple-mps-logo.png', placeholderText: 'Apple Metal', subtitle: 'Apple Metal', - value: 'mps', selected: false } } @@ -48,7 +46,6 @@ export const CPUOption: Story = { args: { placeholderText: 'CPU', subtitle: 'Subtitle', - value: 'cpu', selected: false } } @@ -57,7 +54,6 @@ export const ManualInstall: Story = { args: { placeholderText: 'Manual Install', subtitle: 'Subtitle', - value: 'unsupported', selected: false } } @@ -67,7 +63,6 @@ export const NvidiaSelected: Story = { imagePath: '/assets/images/nvidia-logo-square.jpg', placeholderText: 'NVIDIA', subtitle: 'NVIDIA', - value: 'nvidia', selected: true } } diff --git a/apps/desktop-ui/src/components/install/HardwareOption.vue b/apps/desktop-ui/src/components/install/HardwareOption.vue index ae254fd8f..9acc9e79c 100644 --- a/apps/desktop-ui/src/components/install/HardwareOption.vue +++ b/apps/desktop-ui/src/components/install/HardwareOption.vue @@ -36,17 +36,13 @@ diff --git a/src/components/MenuHamburger.vue b/src/components/MenuHamburger.vue index ab914f667..fa99e032c 100644 --- a/src/components/MenuHamburger.vue +++ b/src/components/MenuHamburger.vue @@ -5,23 +5,23 @@ >
diff --git a/src/components/load3d/controls/CameraControls.vue b/src/components/load3d/controls/CameraControls.vue index fb2d153b7..85ab914d8 100644 --- a/src/components/load3d/controls/CameraControls.vue +++ b/src/components/load3d/controls/CameraControls.vue @@ -1,13 +1,17 @@ diff --git a/src/components/ui/button/button.variants.ts b/src/components/ui/button/button.variants.ts index 6aefda90e..2d36d17b6 100644 --- a/src/components/ui/button/button.variants.ts +++ b/src/components/ui/button/button.variants.ts @@ -16,7 +16,9 @@ export const buttonVariants = cva({ textonly: 'text-base-foreground bg-transparent hover:bg-secondary-background-hover', 'muted-textonly': - 'text-muted-foreground bg-transparent hover:bg-secondary-background-hover' + 'text-muted-foreground bg-transparent hover:bg-secondary-background-hover', + 'destructive-textonly': + 'text-destructive-background bg-transparent hover:bg-destructive-background/10' }, size: { sm: 'h-6 rounded-sm px-2 py-1 text-xs', @@ -41,7 +43,8 @@ const variants = [ 'inverted', 'destructive', 'textonly', - 'muted-textonly' + 'muted-textonly', + 'destructive-textonly' ] as const satisfies Array const sizes = ['sm', 'md', 'lg', 'icon', 'icon-sm'] as const satisfies Array< ButtonVariants['size'] diff --git a/tests-ui/tests/composables/canvas/useSelectedLiteGraphItems.test.ts b/src/composables/canvas/useSelectedLiteGraphItems.test.ts similarity index 98% rename from tests-ui/tests/composables/canvas/useSelectedLiteGraphItems.test.ts rename to src/composables/canvas/useSelectedLiteGraphItems.test.ts index 303dddc08..23e1e8dd3 100644 --- a/tests-ui/tests/composables/canvas/useSelectedLiteGraphItems.test.ts +++ b/src/composables/canvas/useSelectedLiteGraphItems.test.ts @@ -2,12 +2,8 @@ import { createPinia, setActivePinia } from 'pinia' import { beforeEach, describe, expect, it, vi } from 'vitest' import { useSelectedLiteGraphItems } from '@/composables/canvas/useSelectedLiteGraphItems' -import type { LGraphNode } from '@/lib/litegraph/src/litegraph' -import { - LGraphEventMode, - type Positionable, - Reroute -} from '@/lib/litegraph/src/litegraph' +import type { LGraphNode, Positionable } from '@/lib/litegraph/src/litegraph' +import { LGraphEventMode, Reroute } from '@/lib/litegraph/src/litegraph' import { useCanvasStore } from '@/renderer/core/canvas/canvasStore' import { app } from '@/scripts/app' diff --git a/tests-ui/tests/composables/functional/useChainCallback.test.ts b/src/composables/functional/useChainCallback.test.ts similarity index 100% rename from tests-ui/tests/composables/functional/useChainCallback.test.ts rename to src/composables/functional/useChainCallback.test.ts diff --git a/src/composables/graph/useGraphNodeManager.ts b/src/composables/graph/useGraphNodeManager.ts index 4482f9433..a7755afa6 100644 --- a/src/composables/graph/useGraphNodeManager.ts +++ b/src/composables/graph/useGraphNodeManager.ts @@ -34,6 +34,7 @@ import type { } from '@/lib/litegraph/src/litegraph' import type { TitleMode } from '@/lib/litegraph/src/types/globalEnums' import { NodeSlotType } from '@/lib/litegraph/src/types/globalEnums' +import { app } from '@/scripts/app' export interface WidgetSlotMetadata { index: number @@ -47,6 +48,7 @@ export interface SafeWidgetData { borderStyle?: string callback?: ((value: unknown) => void) | undefined controlWidget?: SafeControlWidget + hasLayoutSize?: boolean isDOMWidget?: boolean label?: string nodeType?: string @@ -171,7 +173,12 @@ export function safeWidgetMapper( const callback = (v: unknown) => { const value = normalizeWidgetValue(v) widget.value = value ?? undefined - widget.callback?.(value) + // Match litegraph callback signature: (value, canvas, node, pos, event) + // Some extensions (e.g., Impact Pack) expect node as the 3rd parameter + widget.callback?.(value, app.canvas, node) + // Trigger redraw for all legacy widgets on this node (e.g., mask preview) + // This ensures widgets that depend on other widget values get updated + node.widgets?.forEach((w) => w.triggerDraw?.()) } return { @@ -181,6 +188,7 @@ export function safeWidgetMapper( borderStyle, callback, controlWidget: getControlWidget(widget), + hasLayoutSize: typeof widget.computeLayoutSize === 'function', isDOMWidget: isDOMWidget(widget), label: widget.label, nodeType: getNodeType(node, widget), diff --git a/tests-ui/tests/composables/graph/useSelectionState.test.ts b/src/composables/graph/useSelectionState.test.ts similarity index 100% rename from tests-ui/tests/composables/graph/useSelectionState.test.ts rename to src/composables/graph/useSelectionState.test.ts diff --git a/tests-ui/tests/composables/maskeditor/useCanvasHistory.test.ts b/src/composables/maskeditor/useCanvasHistory.test.ts similarity index 99% rename from tests-ui/tests/composables/maskeditor/useCanvasHistory.test.ts rename to src/composables/maskeditor/useCanvasHistory.test.ts index 0bff43669..587b0347d 100644 --- a/tests-ui/tests/composables/maskeditor/useCanvasHistory.test.ts +++ b/src/composables/maskeditor/useCanvasHistory.test.ts @@ -43,7 +43,7 @@ describe('useCanvasHistory', () => { return rafCallCount } ) - vi.spyOn(window, 'alert').mockImplementation(() => {}) + vi.stubGlobal('alert', () => {}) const createMockImageData = () => { return { diff --git a/tests-ui/tests/composables/maskeditor/useCanvasManager.test.ts b/src/composables/maskeditor/useCanvasManager.test.ts similarity index 100% rename from tests-ui/tests/composables/maskeditor/useCanvasManager.test.ts rename to src/composables/maskeditor/useCanvasManager.test.ts diff --git a/tests-ui/tests/composables/maskeditor/useCanvasTools.test.ts b/src/composables/maskeditor/useCanvasTools.test.ts similarity index 100% rename from tests-ui/tests/composables/maskeditor/useCanvasTools.test.ts rename to src/composables/maskeditor/useCanvasTools.test.ts diff --git a/tests-ui/tests/composables/maskeditor/useImageLoader.test.ts b/src/composables/maskeditor/useImageLoader.test.ts similarity index 100% rename from tests-ui/tests/composables/maskeditor/useImageLoader.test.ts rename to src/composables/maskeditor/useImageLoader.test.ts diff --git a/src/composables/maskeditor/useMaskEditorLoader.ts b/src/composables/maskeditor/useMaskEditorLoader.ts index 01aaaf0e3..74d39a5a2 100644 --- a/src/composables/maskeditor/useMaskEditorLoader.ts +++ b/src/composables/maskeditor/useMaskEditorLoader.ts @@ -104,7 +104,8 @@ export function useMaskEditorLoader() { // If we have a widget filename, we should prioritize it over the node image // because the node image might be stale (e.g. from a previous save) // while the widget value reflects the current selection. - if (widgetFilename) { + // Skip internal reference formats (e.g. "$35-0" used by some plugins like Impact-Pack) + if (widgetFilename && !widgetFilename.startsWith('$')) { try { // Parse the widget value which might be in format "subfolder/filename [type]" or just "filename" let filename = widgetFilename diff --git a/tests-ui/tests/composables/node/useNodePricing.test.ts b/src/composables/node/useNodePricing.test.ts similarity index 100% rename from tests-ui/tests/composables/node/useNodePricing.test.ts rename to src/composables/node/useNodePricing.test.ts diff --git a/tests-ui/tests/composables/node/useCreditsBadge.test.ts b/src/composables/node/usePriceBadge.test.ts similarity index 95% rename from tests-ui/tests/composables/node/useCreditsBadge.test.ts rename to src/composables/node/usePriceBadge.test.ts index eb894566a..d646dd962 100644 --- a/tests-ui/tests/composables/node/useCreditsBadge.test.ts +++ b/src/composables/node/usePriceBadge.test.ts @@ -2,7 +2,7 @@ import { describe, expect, vi } from 'vitest' import { LGraphNode } from '@/lib/litegraph/src/litegraph' -import { subgraphTest } from '../../litegraph/subgraph/fixtures/subgraphFixtures' +import { subgraphTest } from '@/lib/litegraph/src/subgraph/__fixtures__/subgraphFixtures' import { usePriceBadge } from '@/composables/node/usePriceBadge' diff --git a/tests-ui/tests/composables/useWatchWidget.test.ts b/src/composables/node/useWatchWidget.test.ts similarity index 100% rename from tests-ui/tests/composables/useWatchWidget.test.ts rename to src/composables/node/useWatchWidget.test.ts diff --git a/tests-ui/tests/composables/useCompletionSummary.test.ts b/src/composables/queue/useCompletionSummary.test.ts similarity index 100% rename from tests-ui/tests/composables/useCompletionSummary.test.ts rename to src/composables/queue/useCompletionSummary.test.ts diff --git a/tests-ui/tests/composables/useJobList.test.ts b/src/composables/queue/useJobList.test.ts similarity index 88% rename from tests-ui/tests/composables/useJobList.test.ts rename to src/composables/queue/useJobList.test.ts index 36a14162b..2e453bcf1 100644 --- a/tests-ui/tests/composables/useJobList.test.ts +++ b/src/composables/queue/useJobList.test.ts @@ -5,6 +5,9 @@ import type { Ref } from 'vue' import { useJobList } from '@/composables/queue/useJobList' import type { JobState } from '@/types/queue' +import { buildJobDisplay } from '@/utils/queueDisplay' +import type { BuildJobDisplayCtx } from '@/utils/queueDisplay' +import type { TaskItemImpl } from '@/stores/queueStore' type TestTask = { promptId: string @@ -43,19 +46,8 @@ vi.mock('vue-i18n', () => ({ } })) -let stMock: ReturnType -const ensureStMock = () => { - if (!stMock) { - stMock = vi.fn( - (key: string, fallback?: string) => `i18n(${key})-${fallback}` - ) - } - return stMock -} vi.mock('@/i18n', () => ({ - st: (...args: any[]) => { - return ensureStMock()(...args) - } + st: vi.fn((key: string, fallback?: string) => `i18n(${key})-${fallback}`) })) let totalPercent: Ref @@ -75,40 +67,24 @@ vi.mock('@/composables/queue/useQueueProgress', () => ({ } })) -let buildJobDisplayMock: ReturnType -const ensureBuildDisplayMock = () => { - if (!buildJobDisplayMock) { - buildJobDisplayMock = vi.fn((task: any, state: JobState, options: any) => ({ +vi.mock('@/utils/queueDisplay', () => ({ + buildJobDisplay: vi.fn( + (task: TaskItemImpl, state: JobState, options: BuildJobDisplayCtx) => ({ primary: `Job ${task.promptId}`, secondary: `${state} meta`, iconName: `${state}-icon`, iconImageUrl: undefined, showClear: state === 'failed', options - })) - } - return buildJobDisplayMock -} -vi.mock('@/utils/queueDisplay', () => ({ - buildJobDisplay: (...args: any[]) => { - return ensureBuildDisplayMock()(...args) - } + }) + ) })) -let jobStateFromTaskMock: ReturnType -const ensureJobStateMock = () => { - if (!jobStateFromTaskMock) { - jobStateFromTaskMock = vi.fn( - (task: TestTask, isInitializing?: boolean): JobState => - task.mockState ?? (isInitializing ? 'running' : 'completed') - ) - } - return jobStateFromTaskMock -} vi.mock('@/utils/queueUtil', () => ({ - jobStateFromTask: (...args: any[]) => { - return ensureJobStateMock()(...args) - } + jobStateFromTask: vi.fn( + (task: TestTask, isInitializing?: boolean): JobState => + task.mockState ?? (isInitializing ? 'running' : 'completed') + ) })) let queueStoreMock: { @@ -137,7 +113,7 @@ let executionStoreMock: { executingNode: null | { title?: string; type?: string } isPromptInitializing: (promptId?: string | number) => boolean } -let isPromptInitializingMock: ReturnType +let isPromptInitializingMock: (promptId?: string | number) => boolean const ensureExecutionStore = () => { if (!isPromptInitializingMock) { isPromptInitializingMock = vi.fn(() => false) @@ -221,13 +197,9 @@ const resetStores = () => { localeRef.value = 'en-US' tMock.mockClear() - if (stMock) stMock.mockClear() - if (buildJobDisplayMock) buildJobDisplayMock.mockClear() - if (jobStateFromTaskMock) jobStateFromTaskMock.mockClear() - if (isPromptInitializingMock) { - isPromptInitializingMock.mockReset() - isPromptInitializingMock.mockReturnValue(false) + vi.mocked(isPromptInitializingMock).mockReset() + vi.mocked(isPromptInitializingMock).mockReturnValue(false) } } @@ -240,6 +212,7 @@ describe('useJobList', () => { let api: ReturnType | null = null beforeEach(() => { + vi.resetAllMocks() resetStores() wrapper?.unmount() wrapper = null @@ -270,18 +243,18 @@ describe('useJobList', () => { await flush() jobItems.value - expect(buildJobDisplayMock).toHaveBeenCalledWith( + expect(buildJobDisplay).toHaveBeenCalledWith( expect.anything(), 'pending', expect.objectContaining({ showAddedHint: true }) ) - buildJobDisplayMock.mockClear() + vi.mocked(buildJobDisplay).mockClear() await vi.advanceTimersByTimeAsync(3000) await flush() jobItems.value - expect(buildJobDisplayMock).toHaveBeenCalledWith( + expect(buildJobDisplay).toHaveBeenCalledWith( expect.anything(), 'pending', expect.objectContaining({ showAddedHint: false }) @@ -303,13 +276,13 @@ describe('useJobList', () => { await flush() expect(vi.getTimerCount()).toBe(0) - buildJobDisplayMock.mockClear() + vi.mocked(buildJobDisplay).mockClear() queueStoreMock.pendingTasks = [ createTask({ promptId: taskId, queueIndex: 2, mockState: 'pending' }) ] await flush() jobItems.value - expect(buildJobDisplayMock).toHaveBeenCalledWith( + expect(buildJobDisplay).toHaveBeenCalledWith( expect.anything(), 'pending', expect.objectContaining({ showAddedHint: true }) diff --git a/tests-ui/tests/composables/useJobMenu.test.ts b/src/composables/queue/useJobMenu.test.ts similarity index 99% rename from tests-ui/tests/composables/useJobMenu.test.ts rename to src/composables/queue/useJobMenu.test.ts index 0bd876951..ff4100918 100644 --- a/tests-ui/tests/composables/useJobMenu.test.ts +++ b/src/composables/queue/useJobMenu.test.ts @@ -284,7 +284,7 @@ describe('useJobMenu', () => { await nextTick() const entry = findActionEntry(jobMenuEntries.value, 'report-error') - entry?.onClick?.() + void entry?.onClick?.() expect(dialogServiceMock.showExecutionErrorDialog).toHaveBeenCalledWith( error @@ -460,7 +460,7 @@ describe('useJobMenu', () => { await nextTick() const entry = findActionEntry(jobMenuEntries.value, 'download') - entry?.onClick?.() + void entry?.onClick?.() expect(downloadFileMock).toHaveBeenCalledWith('https://asset') }) @@ -471,7 +471,7 @@ describe('useJobMenu', () => { await nextTick() const entry = findActionEntry(jobMenuEntries.value, 'download') - entry?.onClick?.() + void entry?.onClick?.() expect(downloadFileMock).not.toHaveBeenCalled() }) diff --git a/tests-ui/tests/composables/useQueueProgress.test.ts b/src/composables/queue/useQueueProgress.test.ts similarity index 100% rename from tests-ui/tests/composables/useQueueProgress.test.ts rename to src/composables/queue/useQueueProgress.test.ts diff --git a/tests-ui/tests/composables/useResultGallery.test.ts b/src/composables/queue/useResultGallery.test.ts similarity index 100% rename from tests-ui/tests/composables/useResultGallery.test.ts rename to src/composables/queue/useResultGallery.test.ts diff --git a/tests-ui/tests/composables/BrowserTabTitle.test.ts b/src/composables/useBrowserTabTitle.test.ts similarity index 100% rename from tests-ui/tests/composables/BrowserTabTitle.test.ts rename to src/composables/useBrowserTabTitle.test.ts diff --git a/tests-ui/tests/composables/useCachedRequest.test.ts b/src/composables/useCachedRequest.test.ts similarity index 98% rename from tests-ui/tests/composables/useCachedRequest.test.ts rename to src/composables/useCachedRequest.test.ts index 8d2a92a23..08faa3aaf 100644 --- a/tests-ui/tests/composables/useCachedRequest.test.ts +++ b/src/composables/useCachedRequest.test.ts @@ -3,8 +3,11 @@ import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { useCachedRequest } from '@/composables/useCachedRequest' describe('useCachedRequest', () => { - let mockRequestFn: ReturnType - let abortSpy: ReturnType + let mockRequestFn: ( + params: any, + signal?: AbortSignal + ) => Promise + let abortSpy: () => void beforeEach(() => { vi.clearAllMocks() diff --git a/tests-ui/tests/composables/clipboard.test.ts b/src/composables/useCopy.test.ts similarity index 100% rename from tests-ui/tests/composables/clipboard.test.ts rename to src/composables/useCopy.test.ts diff --git a/tests-ui/tests/composables/useCoreCommands.test.ts b/src/composables/useCoreCommands.test.ts similarity index 98% rename from tests-ui/tests/composables/useCoreCommands.test.ts rename to src/composables/useCoreCommands.test.ts index 3c86faa5a..82e3439bc 100644 --- a/tests-ui/tests/composables/useCoreCommands.test.ts +++ b/src/composables/useCoreCommands.test.ts @@ -9,8 +9,8 @@ import { app } from '@/scripts/app' // Mock vue-i18n for useExternalLink const mockLocale = ref('en') -vi.mock('vue-i18n', async (importOriginal) => { - const actual = await importOriginal() +vi.mock('vue-i18n', async () => { + const actual = await vi.importActual('vue-i18n') return { ...actual, useI18n: vi.fn(() => ({ diff --git a/src/composables/useCoreCommands.ts b/src/composables/useCoreCommands.ts index 843e9faad..6b2aa63c2 100644 --- a/src/composables/useCoreCommands.ts +++ b/src/composables/useCoreCommands.ts @@ -39,7 +39,11 @@ import { useLitegraphService } from '@/services/litegraphService' import type { ComfyCommand } from '@/stores/commandStore' import { useExecutionStore } from '@/stores/executionStore' import { useHelpCenterStore } from '@/stores/helpCenterStore' -import { useQueueSettingsStore, useQueueStore } from '@/stores/queueStore' +import { + useQueueSettingsStore, + useQueueStore, + useQueueUIStore +} from '@/stores/queueStore' import { useSubgraphNavigationStore } from '@/stores/subgraphNavigationStore' import { useSubgraphStore } from '@/stores/subgraphStore' import { useBottomPanelStore } from '@/stores/workspace/bottomPanelStore' @@ -63,7 +67,6 @@ import { useWorkflowTemplateSelectorDialog } from './useWorkflowTemplateSelector const { isActiveSubscription, showSubscriptionDialog } = useSubscription() const moveSelectedNodesVersionAdded = '1.22.2' - export function useCoreCommands(): ComfyCommand[] { const workflowService = useWorkflowService() const workflowStore = useWorkflowStore() @@ -75,6 +78,7 @@ export function useCoreCommands(): ComfyCommand[] { const executionStore = useExecutionStore() const telemetry = useTelemetry() const { staticUrls, buildDocsUrl } = useExternalLink() + const settingStore = useSettingStore() const bottomPanelStore = useBottomPanelStore() @@ -82,6 +86,14 @@ export function useCoreCommands(): ComfyCommand[] { useSelectedLiteGraphItems() const getTracker = () => workflowStore.activeWorkflow?.changeTracker + function isQueuePanelV2Enabled() { + return settingStore.get('Comfy.Queue.QPOV2') + } + + async function toggleQueuePanelV2() { + await settingStore.set('Comfy.Queue.QPOV2', !isQueuePanelV2Enabled()) + } + const moveSelectedNodes = ( positionUpdater: (pos: Point, gridSize: number) => Point ) => { @@ -423,6 +435,18 @@ export function useCoreCommands(): ComfyCommand[] { }, active: () => useSettingStore().get('Comfy.Minimap.Visible') }, + { + id: 'Comfy.Queue.ToggleOverlay', + icon: 'pi pi-history', + label: () => t('queue.toggleJobHistory'), + menubarLabel: () => t('queue.jobHistory'), + versionAdded: '1.37.0', + category: 'view-controls' as const, + function: () => { + useQueueUIStore().toggleOverlay() + }, + active: () => useQueueUIStore().isOverlayExpanded + }, { id: 'Comfy.QueuePrompt', icon: 'pi pi-play', @@ -1175,6 +1199,12 @@ export function useCoreCommands(): ComfyCommand[] { await useWorkflowService().reloadCurrentWorkflow() // ensure changes take effect immediately } }, + { + id: 'Comfy.ToggleQPOV2', + icon: 'pi pi-list', + label: 'Toggle Queue Panel V2', + function: toggleQueuePanelV2 + }, { id: 'Comfy.ToggleLinear', icon: 'pi pi-database', diff --git a/tests-ui/tests/composables/useErrorHandling.test.ts b/src/composables/useErrorHandling.test.ts similarity index 100% rename from tests-ui/tests/composables/useErrorHandling.test.ts rename to src/composables/useErrorHandling.test.ts diff --git a/tests-ui/tests/composables/useExternalLink.test.ts b/src/composables/useExternalLink.test.ts similarity index 100% rename from tests-ui/tests/composables/useExternalLink.test.ts rename to src/composables/useExternalLink.test.ts diff --git a/tests-ui/tests/composables/useFeatureFlags.test.ts b/src/composables/useFeatureFlags.test.ts similarity index 100% rename from tests-ui/tests/composables/useFeatureFlags.test.ts rename to src/composables/useFeatureFlags.test.ts diff --git a/src/composables/useFeatureFlags.ts b/src/composables/useFeatureFlags.ts index 697818c4e..043721b98 100644 --- a/src/composables/useFeatureFlags.ts +++ b/src/composables/useFeatureFlags.ts @@ -14,7 +14,8 @@ export enum ServerFeatureFlag { ASSET_UPDATE_OPTIONS_ENABLED = 'asset_update_options_enabled', PRIVATE_MODELS_ENABLED = 'private_models_enabled', ONBOARDING_SURVEY_ENABLED = 'onboarding_survey_enabled', - HUGGINGFACE_MODEL_IMPORT_ENABLED = 'huggingface_model_import_enabled' + HUGGINGFACE_MODEL_IMPORT_ENABLED = 'huggingface_model_import_enabled', + ASYNC_MODEL_UPLOAD_ENABLED = 'async_model_upload_enabled' } /** @@ -65,7 +66,6 @@ export function useFeatureFlags() { ) }, get huggingfaceModelImportEnabled() { - // Check remote config first (from /api/features), fall back to websocket feature flags return ( remoteConfig.value.huggingface_model_import_enabled ?? api.getServerFeature( @@ -73,6 +73,15 @@ export function useFeatureFlags() { false ) ) + }, + get asyncModelUploadEnabled() { + return ( + remoteConfig.value.async_model_upload_enabled ?? + api.getServerFeature( + ServerFeatureFlag.ASYNC_MODEL_UPLOAD_ENABLED, + false + ) + ) } }) diff --git a/tests-ui/tests/composables/useLoad3d.test.ts b/src/composables/useLoad3d.test.ts similarity index 99% rename from tests-ui/tests/composables/useLoad3d.test.ts rename to src/composables/useLoad3d.test.ts index a6c496cce..b5e1251c2 100644 --- a/tests-ui/tests/composables/useLoad3d.test.ts +++ b/src/composables/useLoad3d.test.ts @@ -117,7 +117,9 @@ describe('useLoad3d', () => { } } - vi.mocked(Load3d).mockImplementation(() => mockLoad3d) + vi.mocked(Load3d).mockImplementation(function () { + Object.assign(this, mockLoad3d) + }) mockToastStore = { addAlert: vi.fn() @@ -289,7 +291,7 @@ describe('useLoad3d', () => { }) it('should handle initialization errors', async () => { - vi.mocked(Load3d).mockImplementationOnce(() => { + vi.mocked(Load3d).mockImplementationOnce(function () { throw new Error('Load3d creation failed') }) diff --git a/src/composables/useLoad3d.ts b/src/composables/useLoad3d.ts index 045e8c572..8b589fc2b 100644 --- a/src/composables/useLoad3d.ts +++ b/src/composables/useLoad3d.ts @@ -60,6 +60,8 @@ export const useLoad3d = (nodeOrRef: MaybeRef) => { const playing = ref(false) const selectedSpeed = ref(1) const selectedAnimation = ref(0) + const animationProgress = ref(0) + const animationDuration = ref(0) const loading = ref(false) const loadingMessage = ref('') const isPreview = ref(false) @@ -357,6 +359,13 @@ export const useLoad3d = (nodeOrRef: MaybeRef) => { } } + const handleSeek = (progress: number) => { + if (load3d && animationDuration.value > 0) { + const time = (progress / 100) * animationDuration.value + load3d.setAnimationTime(time) + } + } + const handleBackgroundImageUpdate = async (file: File | null) => { if (!file) { sceneConfig.value.backgroundImage = '' @@ -514,6 +523,14 @@ export const useLoad3d = (nodeOrRef: MaybeRef) => { animationListChange: (newValue: AnimationItem[]) => { animations.value = newValue }, + animationProgressChange: (data: { + progress: number + currentTime: number + duration: number + }) => { + animationProgress.value = data.progress + animationDuration.value = data.duration + }, cameraChanged: (cameraState: CameraState) => { const rawNode = toRaw(nodeRef.value) if (rawNode) { @@ -573,6 +590,8 @@ export const useLoad3d = (nodeOrRef: MaybeRef) => { playing, selectedSpeed, selectedAnimation, + animationProgress, + animationDuration, loading, loadingMessage, @@ -585,6 +604,7 @@ export const useLoad3d = (nodeOrRef: MaybeRef) => { handleStopRecording, handleExportRecording, handleClearRecording, + handleSeek, handleBackgroundImageUpdate, handleExportModel, handleModelDrop, diff --git a/tests-ui/tests/composables/useLoad3dDrag.test.ts b/src/composables/useLoad3dDrag.test.ts similarity index 98% rename from tests-ui/tests/composables/useLoad3dDrag.test.ts rename to src/composables/useLoad3dDrag.test.ts index 284d21c23..f35c5c736 100644 --- a/tests-ui/tests/composables/useLoad3dDrag.test.ts +++ b/src/composables/useLoad3dDrag.test.ts @@ -35,7 +35,7 @@ function createMockDragEvent( describe('useLoad3dDrag', () => { let mockToastStore: any - let mockOnModelDrop: ReturnType + let mockOnModelDrop: (file: File) => void | Promise beforeEach(() => { vi.clearAllMocks() @@ -199,7 +199,7 @@ describe('useLoad3dDrag', () => { const extensions = ['.gltf', '.glb', '.obj', '.fbx', '.stl'] for (const ext of extensions) { - mockOnModelDrop.mockClear() + vi.mocked(mockOnModelDrop).mockClear() const modelFile = new File([], `model${ext}`) const event = createMockDragEvent('drop', { diff --git a/tests-ui/tests/composables/useLoad3dViewer.test.ts b/src/composables/useLoad3dViewer.test.ts similarity index 98% rename from tests-ui/tests/composables/useLoad3dViewer.test.ts rename to src/composables/useLoad3dViewer.test.ts index 69d40d752..77a8e50a0 100644 --- a/tests-ui/tests/composables/useLoad3dViewer.test.ts +++ b/src/composables/useLoad3dViewer.test.ts @@ -120,7 +120,9 @@ describe('useLoad3dViewer', () => { forceRender: vi.fn() } - vi.mocked(Load3d).mockImplementation(() => mockLoad3d) + vi.mocked(Load3d).mockImplementation(function () { + Object.assign(this, mockLoad3d) + }) mockLoad3dService = { copyLoad3dState: vi.fn().mockResolvedValue(undefined), @@ -198,7 +200,7 @@ describe('useLoad3dViewer', () => { }) it('should handle initialization errors', async () => { - vi.mocked(Load3d).mockImplementationOnce(() => { + vi.mocked(Load3d).mockImplementationOnce(function () { throw new Error('Load3d creation failed') }) @@ -312,7 +314,7 @@ describe('useLoad3dViewer', () => { }) it('should handle watcher errors gracefully', async () => { - mockLoad3d.setBackgroundColor.mockImplementationOnce(() => { + mockLoad3d.setBackgroundColor.mockImplementationOnce(function () { throw new Error('Color update failed') }) diff --git a/src/composables/useLoad3dViewer.ts b/src/composables/useLoad3dViewer.ts index cd9acf8d4..9022c2d2d 100644 --- a/src/composables/useLoad3dViewer.ts +++ b/src/composables/useLoad3dViewer.ts @@ -3,6 +3,7 @@ import { ref, toRaw, watch } from 'vue' import Load3d from '@/extensions/core/load3d/Load3d' import Load3dUtils from '@/extensions/core/load3d/Load3dUtils' import type { + AnimationItem, BackgroundRenderModeType, CameraState, CameraType, @@ -49,6 +50,14 @@ export const useLoad3dViewer = (node?: LGraphNode) => { const isSplatModel = ref(false) const isPlyModel = ref(false) + // Animation state + const animations = ref([]) + const playing = ref(false) + const selectedSpeed = ref(1) + const selectedAnimation = ref(0) + const animationProgress = ref(0) + const animationDuration = ref(0) + let load3d: Load3d | null = null let sourceLoad3d: Load3d | null = null @@ -174,6 +183,61 @@ export const useLoad3dViewer = (node?: LGraphNode) => { } }) + // Animation watches + watch(playing, (newValue) => { + if (load3d) { + load3d.toggleAnimation(newValue) + } + }) + + watch(selectedSpeed, (newValue) => { + if (load3d && newValue) { + load3d.setAnimationSpeed(newValue) + } + }) + + watch(selectedAnimation, (newValue) => { + if (load3d && newValue !== undefined) { + load3d.updateSelectedAnimation(newValue) + } + }) + + const handleSeek = (progress: number) => { + if (load3d && animationDuration.value > 0) { + const time = (progress / 100) * animationDuration.value + load3d.setAnimationTime(time) + } + } + + const setupAnimationEvents = () => { + if (!load3d) return + + load3d.addEventListener( + 'animationListChange', + (newValue: AnimationItem[]) => { + animations.value = newValue + } + ) + + load3d.addEventListener( + 'animationProgressChange', + (data: { progress: number; currentTime: number; duration: number }) => { + animationProgress.value = data.progress + animationDuration.value = data.duration + } + ) + + // Initialize animation list if animations already exist + if (load3d.hasAnimations()) { + const clips = load3d.animationManager.animationClips + animations.value = clips.map((clip, index) => ({ + name: clip.name || `Animation ${index + 1}`, + index + })) + animationDuration.value = load3d.getAnimationDuration() + } + } + /** * Initialize viewer in node mode (with source Load3d) */ @@ -270,6 +334,8 @@ export const useLoad3dViewer = (node?: LGraphNode) => { upDirection: upDirection.value, materialMode: materialMode.value } + + setupAnimationEvents() } catch (error) { console.error('Error initializing Load3d viewer:', error) useToastStore().addAlert( @@ -310,6 +376,8 @@ export const useLoad3dViewer = (node?: LGraphNode) => { isPlyModel.value = load3d.isPlyModel() isPreview.value = true + + setupAnimationEvents() } catch (error) { console.error('Error initializing standalone 3D viewer:', error) useToastStore().addAlert('Failed to load 3D model') @@ -527,6 +595,14 @@ export const useLoad3dViewer = (node?: LGraphNode) => { isSplatModel, isPlyModel, + // Animation state + animations, + playing, + selectedSpeed, + selectedAnimation, + animationProgress, + animationDuration, + // Methods initializeViewer, initializeStandaloneViewer, @@ -539,6 +615,7 @@ export const useLoad3dViewer = (node?: LGraphNode) => { refreshViewport, handleBackgroundImageUpdate, handleModelDrop, + handleSeek, cleanup } } diff --git a/tests-ui/tests/composables/useServerLogs.test.ts b/src/composables/useServerLogs.test.ts similarity index 100% rename from tests-ui/tests/composables/useServerLogs.test.ts rename to src/composables/useServerLogs.test.ts diff --git a/tests-ui/tests/composables/useTemplateFiltering.test.ts b/src/composables/useTemplateFiltering.test.ts similarity index 94% rename from tests-ui/tests/composables/useTemplateFiltering.test.ts rename to src/composables/useTemplateFiltering.test.ts index bb2bce269..5f30e5ec1 100644 --- a/tests-ui/tests/composables/useTemplateFiltering.test.ts +++ b/src/composables/useTemplateFiltering.test.ts @@ -1,3 +1,4 @@ +import { createPinia, setActivePinia } from 'pinia' import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' import { nextTick, ref } from 'vue' @@ -19,10 +20,22 @@ const defaultSettingStore = { set: vi.fn().mockResolvedValue(undefined) } +const defaultRankingStore = { + computeDefaultScore: vi.fn(() => 0), + computePopularScore: vi.fn(() => 0), + getUsageScore: vi.fn(() => 0), + computeFreshness: vi.fn(() => 0.5), + isLoaded: { value: false } +} + vi.mock('@/platform/settings/settingStore', () => ({ useSettingStore: vi.fn(() => defaultSettingStore) })) +vi.mock('@/stores/templateRankingStore', () => ({ + useTemplateRankingStore: vi.fn(() => defaultRankingStore) +})) + vi.mock('@/platform/telemetry', () => ({ useTelemetry: vi.fn(() => ({ trackTemplateFilterChanged: vi.fn() @@ -34,6 +47,7 @@ const { useTemplateFiltering } = describe('useTemplateFiltering', () => { beforeEach(() => { + setActivePinia(createPinia()) vi.clearAllMocks() }) diff --git a/src/composables/useTemplateFiltering.ts b/src/composables/useTemplateFiltering.ts index f447f230b..fdb892e07 100644 --- a/src/composables/useTemplateFiltering.ts +++ b/src/composables/useTemplateFiltering.ts @@ -6,12 +6,14 @@ import type { Ref } from 'vue' import { useSettingStore } from '@/platform/settings/settingStore' import { useTelemetry } from '@/platform/telemetry' import type { TemplateInfo } from '@/platform/workflow/templates/types/template' +import { useTemplateRankingStore } from '@/stores/templateRankingStore' import { debounce } from 'es-toolkit/compat' export function useTemplateFiltering( templates: Ref | TemplateInfo[] ) { const settingStore = useSettingStore() + const rankingStore = useTemplateRankingStore() const searchQuery = ref('') const selectedModels = ref( @@ -25,6 +27,8 @@ export function useTemplateFiltering( ) const sortBy = ref< | 'default' + | 'recommended' + | 'popular' | 'alphabetical' | 'newest' | 'vram-low-to-high' @@ -151,10 +155,42 @@ export function useTemplateFiltering( return Number.POSITIVE_INFINITY } + watch( + filteredByRunsOn, + (templates) => { + rankingStore.largestUsageScore = Math.max( + ...templates.map((t) => t.usage || 0) + ) + }, + { immediate: true } + ) + const sortedTemplates = computed(() => { const templates = [...filteredByRunsOn.value] switch (sortBy.value) { + case 'recommended': + // Curated: usage × 0.5 + internal × 0.3 + freshness × 0.2 + return templates.sort((a, b) => { + const scoreA = rankingStore.computeDefaultScore( + a.date, + a.searchRank, + a.usage + ) + const scoreB = rankingStore.computeDefaultScore( + b.date, + b.searchRank, + b.usage + ) + return scoreB - scoreA + }) + case 'popular': + // User-driven: usage × 0.9 + freshness × 0.1 + return templates.sort((a, b) => { + const scoreA = rankingStore.computePopularScore(a.date, a.usage) + const scoreB = rankingStore.computePopularScore(b.date, b.usage) + return scoreB - scoreA + }) case 'alphabetical': return templates.sort((a, b) => { const nameA = a.title || a.name || '' @@ -184,7 +220,7 @@ export function useTemplateFiltering( return vramA - vramB }) case 'model-size-low-to-high': - return templates.sort((a: any, b: any) => { + return templates.sort((a, b) => { const sizeA = typeof a.size === 'number' ? a.size : Number.POSITIVE_INFINITY const sizeB = @@ -194,7 +230,6 @@ export function useTemplateFiltering( }) case 'default': default: - // Keep original order (default order) return templates } }) @@ -206,7 +241,7 @@ export function useTemplateFiltering( selectedModels.value = [] selectedUseCases.value = [] selectedRunsOn.value = [] - sortBy.value = 'newest' + sortBy.value = 'default' } const removeModelFilter = (model: string) => { diff --git a/tests-ui/tests/widgets/proxyWidget.test.ts b/src/core/graph/subgraph/proxyWidget.test.ts similarity index 98% rename from tests-ui/tests/widgets/proxyWidget.test.ts rename to src/core/graph/subgraph/proxyWidget.test.ts index 940ee66f0..c0d41d23e 100644 --- a/tests-ui/tests/widgets/proxyWidget.test.ts +++ b/src/core/graph/subgraph/proxyWidget.test.ts @@ -8,7 +8,7 @@ import type { LGraphCanvas, SubgraphNode } from '@/lib/litegraph/src/litegraph' import { createTestSubgraph, createTestSubgraphNode -} from '../litegraph/subgraph/fixtures/subgraphHelpers' +} from '@/lib/litegraph/src/subgraph/__fixtures__/subgraphHelpers' const canvasEl: Partial = { addEventListener() {} } const canvas: Partial = { canvas: canvasEl as HTMLCanvasElement } diff --git a/tests-ui/tests/widgets/dynamicCombo.test.ts b/src/core/graph/widgets/dynamicWidgets.test.ts similarity index 100% rename from tests-ui/tests/widgets/dynamicCombo.test.ts rename to src/core/graph/widgets/dynamicWidgets.test.ts diff --git a/tests-ui/tests/extensions/contextMenuExtensionName.test.ts b/src/extensions/core/contextMenuFilter.name.test.ts similarity index 100% rename from tests-ui/tests/extensions/contextMenuExtensionName.test.ts rename to src/extensions/core/contextMenuFilter.name.test.ts diff --git a/tests-ui/tests/extensions/contextMenuExtension.test.ts b/src/extensions/core/contextMenuFilter.test.ts similarity index 100% rename from tests-ui/tests/extensions/contextMenuExtension.test.ts rename to src/extensions/core/contextMenuFilter.test.ts diff --git a/tests-ui/tests/dynamicPrompts.test.ts b/src/extensions/core/dynamicPrompts.test.ts similarity index 100% rename from tests-ui/tests/dynamicPrompts.test.ts rename to src/extensions/core/dynamicPrompts.test.ts diff --git a/src/extensions/core/load3d/AnimationManager.ts b/src/extensions/core/load3d/AnimationManager.ts index a451da8cd..80fc6f153 100644 --- a/src/extensions/core/load3d/AnimationManager.ts +++ b/src/extensions/core/load3d/AnimationManager.ts @@ -125,6 +125,13 @@ export class AnimationManager implements AnimationManagerInterface { } this.animationActions = [action] + + // Emit initial progress to set duration + this.eventManager.emitEvent('animationProgressChange', { + progress: 0, + currentTime: 0, + duration: clip.duration + }) } toggleAnimation(play?: boolean): void { @@ -150,8 +157,58 @@ export class AnimationManager implements AnimationManagerInterface { update(delta: number): void { if (this.currentAnimation && this.isAnimationPlaying) { this.currentAnimation.update(delta) + + if (this.animationActions.length > 0) { + const action = this.animationActions[0] + const clip = action.getClip() + const progress = (action.time / clip.duration) * 100 + this.eventManager.emitEvent('animationProgressChange', { + progress, + currentTime: action.time, + duration: clip.duration + }) + } } } + getAnimationTime(): number { + if (this.animationActions.length === 0) return 0 + return this.animationActions[0].time + } + + getAnimationDuration(): number { + if (this.animationActions.length === 0) return 0 + return this.animationActions[0].getClip().duration + } + + setAnimationTime(time: number): void { + if (this.animationActions.length === 0) return + const duration = this.getAnimationDuration() + const clampedTime = Math.max(0, Math.min(time, duration)) + + // Temporarily unpause to allow time update, then restore + const wasPaused = this.animationActions.map((action) => action.paused) + this.animationActions.forEach((action) => { + action.paused = false + action.time = clampedTime + }) + + if (this.currentAnimation) { + this.currentAnimation.setTime(clampedTime) + this.currentAnimation.update(0) + } + + // Restore paused state + this.animationActions.forEach((action, i) => { + action.paused = wasPaused[i] + }) + + this.eventManager.emitEvent('animationProgressChange', { + progress: (clampedTime / duration) * 100, + currentTime: clampedTime, + duration + }) + } + reset(): void {} } diff --git a/src/extensions/core/load3d/Load3d.ts b/src/extensions/core/load3d/Load3d.ts index 2fb8ff6bb..f17683b64 100644 --- a/src/extensions/core/load3d/Load3d.ts +++ b/src/extensions/core/load3d/Load3d.ts @@ -392,7 +392,8 @@ class Load3d { this.STATUS_MOUSE_ON_SCENE || this.STATUS_MOUSE_ON_VIEWER || this.isRecording() || - !this.INITIAL_RENDER_DONE + !this.INITIAL_RENDER_DONE || + this.animationManager.isAnimationPlaying ) } @@ -726,6 +727,19 @@ class Load3d { return this.animationManager.animationClips.length > 0 } + public getAnimationTime(): number { + return this.animationManager.getAnimationTime() + } + + public getAnimationDuration(): number { + return this.animationManager.getAnimationDuration() + } + + public setAnimationTime(time: number): void { + this.animationManager.setAnimationTime(time) + this.forceRender() + } + public remove(): void { if (this.contextMenuAbortController) { this.contextMenuAbortController.abort() diff --git a/src/extensions/core/load3d/Load3dUtils.ts b/src/extensions/core/load3d/Load3dUtils.ts index 4a63e6b5a..13095ac96 100644 --- a/src/extensions/core/load3d/Load3dUtils.ts +++ b/src/extensions/core/load3d/Load3dUtils.ts @@ -34,9 +34,26 @@ class Load3dUtils { return await resp.json() } + static readonly MAX_UPLOAD_SIZE_MB = 100 + static async uploadFile(file: File, subfolder: string) { let uploadPath + const fileSizeMB = file.size / 1024 / 1024 + if (fileSizeMB > this.MAX_UPLOAD_SIZE_MB) { + const message = t('toastMessages.fileTooLarge', { + size: fileSizeMB.toFixed(1), + maxSize: this.MAX_UPLOAD_SIZE_MB + }) + console.warn( + '[Load3D] uploadFile: file too large', + fileSizeMB.toFixed(2), + 'MB' + ) + useToastStore().addAlert(message) + return undefined + } + try { const body = new FormData() body.append('image', file) @@ -61,7 +78,7 @@ class Load3dUtils { useToastStore().addAlert(resp.status + ' - ' + resp.statusText) } } catch (error) { - console.error('Upload error:', error) + console.error('[Load3D] uploadFile: exception', error) useToastStore().addAlert( error instanceof Error ? error.message diff --git a/src/extensions/core/load3d/LoaderManager.ts b/src/extensions/core/load3d/LoaderManager.ts index 8fbc31767..03002d661 100644 --- a/src/extensions/core/load3d/LoaderManager.ts +++ b/src/extensions/core/load3d/LoaderManager.ts @@ -3,9 +3,10 @@ import * as THREE from 'three' import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader' import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader' -import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader' import { PLYLoader } from 'three/examples/jsm/loaders/PLYLoader' import { STLLoader } from 'three/examples/jsm/loaders/STLLoader' +import { MtlObjBridge, OBJLoader2Parallel } from 'wwobjloader2' +import OBJLoader2WorkerUrl from 'wwobjloader2/worker?url' import { t } from '@/i18n' import { useSettingStore } from '@/platform/settings/settingStore' @@ -22,7 +23,7 @@ import { FastPLYLoader } from './loader/FastPLYLoader' export class LoaderManager implements LoaderManagerInterface { gltfLoader: GLTFLoader - objLoader: OBJLoader + objLoader: OBJLoader2Parallel mtlLoader: MTLLoader fbxLoader: FBXLoader stlLoader: STLLoader @@ -41,7 +42,12 @@ export class LoaderManager implements LoaderManagerInterface { this.eventManager = eventManager this.gltfLoader = new GLTFLoader() - this.objLoader = new OBJLoader() + this.objLoader = new OBJLoader2Parallel() + // Set worker URL for Vite compatibility + this.objLoader.setWorkerUrl( + true, + new URL(OBJLoader2WorkerUrl, import.meta.url) + ) this.mtlLoader = new MTLLoader() this.fbxLoader = new FBXLoader() this.stlLoader = new STLLoader() @@ -160,6 +166,10 @@ export class LoaderManager implements LoaderManagerInterface { fbxModel.traverse((child) => { if (child instanceof THREE.Mesh) { this.modelManager.originalMaterials.set(child, child.material) + + if (child instanceof THREE.SkinnedMesh) { + child.frustumCulled = false + } } }) break @@ -173,7 +183,9 @@ export class LoaderManager implements LoaderManagerInterface { const materials = await this.mtlLoader.loadAsync(mtlFileName) materials.preload() - this.objLoader.setMaterials(materials) + const materialsFromMtl = + MtlObjBridge.addMaterialsFromMtlLoader(materials) + this.objLoader.setMaterials(materialsFromMtl) } catch (e) { console.log( 'No MTL file found or error loading it, continuing without materials' @@ -181,8 +193,10 @@ export class LoaderManager implements LoaderManagerInterface { } } - this.objLoader.setPath(path) - model = await this.objLoader.loadAsync(filename) + // OBJLoader2Parallel uses Web Worker for parsing (non-blocking) + const objUrl = path + encodeURIComponent(filename) + model = await this.objLoader.loadAsync(objUrl) + model.traverse((child) => { if (child instanceof THREE.Mesh) { this.modelManager.originalMaterials.set(child, child.material) @@ -193,7 +207,6 @@ export class LoaderManager implements LoaderManagerInterface { case 'gltf': case 'glb': this.gltfLoader.setPath(path) - const gltf = await this.gltfLoader.loadAsync(filename) this.modelManager.setOriginalModel(gltf) @@ -203,6 +216,10 @@ export class LoaderManager implements LoaderManagerInterface { if (child instanceof THREE.Mesh) { child.geometry.computeVertexNormals() this.modelManager.originalMaterials.set(child, child.material) + + if (child instanceof THREE.SkinnedMesh) { + child.frustumCulled = false + } } }) break diff --git a/src/extensions/core/load3d/interfaces.ts b/src/extensions/core/load3d/interfaces.ts index 2b043fdb1..7954f6bfe 100644 --- a/src/extensions/core/load3d/interfaces.ts +++ b/src/extensions/core/load3d/interfaces.ts @@ -4,8 +4,8 @@ import { ViewHelper } from 'three/examples/jsm/helpers/ViewHelper' import { FBXLoader } from 'three/examples/jsm/loaders/FBXLoader' import { type GLTF, GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' import { MTLLoader } from 'three/examples/jsm/loaders/MTLLoader' -import { OBJLoader } from 'three/examples/jsm/loaders/OBJLoader' import { STLLoader } from 'three/examples/jsm/loaders/STLLoader' +import { type OBJLoader2Parallel } from 'wwobjloader2' export type MaterialMode = | 'original' @@ -146,6 +146,9 @@ export interface AnimationManagerInterface extends BaseManager { updateSelectedAnimation(index: number): void toggleAnimation(play?: boolean): void update(delta: number): void + getAnimationTime(): number + getAnimationDuration(): number + setAnimationTime(time: number): void } export interface ModelManagerInterface { @@ -176,7 +179,7 @@ export interface ModelManagerInterface { export interface LoaderManagerInterface { gltfLoader: GLTFLoader - objLoader: OBJLoader + objLoader: OBJLoader2Parallel mtlLoader: MTLLoader fbxLoader: FBXLoader stlLoader: STLLoader diff --git a/src/extensions/core/maskeditor.ts b/src/extensions/core/maskeditor.ts index a0084cfb9..406fdcd7d 100644 --- a/src/extensions/core/maskeditor.ts +++ b/src/extensions/core/maskeditor.ts @@ -1,7 +1,7 @@ import _ from 'es-toolkit/compat' import type { LGraphNode } from '@/lib/litegraph/src/litegraph' -import { app } from '@/scripts/app' +import { app, ComfyApp } from '@/scripts/app' import { useMaskEditorStore } from '@/stores/maskEditorStore' import { useDialogStore } from '@/stores/dialogStore' import { useMaskEditor } from '@/composables/maskeditor/useMaskEditor' @@ -20,11 +20,32 @@ function openMaskEditor(node: LGraphNode): void { useMaskEditor().openMaskEditor(node) } +// Open mask editor from clipspace (for plugin compatibility) +// This is called when ComfyApp.open_maskeditor() is invoked without arguments +function openMaskEditorFromClipspace(): void { + const node = ComfyApp.clipspace_return_node as LGraphNode | null + if (!node) { + console.error('[MaskEditor] No clipspace_return_node found') + return + } + + openMaskEditor(node) +} + // Check if the dialog is already opened function isOpened(): boolean { return useDialogStore().isDialogOpen('global-mask-editor') } +const changeBrushSize = async (sizeChanger: (oldSize: number) => number) => { + if (!isOpened()) return + + const store = useMaskEditorStore() + const oldBrushSize = store.brushSettings.size + const newBrushSize = sizeChanger(oldBrushSize) + store.setBrushSize(newBrushSize) +} + app.registerExtension({ name: 'Comfy.MaskEditor', settings: [ @@ -70,22 +91,33 @@ app.registerExtension({ id: 'Comfy.MaskEditor.BrushSize.Increase', icon: 'pi pi-plus-circle', label: 'Increase Brush Size in MaskEditor', - function: () => changeBrushSize((old) => _.clamp(old + 4, 1, 100)) + function: () => changeBrushSize((old) => _.clamp(old + 2, 1, 250)) }, { id: 'Comfy.MaskEditor.BrushSize.Decrease', icon: 'pi pi-minus-circle', label: 'Decrease Brush Size in MaskEditor', - function: () => changeBrushSize((old) => _.clamp(old - 4, 1, 100)) + function: () => changeBrushSize((old) => _.clamp(old - 2, 1, 250)) + }, + { + id: 'Comfy.MaskEditor.ColorPicker', + icon: 'pi pi-palette', + label: 'Open Color Picker in MaskEditor', + function: () => { + if (!isOpened()) return + + const store = useMaskEditorStore() + store.colorInput?.click() + } } - ] + ], + init() { + // Set up ComfyApp static methods for plugin compatibility (deprecated) + ComfyApp.open_maskeditor = openMaskEditorFromClipspace + + console.warn( + '[MaskEditor] ComfyApp.open_maskeditor is deprecated. ' + + 'Plugins should migrate to using the command system or direct node context menu integration.' + ) + } }) - -const changeBrushSize = async (sizeChanger: (oldSize: number) => number) => { - if (!isOpened()) return - - const store = useMaskEditorStore() - const oldBrushSize = store.brushSettings.size - const newBrushSize = sizeChanger(oldBrushSize) - store.setBrushSize(newBrushSize) -} diff --git a/tests-ui/tests/litegraph/utils/CanvasPointer.deviceDetection.test.ts b/src/lib/litegraph/src/CanvasPointer.deviceDetection.test.ts similarity index 100% rename from tests-ui/tests/litegraph/utils/CanvasPointer.deviceDetection.test.ts rename to src/lib/litegraph/src/CanvasPointer.deviceDetection.test.ts diff --git a/tests-ui/tests/litegraph/core/ConfigureGraph.test.ts b/src/lib/litegraph/src/LGraph.configure.test.ts similarity index 92% rename from tests-ui/tests/litegraph/core/ConfigureGraph.test.ts rename to src/lib/litegraph/src/LGraph.configure.test.ts index 935ec1f28..2401dfe30 100644 --- a/tests-ui/tests/litegraph/core/ConfigureGraph.test.ts +++ b/src/lib/litegraph/src/LGraph.configure.test.ts @@ -3,7 +3,7 @@ import { describe } from 'vitest' import { LGraph } from '@/lib/litegraph/src/litegraph' -import { dirtyTest } from './fixtures/testExtensions' +import { dirtyTest } from './__fixtures__/testExtensions' describe.skip('LGraph configure()', () => { dirtyTest( diff --git a/tests-ui/tests/litegraph/core/LGraph_constructor.test.ts b/src/lib/litegraph/src/LGraph.constructor.test.ts similarity index 90% rename from tests-ui/tests/litegraph/core/LGraph_constructor.test.ts rename to src/lib/litegraph/src/LGraph.constructor.test.ts index 62720b9c0..4e214cae5 100644 --- a/tests-ui/tests/litegraph/core/LGraph_constructor.test.ts +++ b/src/lib/litegraph/src/LGraph.constructor.test.ts @@ -3,7 +3,7 @@ import { describe } from 'vitest' import { LGraph } from '@/lib/litegraph/src/litegraph' -import { dirtyTest } from './fixtures/testExtensions' +import { dirtyTest } from './__fixtures__/testExtensions' describe.skip('LGraph (constructor only)', () => { dirtyTest( diff --git a/tests-ui/tests/litegraph/core/serialise.test.ts b/src/lib/litegraph/src/LGraph.serialise.test.ts similarity index 94% rename from tests-ui/tests/litegraph/core/serialise.test.ts rename to src/lib/litegraph/src/LGraph.serialise.test.ts index 629c50e98..3eee37c6a 100644 --- a/tests-ui/tests/litegraph/core/serialise.test.ts +++ b/src/lib/litegraph/src/LGraph.serialise.test.ts @@ -3,7 +3,7 @@ import { describe } from 'vitest' import { LGraph, LGraphGroup, LGraphNode } from '@/lib/litegraph/src/litegraph' import type { ISerialisedGraph } from '@/lib/litegraph/src/litegraph' -import { test } from './fixtures/testExtensions' +import { test } from './__fixtures__/testExtensions' describe('LGraph Serialisation', () => { test('can (de)serialise node / group titles', ({ expect, minimalGraph }) => { diff --git a/tests-ui/tests/litegraph/core/LGraph.test.ts b/src/lib/litegraph/src/LGraph.test.ts similarity index 86% rename from tests-ui/tests/litegraph/core/LGraph.test.ts rename to src/lib/litegraph/src/LGraph.test.ts index 61d3da734..1c2f38da2 100644 --- a/tests-ui/tests/litegraph/core/LGraph.test.ts +++ b/src/lib/litegraph/src/LGraph.test.ts @@ -1,10 +1,43 @@ -import { describe } from 'vitest' +import { describe, expect, it } from 'vitest' import { LGraph, LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph' -import { test } from './fixtures/testExtensions' +import { test } from './__fixtures__/testExtensions' + +function swapNodes(nodes: LGraphNode[]) { + const firstNode = nodes[0] + const lastNode = nodes[nodes.length - 1] + nodes[0] = lastNode + nodes[nodes.length - 1] = firstNode + return nodes +} + +function createGraph(...nodes: LGraphNode[]) { + const graph = new LGraph() + nodes.forEach((node) => graph.add(node)) + return graph +} + +class DummyNode extends LGraphNode { + constructor() { + super('dummy') + } +} describe('LGraph', () => { + it('should serialize deterministic node order', async () => { + LiteGraph.registerNodeType('dummy', DummyNode) + const node1 = new DummyNode() + const node2 = new DummyNode() + const graph = createGraph(node1, node2) + + const result1 = graph.serialize({ sortNodes: true }) + expect(result1.nodes).not.toHaveLength(0) + graph._nodes = swapNodes(graph.nodes) + const result2 = graph.serialize({ sortNodes: true }) + + expect(result1).toEqual(result2) + }) test('can be instantiated', ({ expect }) => { // @ts-expect-error Intentional - extra holds any / all consumer data that should be serialised const graph = new LGraph({ extra: 'TestGraph' }) diff --git a/tests-ui/tests/litegraph/core/LGraphButton.test.ts b/src/lib/litegraph/src/LGraphButton.test.ts similarity index 98% rename from tests-ui/tests/litegraph/core/LGraphButton.test.ts rename to src/lib/litegraph/src/LGraphButton.test.ts index 18830d8a4..83d17abc7 100644 --- a/tests-ui/tests/litegraph/core/LGraphButton.test.ts +++ b/src/lib/litegraph/src/LGraphButton.test.ts @@ -1,7 +1,6 @@ import { describe, expect, it, vi } from 'vitest' -import { LGraphButton } from '@/lib/litegraph/src/litegraph' -import { Rectangle } from '@/lib/litegraph/src/litegraph' +import { LGraphButton, Rectangle } from '@/lib/litegraph/src/litegraph' describe('LGraphButton', () => { describe('Constructor', () => { diff --git a/tests-ui/tests/litegraph/core/LGraphCanvas.titleButtons.test.ts b/src/lib/litegraph/src/LGraphCanvas.titleButtons.test.ts similarity index 98% rename from tests-ui/tests/litegraph/core/LGraphCanvas.titleButtons.test.ts rename to src/lib/litegraph/src/LGraphCanvas.titleButtons.test.ts index f02fe005e..5c814f95e 100644 --- a/tests-ui/tests/litegraph/core/LGraphCanvas.titleButtons.test.ts +++ b/src/lib/litegraph/src/LGraphCanvas.titleButtons.test.ts @@ -1,7 +1,10 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' -import { LGraphCanvas } from '@/lib/litegraph/src/litegraph' -import { LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph' +import { + LGraphCanvas, + LGraphNode, + LiteGraph +} from '@/lib/litegraph/src/litegraph' describe('LGraphCanvas Title Button Rendering', () => { let canvas: LGraphCanvas diff --git a/tests-ui/tests/litegraph/core/LGraphGroup.test.ts b/src/lib/litegraph/src/LGraphGroup.test.ts similarity index 84% rename from tests-ui/tests/litegraph/core/LGraphGroup.test.ts rename to src/lib/litegraph/src/LGraphGroup.test.ts index a50b33256..589e5a958 100644 --- a/tests-ui/tests/litegraph/core/LGraphGroup.test.ts +++ b/src/lib/litegraph/src/LGraphGroup.test.ts @@ -2,7 +2,7 @@ import { describe, expect } from 'vitest' import { LGraphGroup } from '@/lib/litegraph/src/litegraph' -import { test } from './fixtures/testExtensions' +import { test } from './__fixtures__/testExtensions' describe('LGraphGroup', () => { test('serializes to the existing format', () => { diff --git a/tests-ui/tests/litegraph/core/LGraphNode.resize.test.ts b/src/lib/litegraph/src/LGraphNode.resize.test.ts similarity index 98% rename from tests-ui/tests/litegraph/core/LGraphNode.resize.test.ts rename to src/lib/litegraph/src/LGraphNode.resize.test.ts index eb967fcab..b3f971eed 100644 --- a/tests-ui/tests/litegraph/core/LGraphNode.resize.test.ts +++ b/src/lib/litegraph/src/LGraphNode.resize.test.ts @@ -2,7 +2,7 @@ import { beforeEach, describe, expect } from 'vitest' import { LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph' -import { test } from './fixtures/testExtensions' +import { test } from './__fixtures__/testExtensions' describe('LGraphNode resize functionality', () => { let node: LGraphNode diff --git a/tests-ui/tests/litegraph/core/LGraphNode.test.ts b/src/lib/litegraph/src/LGraphNode.test.ts similarity index 99% rename from tests-ui/tests/litegraph/core/LGraphNode.test.ts rename to src/lib/litegraph/src/LGraphNode.test.ts index a08a228f2..6451e7dfe 100644 --- a/tests-ui/tests/litegraph/core/LGraphNode.test.ts +++ b/src/lib/litegraph/src/LGraphNode.test.ts @@ -13,7 +13,7 @@ import { NodeOutputSlot } from '@/lib/litegraph/src/litegraph' -import { test } from './fixtures/testExtensions' +import { test } from './__fixtures__/testExtensions' function getMockISerialisedNode( data: Partial diff --git a/tests-ui/tests/litegraph/core/LGraphNode.titleButtons.test.ts b/src/lib/litegraph/src/LGraphNode.titleButtons.test.ts similarity index 98% rename from tests-ui/tests/litegraph/core/LGraphNode.titleButtons.test.ts rename to src/lib/litegraph/src/LGraphNode.titleButtons.test.ts index 6599d6562..1c645cfd9 100644 --- a/tests-ui/tests/litegraph/core/LGraphNode.titleButtons.test.ts +++ b/src/lib/litegraph/src/LGraphNode.titleButtons.test.ts @@ -1,8 +1,7 @@ import { describe, expect, it, vi } from 'vitest' -import { LGraphButton } from '@/lib/litegraph/src/litegraph' import type { LGraphCanvas } from '@/lib/litegraph/src/litegraph' -import { LGraphNode } from '@/lib/litegraph/src/litegraph' +import { LGraphButton, LGraphNode } from '@/lib/litegraph/src/litegraph' describe('LGraphNode Title Buttons', () => { describe('addTitleButton', () => { diff --git a/tests-ui/tests/litegraph/core/LGraphNode.widgetOrder.test.ts b/src/lib/litegraph/src/LGraphNode.widgetOrder.test.ts similarity index 100% rename from tests-ui/tests/litegraph/core/LGraphNode.widgetOrder.test.ts rename to src/lib/litegraph/src/LGraphNode.widgetOrder.test.ts diff --git a/tests-ui/tests/litegraph/core/LGraphNodeProperties.test.ts b/src/lib/litegraph/src/LGraphNodeProperties.test.ts similarity index 100% rename from tests-ui/tests/litegraph/core/LGraphNodeProperties.test.ts rename to src/lib/litegraph/src/LGraphNodeProperties.test.ts diff --git a/tests-ui/tests/litegraph/core/LLink.test.ts b/src/lib/litegraph/src/LLink.test.ts similarity index 89% rename from tests-ui/tests/litegraph/core/LLink.test.ts rename to src/lib/litegraph/src/LLink.test.ts index a1cdfbea0..fc3f5918b 100644 --- a/tests-ui/tests/litegraph/core/LLink.test.ts +++ b/src/lib/litegraph/src/LLink.test.ts @@ -2,7 +2,7 @@ import { describe, expect } from 'vitest' import { LLink } from '@/lib/litegraph/src/litegraph' -import { test } from './fixtures/testExtensions' +import { test } from './__fixtures__/testExtensions' describe('LLink', () => { test('matches previous snapshot', () => { diff --git a/tests-ui/tests/litegraph/core/fixtures/assets/floatingBranch.json b/src/lib/litegraph/src/__fixtures__/assets/floatingBranch.json similarity index 100% rename from tests-ui/tests/litegraph/core/fixtures/assets/floatingBranch.json rename to src/lib/litegraph/src/__fixtures__/assets/floatingBranch.json diff --git a/tests-ui/tests/litegraph/core/fixtures/assets/floatingLink.json b/src/lib/litegraph/src/__fixtures__/assets/floatingLink.json similarity index 100% rename from tests-ui/tests/litegraph/core/fixtures/assets/floatingLink.json rename to src/lib/litegraph/src/__fixtures__/assets/floatingLink.json diff --git a/tests-ui/tests/litegraph/core/fixtures/assets/linkedNodes.json b/src/lib/litegraph/src/__fixtures__/assets/linkedNodes.json similarity index 100% rename from tests-ui/tests/litegraph/core/fixtures/assets/linkedNodes.json rename to src/lib/litegraph/src/__fixtures__/assets/linkedNodes.json diff --git a/tests-ui/tests/litegraph/core/fixtures/assets/reroutesComplex.json b/src/lib/litegraph/src/__fixtures__/assets/reroutesComplex.json similarity index 100% rename from tests-ui/tests/litegraph/core/fixtures/assets/reroutesComplex.json rename to src/lib/litegraph/src/__fixtures__/assets/reroutesComplex.json diff --git a/tests-ui/tests/litegraph/core/fixtures/assets/testGraphs.ts b/src/lib/litegraph/src/__fixtures__/assets/testGraphs.ts similarity index 100% rename from tests-ui/tests/litegraph/core/fixtures/assets/testGraphs.ts rename to src/lib/litegraph/src/__fixtures__/assets/testGraphs.ts diff --git a/tests-ui/tests/litegraph/core/fixtures/testExtensions.ts b/src/lib/litegraph/src/__fixtures__/testExtensions.ts similarity index 93% rename from tests-ui/tests/litegraph/core/fixtures/testExtensions.ts rename to src/lib/litegraph/src/__fixtures__/testExtensions.ts index 300b23814..6aff55438 100644 --- a/tests-ui/tests/litegraph/core/fixtures/testExtensions.ts +++ b/src/lib/litegraph/src/__fixtures__/testExtensions.ts @@ -1,3 +1,4 @@ +// oxlint-disable no-empty-pattern import { test as baseTest } from 'vitest' import { LGraph } from '@/lib/litegraph/src/LGraph' @@ -33,7 +34,6 @@ interface DirtyFixtures { } export const test = baseTest.extend({ - // eslint-disable-next-line no-empty-pattern minimalGraph: async ({}, use) => { // Before each test function const serialisable = structuredClone(minimalSerialisableGraph) @@ -48,7 +48,7 @@ export const test = baseTest.extend({ floatingLink as unknown as ISerialisedGraph ), linkedNodesGraph: structuredClone(linkedNodes as unknown as ISerialisedGraph), - // eslint-disable-next-line no-empty-pattern + floatingBranchGraph: async ({}, use) => { const cloned = structuredClone( floatingBranch as unknown as ISerialisedGraph @@ -56,7 +56,7 @@ export const test = baseTest.extend({ const graph = new LGraph(cloned) await use(graph) }, - // eslint-disable-next-line no-empty-pattern + reroutesComplexGraph: async ({}, use) => { const cloned = structuredClone( reroutesComplex as unknown as ISerialisedGraph @@ -68,7 +68,6 @@ export const test = baseTest.extend({ /** Test that use {@link DirtyFixtures}. One test per file. */ export const dirtyTest = test.extend({ - // eslint-disable-next-line no-empty-pattern basicSerialisableGraph: async ({}, use) => { if (!basicSerialisableGraph.nodes) throw new Error('Invalid test object') diff --git a/tests-ui/tests/litegraph/core/__snapshots__/LGraph.test.ts.snap b/src/lib/litegraph/src/__snapshots__/LGraph.test.ts.snap similarity index 100% rename from tests-ui/tests/litegraph/core/__snapshots__/LGraph.test.ts.snap rename to src/lib/litegraph/src/__snapshots__/LGraph.test.ts.snap diff --git a/tests-ui/tests/litegraph/core/__snapshots__/LGraphGroup.test.ts.snap b/src/lib/litegraph/src/__snapshots__/LGraphGroup.test.ts.snap similarity index 100% rename from tests-ui/tests/litegraph/core/__snapshots__/LGraphGroup.test.ts.snap rename to src/lib/litegraph/src/__snapshots__/LGraphGroup.test.ts.snap diff --git a/tests-ui/tests/litegraph/core/__snapshots__/LLink.test.ts.snap b/src/lib/litegraph/src/__snapshots__/LLink.test.ts.snap similarity index 100% rename from tests-ui/tests/litegraph/core/__snapshots__/LLink.test.ts.snap rename to src/lib/litegraph/src/__snapshots__/LLink.test.ts.snap diff --git a/tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap b/src/lib/litegraph/src/__snapshots__/litegraph.test.ts.snap similarity index 100% rename from tests-ui/tests/litegraph/core/__snapshots__/litegraph.test.ts.snap rename to src/lib/litegraph/src/__snapshots__/litegraph.test.ts.snap diff --git a/tests-ui/tests/litegraph/core/LinkConnector.test.ts b/src/lib/litegraph/src/canvas/LinkConnector.core.test.ts similarity index 93% rename from tests-ui/tests/litegraph/core/LinkConnector.test.ts rename to src/lib/litegraph/src/canvas/LinkConnector.core.test.ts index 52faacf56..65b468940 100644 --- a/tests-ui/tests/litegraph/core/LinkConnector.test.ts +++ b/src/lib/litegraph/src/canvas/LinkConnector.core.test.ts @@ -1,23 +1,27 @@ +// oxlint-disable no-empty-pattern import { test as baseTest, describe, expect, vi } from 'vitest' -import { LinkConnector } from '@/lib/litegraph/src/litegraph' -import type { MovingInputLink } from '@/lib/litegraph/src/litegraph' -import { ToInputRenderLink } from '@/lib/litegraph/src/litegraph' -import type { LinkNetwork } from '@/lib/litegraph/src/litegraph' -import type { ISlotType } from '@/lib/litegraph/src/litegraph' +import type { + MovingInputLink, + RerouteId, + LinkNetwork, + ISlotType +} from '@/lib/litegraph/src/litegraph' import { LGraph, LGraphNode, LLink, Reroute, - type RerouteId + LinkConnector, + ToInputRenderLink, + LinkDirection } from '@/lib/litegraph/src/litegraph' -import { LinkDirection } from '@/lib/litegraph/src/litegraph' +import type { ConnectingLink } from '@/lib/litegraph/src/interfaces' interface TestContext { network: LinkNetwork & { add(node: LGraphNode): void } connector: LinkConnector - setConnectingLinks: ReturnType + setConnectingLinks: (value: ConnectingLink[]) => void createTestNode: (id: number, slotType?: ISlotType) => LGraphNode createTestLink: ( id: number, @@ -28,7 +32,6 @@ interface TestContext { } const test = baseTest.extend({ - // eslint-disable-next-line no-empty-pattern network: async ({}, use) => { const graph = new LGraph() const floatingLinks = new Map() @@ -53,9 +56,8 @@ const test = baseTest.extend({ }, setConnectingLinks: async ( - // eslint-disable-next-line no-empty-pattern {}, - use: (mock: ReturnType) => Promise + use: (mock: (value: ConnectingLink[]) => void) => Promise ) => { const mock = vi.fn() await use(mock) diff --git a/tests-ui/tests/litegraph/core/LinkConnector.integration.test.ts b/src/lib/litegraph/src/canvas/LinkConnector.integration.test.ts similarity index 98% rename from tests-ui/tests/litegraph/core/LinkConnector.integration.test.ts rename to src/lib/litegraph/src/canvas/LinkConnector.integration.test.ts index da99d9135..3c4368c5a 100644 --- a/tests-ui/tests/litegraph/core/LinkConnector.integration.test.ts +++ b/src/lib/litegraph/src/canvas/LinkConnector.integration.test.ts @@ -1,21 +1,22 @@ +// oxlint-disable no-empty-pattern // TODO: Fix these tests after migration import { afterEach, describe, expect, vi } from 'vitest' -import type { LGraph, Reroute } from '@/lib/litegraph/src/litegraph' -import { - type CanvasPointerEvent, - LGraphNode, - LLink, - LinkConnector, - type RerouteId +import type { + LGraph, + Reroute, + CanvasPointerEvent, + RerouteId } from '@/lib/litegraph/src/litegraph' +import { LGraphNode, LLink, LinkConnector } from '@/lib/litegraph/src/litegraph' -import { test as baseTest } from './fixtures/testExtensions' +import { test as baseTest } from '../__fixtures__/testExtensions' +import type { ConnectingLink } from '@/lib/litegraph/src/interfaces' interface TestContext { graph: LGraph connector: LinkConnector - setConnectingLinks: ReturnType + setConnectingLinks: (value: ConnectingLink[]) => void createTestNode: (id: number) => LGraphNode reroutesBeforeTest: [rerouteId: RerouteId, reroute: Reroute][] validateIntegrityNoChanges: () => void @@ -41,9 +42,8 @@ const test = baseTest.extend({ await use(reroutesComplexGraph) }, setConnectingLinks: async ( - // eslint-disable-next-line no-empty-pattern {}, - use: (mock: ReturnType) => Promise + use: (mock: (value: ConnectingLink[]) => void) => Promise ) => { const mock = vi.fn() await use(mock) @@ -1078,6 +1078,7 @@ describe('LinkConnector Integration', () => { const originalParentChain = LLink.getReroutes(graph, toReroute) const sortAndJoin = (numbers: Iterable) => + // oxlint-disable-next-line require-array-sort-compare [...numbers].sort().join(',') const hasIdenticalLinks = (a: Reroute, b: Reroute) => sortAndJoin(a.linkIds) === sortAndJoin(b.linkIds) && diff --git a/tests-ui/tests/litegraph/canvas/LinkConnector.test.ts b/src/lib/litegraph/src/canvas/LinkConnector.test.ts similarity index 100% rename from tests-ui/tests/litegraph/canvas/LinkConnector.test.ts rename to src/lib/litegraph/src/canvas/LinkConnector.test.ts diff --git a/tests-ui/tests/litegraph/canvas/LinkConnectorSubgraphInputValidation.test.ts b/src/lib/litegraph/src/canvas/LinkConnectorSubgraphInputValidation.test.ts similarity index 99% rename from tests-ui/tests/litegraph/canvas/LinkConnectorSubgraphInputValidation.test.ts rename to src/lib/litegraph/src/canvas/LinkConnectorSubgraphInputValidation.test.ts index 072a0fb4c..3d9740c4f 100644 --- a/tests-ui/tests/litegraph/canvas/LinkConnectorSubgraphInputValidation.test.ts +++ b/src/lib/litegraph/src/canvas/LinkConnectorSubgraphInputValidation.test.ts @@ -12,7 +12,7 @@ import { ToInputFromIoNodeLink } from '@/lib/litegraph/src/canvas/ToInputFromIoN import type { NodeInputSlot } from '@/lib/litegraph/src/litegraph' import { LinkDirection } from '@/lib/litegraph/src/types/globalEnums' -import { createTestSubgraph } from '../subgraph/fixtures/subgraphHelpers' +import { createTestSubgraph } from '../subgraph/__fixtures__/subgraphHelpers' describe('LinkConnector SubgraphInput connection validation', () => { let connector: LinkConnector diff --git a/tests-ui/tests/litegraph/core/ToOutputRenderLink.test.ts b/src/lib/litegraph/src/canvas/ToOutputRenderLink.test.ts similarity index 94% rename from tests-ui/tests/litegraph/core/ToOutputRenderLink.test.ts rename to src/lib/litegraph/src/canvas/ToOutputRenderLink.test.ts index 7899f8924..73bfec657 100644 --- a/tests-ui/tests/litegraph/core/ToOutputRenderLink.test.ts +++ b/src/lib/litegraph/src/canvas/ToOutputRenderLink.test.ts @@ -1,7 +1,9 @@ import { describe, expect, it, vi } from 'vitest' -import { ToOutputRenderLink } from '@/lib/litegraph/src/litegraph' -import { LinkDirection } from '@/lib/litegraph/src/litegraph' +import { + LinkDirection, + ToOutputRenderLink +} from '@/lib/litegraph/src/litegraph' describe('ToOutputRenderLink', () => { describe('connectToOutput', () => { diff --git a/tests-ui/tests/litegraph/core/contextMenuCompat.test.ts b/src/lib/litegraph/src/contextMenuCompat.test.ts similarity index 100% rename from tests-ui/tests/litegraph/core/contextMenuCompat.test.ts rename to src/lib/litegraph/src/contextMenuCompat.test.ts diff --git a/tests-ui/tests/litegraph/infrastructure/Rectangle.resize.test.ts b/src/lib/litegraph/src/infrastructure/Rectangle.resize.test.ts similarity index 100% rename from tests-ui/tests/litegraph/infrastructure/Rectangle.resize.test.ts rename to src/lib/litegraph/src/infrastructure/Rectangle.resize.test.ts diff --git a/tests-ui/tests/litegraph/infrastructure/Rectangle.test.ts b/src/lib/litegraph/src/infrastructure/Rectangle.test.ts similarity index 99% rename from tests-ui/tests/litegraph/infrastructure/Rectangle.test.ts rename to src/lib/litegraph/src/infrastructure/Rectangle.test.ts index b89545845..b4fc56091 100644 --- a/tests-ui/tests/litegraph/infrastructure/Rectangle.test.ts +++ b/src/lib/litegraph/src/infrastructure/Rectangle.test.ts @@ -1,3 +1,4 @@ +// oxlint-disable no-empty-pattern import { test as baseTest, describe, expect, vi } from 'vitest' import { Rectangle } from '@/lib/litegraph/src/litegraph' @@ -6,7 +7,6 @@ import type { Point, Size } from '@/lib/litegraph/src/litegraph' // TODO: If there's a common test context, use it here // For now, we'll define a simple context for Rectangle tests const test = baseTest.extend<{ rect: Rectangle }>({ - // eslint-disable-next-line no-empty-pattern rect: async ({}, use) => { await use(new Rectangle()) } diff --git a/tests-ui/tests/litegraph/core/litegraph.test.ts b/src/lib/litegraph/src/litegraph.test.ts similarity index 87% rename from tests-ui/tests/litegraph/core/litegraph.test.ts rename to src/lib/litegraph/src/litegraph.test.ts index cc58100fa..936b82f6e 100644 --- a/tests-ui/tests/litegraph/core/litegraph.test.ts +++ b/src/lib/litegraph/src/litegraph.test.ts @@ -1,10 +1,13 @@ import { clamp } from 'es-toolkit/compat' import { beforeEach, describe, expect, vi } from 'vitest' -import { LiteGraphGlobal } from '@/lib/litegraph/src/litegraph' -import { LGraphCanvas, LiteGraph } from '@/lib/litegraph/src/litegraph' +import { + LiteGraphGlobal, + LGraphCanvas, + LiteGraph +} from '@/lib/litegraph/src/litegraph' -import { test } from './fixtures/testExtensions' +import { test } from './__fixtures__/testExtensions' describe('Litegraph module', () => { test('contains a global export', ({ expect }) => { diff --git a/tests-ui/tests/litegraph/core/measure.test.ts b/src/lib/litegraph/src/measure.test.ts similarity index 100% rename from tests-ui/tests/litegraph/core/measure.test.ts rename to src/lib/litegraph/src/measure.test.ts diff --git a/tests-ui/tests/litegraph/core/NodeSlot.test.ts b/src/lib/litegraph/src/node/NodeSlot.test.ts similarity index 100% rename from tests-ui/tests/litegraph/core/NodeSlot.test.ts rename to src/lib/litegraph/src/node/NodeSlot.test.ts diff --git a/tests-ui/tests/litegraph/subgraph/ExecutableNodeDTO.test.ts b/src/lib/litegraph/src/subgraph/ExecutableNodeDTO.test.ts similarity index 98% rename from tests-ui/tests/litegraph/subgraph/ExecutableNodeDTO.test.ts rename to src/lib/litegraph/src/subgraph/ExecutableNodeDTO.test.ts index 4418d9422..003fa59e1 100644 --- a/tests-ui/tests/litegraph/subgraph/ExecutableNodeDTO.test.ts +++ b/src/lib/litegraph/src/subgraph/ExecutableNodeDTO.test.ts @@ -1,14 +1,17 @@ // TODO: Fix these tests after migration import { describe, expect, it, vi } from 'vitest' -import { LGraph, LGraphNode } from '@/lib/litegraph/src/litegraph' -import { ExecutableNodeDTO } from '@/lib/litegraph/src/litegraph' +import { + LGraph, + LGraphNode, + ExecutableNodeDTO +} from '@/lib/litegraph/src/litegraph' import { createNestedSubgraphs, createTestSubgraph, createTestSubgraphNode -} from './fixtures/subgraphHelpers' +} from './__fixtures__/subgraphHelpers' describe.skip('ExecutableNodeDTO Creation', () => { it('should create DTO from regular node', () => { diff --git a/tests-ui/tests/litegraph/subgraph/Subgraph.test.ts b/src/lib/litegraph/src/subgraph/Subgraph.test.ts similarity index 97% rename from tests-ui/tests/litegraph/subgraph/Subgraph.test.ts rename to src/lib/litegraph/src/subgraph/Subgraph.test.ts index 773bcca00..4266a6073 100644 --- a/tests-ui/tests/litegraph/subgraph/Subgraph.test.ts +++ b/src/lib/litegraph/src/subgraph/Subgraph.test.ts @@ -8,16 +8,19 @@ */ import { describe, expect, it } from 'vitest' -import { RecursionError } from '@/lib/litegraph/src/litegraph' -import { LGraph, Subgraph } from '@/lib/litegraph/src/litegraph' -import { createUuidv4 } from '@/lib/litegraph/src/litegraph' +import { + createUuidv4, + RecursionError, + LGraph, + Subgraph +} from '@/lib/litegraph/src/litegraph' -import { subgraphTest } from './fixtures/subgraphFixtures' +import { subgraphTest } from './__fixtures__/subgraphFixtures' import { assertSubgraphStructure, createTestSubgraph, createTestSubgraphData -} from './fixtures/subgraphHelpers' +} from './__fixtures__/subgraphHelpers' describe.skip('Subgraph Construction', () => { it('should create a subgraph with minimal data', () => { diff --git a/tests-ui/tests/litegraph/subgraph/SubgraphConversion.test.ts b/src/lib/litegraph/src/subgraph/SubgraphConversion.test.ts similarity index 98% rename from tests-ui/tests/litegraph/subgraph/SubgraphConversion.test.ts rename to src/lib/litegraph/src/subgraph/SubgraphConversion.test.ts index f978710ae..4e5cbae35 100644 --- a/tests-ui/tests/litegraph/subgraph/SubgraphConversion.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphConversion.test.ts @@ -1,18 +1,17 @@ // TODO: Fix these tests after migration import { assert, describe, expect, it } from 'vitest' -import type { LGraph } from '@/lib/litegraph/src/litegraph' import { - type ISlotType, LGraphGroup, LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph' +import type { LGraph, ISlotType } from '@/lib/litegraph/src/litegraph' import { createTestSubgraph, createTestSubgraphNode -} from './fixtures/subgraphHelpers' +} from './__fixtures__/subgraphHelpers' function createNode( graph: LGraph, diff --git a/tests-ui/tests/litegraph/subgraph/SubgraphEdgeCases.test.ts b/src/lib/litegraph/src/subgraph/SubgraphEdgeCases.test.ts similarity index 99% rename from tests-ui/tests/litegraph/subgraph/SubgraphEdgeCases.test.ts rename to src/lib/litegraph/src/subgraph/SubgraphEdgeCases.test.ts index 8734575b1..3251a4d88 100644 --- a/tests-ui/tests/litegraph/subgraph/SubgraphEdgeCases.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphEdgeCases.test.ts @@ -13,7 +13,7 @@ import { createNestedSubgraphs, createTestSubgraph, createTestSubgraphNode -} from './fixtures/subgraphHelpers' +} from './__fixtures__/subgraphHelpers' describe.skip('SubgraphEdgeCases - Recursion Detection', () => { it('should handle circular subgraph references without crashing', () => { diff --git a/tests-ui/tests/litegraph/subgraph/SubgraphEvents.test.ts b/src/lib/litegraph/src/subgraph/SubgraphEvents.test.ts similarity index 99% rename from tests-ui/tests/litegraph/subgraph/SubgraphEvents.test.ts rename to src/lib/litegraph/src/subgraph/SubgraphEvents.test.ts index abff4fa7a..ade35e919 100644 --- a/tests-ui/tests/litegraph/subgraph/SubgraphEvents.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphEvents.test.ts @@ -1,8 +1,8 @@ // TODO: Fix these tests after migration import { describe, expect, vi } from 'vitest' -import { subgraphTest } from './fixtures/subgraphFixtures' -import { verifyEventSequence } from './fixtures/subgraphHelpers' +import { subgraphTest } from './__fixtures__/subgraphFixtures' +import { verifyEventSequence } from './__fixtures__/subgraphHelpers' describe.skip('SubgraphEvents - Event Payload Verification', () => { subgraphTest( diff --git a/tests-ui/tests/litegraph/subgraph/SubgraphIO.test.ts b/src/lib/litegraph/src/subgraph/SubgraphIO.test.ts similarity index 99% rename from tests-ui/tests/litegraph/subgraph/SubgraphIO.test.ts rename to src/lib/litegraph/src/subgraph/SubgraphIO.test.ts index 25f2ecd10..c3fa79970 100644 --- a/tests-ui/tests/litegraph/subgraph/SubgraphIO.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphIO.test.ts @@ -5,11 +5,11 @@ import { LGraphNode } from '@/lib/litegraph/src/litegraph' import { ToInputFromIoNodeLink } from '@/lib/litegraph/src/canvas/ToInputFromIoNodeLink' import { LinkDirection } from '@/lib/litegraph/src//types/globalEnums' -import { subgraphTest } from './fixtures/subgraphFixtures' +import { subgraphTest } from './__fixtures__/subgraphFixtures' import { createTestSubgraph, createTestSubgraphNode -} from './fixtures/subgraphHelpers' +} from './__fixtures__/subgraphHelpers' describe('SubgraphIO - Input Slot Dual-Nature Behavior', () => { subgraphTest( diff --git a/tests-ui/tests/litegraph/subgraph/SubgraphMemory.test.ts b/src/lib/litegraph/src/subgraph/SubgraphMemory.test.ts similarity index 99% rename from tests-ui/tests/litegraph/subgraph/SubgraphMemory.test.ts rename to src/lib/litegraph/src/subgraph/SubgraphMemory.test.ts index 5e6770d1e..6a4e662bf 100644 --- a/tests-ui/tests/litegraph/subgraph/SubgraphMemory.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphMemory.test.ts @@ -3,11 +3,11 @@ import { describe, expect, it, vi } from 'vitest' import { LGraph } from '@/lib/litegraph/src/litegraph' -import { subgraphTest } from './fixtures/subgraphFixtures' +import { subgraphTest } from './__fixtures__/subgraphFixtures' import { createTestSubgraph, createTestSubgraphNode -} from './fixtures/subgraphHelpers' +} from './__fixtures__/subgraphHelpers' describe.skip('SubgraphNode Memory Management', () => { describe.skip('Event Listener Cleanup', () => { diff --git a/tests-ui/tests/litegraph/subgraph/SubgraphNode.test.ts b/src/lib/litegraph/src/subgraph/SubgraphNode.test.ts similarity index 99% rename from tests-ui/tests/litegraph/subgraph/SubgraphNode.test.ts rename to src/lib/litegraph/src/subgraph/SubgraphNode.test.ts index 40ad062c6..e82e03149 100644 --- a/tests-ui/tests/litegraph/subgraph/SubgraphNode.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphNode.test.ts @@ -9,11 +9,11 @@ import { describe, expect, it, vi } from 'vitest' import { LGraph, Subgraph } from '@/lib/litegraph/src/litegraph' -import { subgraphTest } from './fixtures/subgraphFixtures' +import { subgraphTest } from './__fixtures__/subgraphFixtures' import { createTestSubgraph, createTestSubgraphNode -} from './fixtures/subgraphHelpers' +} from './__fixtures__/subgraphHelpers' describe.skip('SubgraphNode Construction', () => { it('should create a SubgraphNode from a subgraph definition', () => { diff --git a/tests-ui/tests/litegraph/subgraph/SubgraphNode.titleButton.test.ts b/src/lib/litegraph/src/subgraph/SubgraphNode.titleButton.test.ts similarity index 99% rename from tests-ui/tests/litegraph/subgraph/SubgraphNode.titleButton.test.ts rename to src/lib/litegraph/src/subgraph/SubgraphNode.titleButton.test.ts index 9bc64802c..c76e9d5ee 100644 --- a/tests-ui/tests/litegraph/subgraph/SubgraphNode.titleButton.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphNode.titleButton.test.ts @@ -7,7 +7,7 @@ import type { LGraphCanvas } from '@/lib/litegraph/src/litegraph' import { createTestSubgraph, createTestSubgraphNode -} from './fixtures/subgraphHelpers' +} from './__fixtures__/subgraphHelpers' describe.skip('SubgraphNode Title Button', () => { describe.skip('Constructor', () => { diff --git a/tests-ui/tests/litegraph/subgraph/SubgraphSerialization.test.ts b/src/lib/litegraph/src/subgraph/SubgraphSerialization.test.ts similarity index 99% rename from tests-ui/tests/litegraph/subgraph/SubgraphSerialization.test.ts rename to src/lib/litegraph/src/subgraph/SubgraphSerialization.test.ts index 35e113b0e..f773fe63d 100644 --- a/tests-ui/tests/litegraph/subgraph/SubgraphSerialization.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphSerialization.test.ts @@ -12,7 +12,7 @@ import { LGraph, Subgraph } from '@/lib/litegraph/src/litegraph' import { createTestSubgraph, createTestSubgraphNode -} from './fixtures/subgraphHelpers' +} from './__fixtures__/subgraphHelpers' describe.skip('SubgraphSerialization - Basic Serialization', () => { it('should save and load simple subgraphs', () => { diff --git a/tests-ui/tests/litegraph/subgraph/SubgraphSlotConnections.test.ts b/src/lib/litegraph/src/subgraph/SubgraphSlotConnections.test.ts similarity index 96% rename from tests-ui/tests/litegraph/subgraph/SubgraphSlotConnections.test.ts rename to src/lib/litegraph/src/subgraph/SubgraphSlotConnections.test.ts index 0c10b782a..515c0ac22 100644 --- a/tests-ui/tests/litegraph/subgraph/SubgraphSlotConnections.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphSlotConnections.test.ts @@ -1,21 +1,24 @@ // TODO: Fix these tests after migration import { describe, expect, it, vi } from 'vitest' -import { LinkConnector } from '@/lib/litegraph/src/litegraph' -import { ToInputFromIoNodeLink } from '@/lib/litegraph/src/litegraph' -import { SUBGRAPH_INPUT_ID } from '@/lib/litegraph/src/litegraph' -import { LGraphNode, type LinkNetwork } from '@/lib/litegraph/src/litegraph' -import type { NodeInputSlot } from '@/lib/litegraph/src/litegraph' -import type { NodeOutputSlot } from '@/lib/litegraph/src/litegraph' import { + SUBGRAPH_INPUT_ID, + LinkConnector, + ToInputFromIoNodeLink, + LGraphNode, isSubgraphInput, isSubgraphOutput } from '@/lib/litegraph/src/litegraph' +import type { + LinkNetwork, + NodeInputSlot, + NodeOutputSlot +} from '@/lib/litegraph/src/litegraph' import { createTestSubgraph, createTestSubgraphNode -} from './fixtures/subgraphHelpers' +} from './__fixtures__/subgraphHelpers' describe.skip('Subgraph slot connections', () => { describe.skip('SubgraphInput connections', () => { diff --git a/tests-ui/tests/litegraph/subgraph/SubgraphSlotVisualFeedback.test.ts b/src/lib/litegraph/src/subgraph/SubgraphSlotVisualFeedback.test.ts similarity index 98% rename from tests-ui/tests/litegraph/subgraph/SubgraphSlotVisualFeedback.test.ts rename to src/lib/litegraph/src/subgraph/SubgraphSlotVisualFeedback.test.ts index 0ed819a4f..baf842812 100644 --- a/tests-ui/tests/litegraph/subgraph/SubgraphSlotVisualFeedback.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphSlotVisualFeedback.test.ts @@ -3,7 +3,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' import { LGraphNode } from '@/lib/litegraph/src/litegraph' -import { createTestSubgraph } from './fixtures/subgraphHelpers' +import { createTestSubgraph } from './__fixtures__/subgraphHelpers' describe.skip('SubgraphSlot visual feedback', () => { let mockCtx: CanvasRenderingContext2D diff --git a/tests-ui/tests/litegraph/subgraph/SubgraphWidgetPromotion.test.ts b/src/lib/litegraph/src/subgraph/SubgraphWidgetPromotion.test.ts similarity index 97% rename from tests-ui/tests/litegraph/subgraph/SubgraphWidgetPromotion.test.ts rename to src/lib/litegraph/src/subgraph/SubgraphWidgetPromotion.test.ts index 36793829d..d938b300a 100644 --- a/tests-ui/tests/litegraph/subgraph/SubgraphWidgetPromotion.test.ts +++ b/src/lib/litegraph/src/subgraph/SubgraphWidgetPromotion.test.ts @@ -1,16 +1,18 @@ // TODO: Fix these tests after migration import { describe, expect, it } from 'vitest' -import type { ISlotType, Subgraph } from '@/lib/litegraph/src/litegraph' -import { LGraphNode } from '@/lib/litegraph/src/litegraph' -import type { TWidgetType } from '@/lib/litegraph/src/litegraph' -import { BaseWidget } from '@/lib/litegraph/src/litegraph' +import type { + ISlotType, + Subgraph, + TWidgetType +} from '@/lib/litegraph/src/litegraph' +import { BaseWidget, LGraphNode } from '@/lib/litegraph/src/litegraph' import { createEventCapture, createTestSubgraph, createTestSubgraphNode -} from './fixtures/subgraphHelpers' +} from './__fixtures__/subgraphHelpers' // Helper to create a node with a widget function createNodeWithWidget( diff --git a/tests-ui/tests/litegraph/subgraph/fixtures/README.md b/src/lib/litegraph/src/subgraph/__fixtures__/README.md similarity index 100% rename from tests-ui/tests/litegraph/subgraph/fixtures/README.md rename to src/lib/litegraph/src/subgraph/__fixtures__/README.md diff --git a/tests-ui/tests/litegraph/subgraph/fixtures/subgraphFixtures.ts b/src/lib/litegraph/src/subgraph/__fixtures__/subgraphFixtures.ts similarity index 93% rename from tests-ui/tests/litegraph/subgraph/fixtures/subgraphFixtures.ts rename to src/lib/litegraph/src/subgraph/__fixtures__/subgraphFixtures.ts index 02134868c..6f88d1c8f 100644 --- a/tests-ui/tests/litegraph/subgraph/fixtures/subgraphFixtures.ts +++ b/src/lib/litegraph/src/subgraph/__fixtures__/subgraphFixtures.ts @@ -1,3 +1,4 @@ +// oxlint-disable no-empty-pattern /** * Vitest Fixtures for Subgraph Testing * @@ -9,7 +10,7 @@ import type { Subgraph } from '@/lib/litegraph/src/litegraph' import { LGraph } from '@/lib/litegraph/src/litegraph' import type { SubgraphNode } from '@/lib/litegraph/src/subgraph/SubgraphNode' -import { test } from '../../core/fixtures/testExtensions' +import { test } from '../../__fixtures__/testExtensions' import { createEventCapture, createNestedSubgraphs, @@ -59,7 +60,7 @@ interface SubgraphFixtures { */ export const subgraphTest = test.extend({ // @ts-expect-error TODO: Fix after merge - fixture use parameter type - // eslint-disable-next-line no-empty-pattern + emptySubgraph: async ({}, use: (value: unknown) => Promise) => { const subgraph = createTestSubgraph({ name: 'Empty Test Subgraph', @@ -72,7 +73,7 @@ export const subgraphTest = test.extend({ }, // @ts-expect-error TODO: Fix after merge - fixture use parameter type - // eslint-disable-next-line no-empty-pattern + simpleSubgraph: async ({}, use: (value: unknown) => Promise) => { const subgraph = createTestSubgraph({ name: 'Simple Test Subgraph', @@ -85,7 +86,7 @@ export const subgraphTest = test.extend({ }, // @ts-expect-error TODO: Fix after merge - fixture use parameter type - // eslint-disable-next-line no-empty-pattern + complexSubgraph: async ({}, use: (value: unknown) => Promise) => { const subgraph = createTestSubgraph({ name: 'Complex Test Subgraph', @@ -105,7 +106,7 @@ export const subgraphTest = test.extend({ }, // @ts-expect-error TODO: Fix after merge - fixture use parameter type - // eslint-disable-next-line no-empty-pattern + nestedSubgraph: async ({}, use: (value: unknown) => Promise) => { const nested = createNestedSubgraphs({ depth: 3, @@ -118,7 +119,7 @@ export const subgraphTest = test.extend({ }, // @ts-expect-error TODO: Fix after merge - fixture use parameter type - // eslint-disable-next-line no-empty-pattern + subgraphWithNode: async ({}, use: (value: unknown) => Promise) => { // Create the subgraph definition const subgraph = createTestSubgraph({ @@ -146,7 +147,7 @@ export const subgraphTest = test.extend({ }, // @ts-expect-error TODO: Fix after merge - fixture use parameter type - // eslint-disable-next-line no-empty-pattern + eventCapture: async ({}, use: (value: unknown) => Promise) => { const subgraph = createTestSubgraph({ name: 'Event Test Subgraph' diff --git a/tests-ui/tests/litegraph/subgraph/fixtures/subgraphHelpers.ts b/src/lib/litegraph/src/subgraph/__fixtures__/subgraphHelpers.ts similarity index 100% rename from tests-ui/tests/litegraph/subgraph/fixtures/subgraphHelpers.ts rename to src/lib/litegraph/src/subgraph/__fixtures__/subgraphHelpers.ts diff --git a/tests-ui/tests/litegraph/subgraph/fixtures/testSubgraphs.json b/src/lib/litegraph/src/subgraph/__fixtures__/testSubgraphs.json similarity index 100% rename from tests-ui/tests/litegraph/subgraph/fixtures/testSubgraphs.json rename to src/lib/litegraph/src/subgraph/__fixtures__/testSubgraphs.json diff --git a/tests-ui/tests/litegraph/subgraph/subgraphUtils.test.ts b/src/lib/litegraph/src/subgraph/subgraphUtils.test.ts similarity index 98% rename from tests-ui/tests/litegraph/subgraph/subgraphUtils.test.ts rename to src/lib/litegraph/src/subgraph/subgraphUtils.test.ts index c1cea490f..a5f5893b0 100644 --- a/tests-ui/tests/litegraph/subgraph/subgraphUtils.test.ts +++ b/src/lib/litegraph/src/subgraph/subgraphUtils.test.ts @@ -1,8 +1,8 @@ // TODO: Fix these tests after migration import { describe, expect, it } from 'vitest' -import { LGraph } from '@/lib/litegraph/src/litegraph' import { + LGraph, findUsedSubgraphIds, getDirectSubgraphIds } from '@/lib/litegraph/src/litegraph' @@ -11,7 +11,7 @@ import type { UUID } from '@/lib/litegraph/src/litegraph' import { createTestSubgraph, createTestSubgraphNode -} from './fixtures/subgraphHelpers' +} from './__fixtures__/subgraphHelpers' describe.skip('subgraphUtils', () => { describe.skip('getDirectSubgraphIds', () => { diff --git a/tests-ui/tests/litegraph/utils/spaceDistribution.test.ts b/src/lib/litegraph/src/utils/spaceDistribution.test.ts similarity index 90% rename from tests-ui/tests/litegraph/utils/spaceDistribution.test.ts rename to src/lib/litegraph/src/utils/spaceDistribution.test.ts index 4d029762f..254c13da6 100644 --- a/tests-ui/tests/litegraph/utils/spaceDistribution.test.ts +++ b/src/lib/litegraph/src/utils/spaceDistribution.test.ts @@ -1,9 +1,7 @@ import { describe, expect, it } from 'vitest' -import { - type SpaceRequest, - distributeSpace -} from '@/lib/litegraph/src/litegraph' +import { distributeSpace } from '@/lib/litegraph/src/litegraph' +import type { SpaceRequest } from '@/lib/litegraph/src/litegraph' describe('distributeSpace', () => { it('should distribute space according to minimum sizes when space is limited', () => { diff --git a/tests-ui/tests/litegraph/utils/textUtils.test.ts b/src/lib/litegraph/src/utils/textUtils.test.ts similarity index 100% rename from tests-ui/tests/litegraph/utils/textUtils.test.ts rename to src/lib/litegraph/src/utils/textUtils.test.ts diff --git a/tests-ui/tests/litegraph/utils/widget.test.ts b/src/lib/litegraph/src/utils/widget.test.ts similarity index 100% rename from tests-ui/tests/litegraph/utils/widget.test.ts rename to src/lib/litegraph/src/utils/widget.test.ts diff --git a/tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts b/src/lib/litegraph/src/widgets/ComboWidget.test.ts similarity index 94% rename from tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts rename to src/lib/litegraph/src/widgets/ComboWidget.test.ts index e3b9ef6cd..b1605906f 100644 --- a/tests-ui/tests/lib/litegraph/src/widgets/ComboWidget.test.ts +++ b/src/lib/litegraph/src/widgets/ComboWidget.test.ts @@ -1,23 +1,16 @@ import { beforeEach, describe, expect, it, vi } from 'vitest' +import type * as LGraphCanvasModule from '@/lib/litegraph/src/LGraphCanvas' import { LGraphNode, LiteGraph } from '@/lib/litegraph/src/litegraph' import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events' import type { IComboWidget } from '@/lib/litegraph/src/types/widgets' import { ComboWidget } from '@/lib/litegraph/src/widgets/ComboWidget' -const { LGraphCanvas } = await vi.importActual< - typeof import('@/lib/litegraph/src/LGraphCanvas') ->('@/lib/litegraph/src/LGraphCanvas') +const { LGraphCanvas } = await vi.importActual( + '@/lib/litegraph/src/LGraphCanvas' +) type LGraphCanvasType = InstanceType -type ContextMenuInstance = { - addItem?: ( - name: string, - value: string, - options: { callback?: (value: string) => void; className?: string } - ) => void -} - interface MockWidgetConfig extends Omit { options: IComboWidget['options'] } @@ -465,12 +458,12 @@ describe('ComboWidget', () => { node.size = [200, 30] let capturedCallback: ((value: string) => void) | undefined - const mockContextMenu = vi.fn((_values, options) => { - capturedCallback = options.callback - return {} as ContextMenuInstance - }) - LiteGraph.ContextMenu = - mockContextMenu as unknown as typeof LiteGraph.ContextMenu + const mockContextMenu = vi + .fn() + .mockImplementation(function (_values, options) { + capturedCallback = options.callback + }) + LiteGraph.ContextMenu = mockContextMenu const setValueSpy = vi.spyOn(widget, 'setValue') widget.onClick({ e: mockEvent, node, canvas: mockCanvas }) @@ -507,12 +500,12 @@ describe('ComboWidget', () => { node.size = [200, 30] let capturedCallback: ((value: string) => void) | undefined - const mockContextMenu = vi.fn((_values, options) => { - capturedCallback = options.callback - return {} as ContextMenuInstance - }) - LiteGraph.ContextMenu = - mockContextMenu as unknown as typeof LiteGraph.ContextMenu + const mockContextMenu = vi + .fn() + .mockImplementation(function (_values, options) { + capturedCallback = options.callback + }) + LiteGraph.ContextMenu = mockContextMenu const setValueSpy = vi.spyOn(widget, 'setValue') widget.onClick({ e: mockEvent, node, canvas: mockCanvas }) @@ -653,7 +646,7 @@ describe('ComboWidget', () => { }) it('should handle getOptionLabel error gracefully', () => { - const mockGetOptionLabel = vi.fn().mockImplementation(() => { + const mockGetOptionLabel = vi.fn().mockImplementation(function () { throw new Error('Formatting failed') }) const consoleErrorSpy = vi @@ -768,9 +761,12 @@ describe('ComboWidget', () => { node.size = [200, 30] const mockAddItem = vi.fn() - const mockContextMenu = vi.fn(() => ({ addItem: mockAddItem })) - LiteGraph.ContextMenu = - mockContextMenu as unknown as typeof LiteGraph.ContextMenu + const mockContextMenu = vi + .fn() + .mockImplementation(function () { + this.addItem = mockAddItem + }) + LiteGraph.ContextMenu = mockContextMenu widget.onClick({ e: mockEvent, node, canvas: mockCanvas }) @@ -827,12 +823,13 @@ describe('ComboWidget', () => { const mockAddItem = vi.fn() let capturedCallback: ((value: string) => void) | undefined - const mockContextMenu = vi.fn((_values, options) => { - capturedCallback = options.callback - return { addItem: mockAddItem } - }) - LiteGraph.ContextMenu = - mockContextMenu as unknown as typeof LiteGraph.ContextMenu + const mockContextMenu = vi + .fn() + .mockImplementation(function (_values, options) { + capturedCallback = options.callback + this.addItem = mockAddItem + }) + LiteGraph.ContextMenu = mockContextMenu const setValueSpy = vi.spyOn(widget, 'setValue') widget.onClick({ e: mockEvent, node, canvas: mockCanvas }) @@ -879,12 +876,13 @@ describe('ComboWidget', () => { const mockAddItem = vi.fn() let capturedCallback: ((value: string) => void) | undefined - const mockContextMenu = vi.fn((_values, options) => { - capturedCallback = options.callback - return { addItem: mockAddItem } as ContextMenuInstance - }) - LiteGraph.ContextMenu = - mockContextMenu as unknown as typeof LiteGraph.ContextMenu + const mockContextMenu = vi + .fn() + .mockImplementation(function (_values, options) { + capturedCallback = options.callback + this.addItem = mockAddItem + }) + LiteGraph.ContextMenu = mockContextMenu widget.onClick({ e: mockEvent, node, canvas: mockCanvas }) @@ -931,7 +929,7 @@ describe('ComboWidget', () => { const mockGetOptionLabel = vi .fn() .mockReturnValueOnce('Beautiful Sunset.png') - .mockImplementationOnce(() => { + .mockImplementationOnce(function () { throw new Error('Formatting failed') }) @@ -957,11 +955,12 @@ describe('ComboWidget', () => { .mockImplementation(() => {}) const mockAddItem = vi.fn() - const mockContextMenu = vi.fn(() => { - return { addItem: mockAddItem } as ContextMenuInstance - }) - LiteGraph.ContextMenu = - mockContextMenu as unknown as typeof LiteGraph.ContextMenu + const mockContextMenu = vi + .fn() + .mockImplementation(function () { + this.addItem = mockAddItem + }) + LiteGraph.ContextMenu = mockContextMenu widget.onClick({ e: mockEvent, node, canvas: mockCanvas }) @@ -1007,9 +1006,8 @@ describe('ComboWidget', () => { node.pos = [50, 50] node.size = [200, 30] - const mockContextMenu = vi.fn() - LiteGraph.ContextMenu = - mockContextMenu as unknown as typeof LiteGraph.ContextMenu + const mockContextMenu = vi.fn() + LiteGraph.ContextMenu = mockContextMenu widget.onClick({ e: mockEvent, node, canvas: mockCanvas }) diff --git a/src/locales/en/commands.json b/src/locales/en/commands.json index 5e8123885..a621e774a 100644 --- a/src/locales/en/commands.json +++ b/src/locales/en/commands.json @@ -200,6 +200,9 @@ "Comfy_MaskEditor_BrushSize_Increase": { "label": "Increase Brush Size in MaskEditor" }, + "Comfy_MaskEditor_ColorPicker": { + "label": "Open Color Picker in MaskEditor" + }, "Comfy_MaskEditor_OpenMaskEditor": { "label": "Open Mask Editor for Selected Node" }, @@ -260,6 +263,9 @@ "Comfy_ToggleLinear": { "label": "toggle linear mode" }, + "Comfy_ToggleQPOV2": { + "label": "Toggle Queue Panel V2" + }, "Comfy_ToggleTheme": { "label": "Toggle Theme (Dark/Light)" }, @@ -324,4 +330,4 @@ "label": "Toggle Workflows Sidebar", "tooltip": "Workflows" } -} \ No newline at end of file +} diff --git a/src/locales/en/main.json b/src/locales/en/main.json index af70861a3..6fb145d3a 100644 --- a/src/locales/en/main.json +++ b/src/locales/en/main.json @@ -119,6 +119,8 @@ "customBackground": "Custom Background", "settings": "Settings", "searchWorkflows": "Search Workflows", + "scrollLeft": "Scroll Left", + "scrollRight": "Scroll Right", "searchSettings": "Search Settings", "searchNodes": "Search Nodes", "searchModels": "Search Models", @@ -179,6 +181,7 @@ "missing": "Missing", "inProgress": "In progress", "completed": "Completed", + "downloading": "Downloading", "interrupted": "Interrupted", "queued": "Queued", "running": "Running", @@ -506,10 +509,12 @@ "title": "Choose your hardware setup", "recommended": "RECOMMENDED", "nvidiaSubtitle": "NVIDIA CUDA", + "amdSubtitle": "AMD ROCm™", "cpuSubtitle": "CPU Mode", "manualSubtitle": "Manual Setup", "appleMetalDescription": "Leverages your Mac's GPU for faster speed and a better overall experience", "nvidiaDescription": "Use your NVIDIA GPU with CUDA acceleration for the best performance.", + "amdDescription": "Use your AMD GPU with ROCm™ acceleration for the best performance.", "cpuDescription": "Use CPU mode for compatibility when GPU acceleration is not available", "manualDescription": "Configure ComfyUI manually for advanced setups or unsupported hardware" }, @@ -648,6 +653,7 @@ "box": "Box" }, "sideToolbar": { + "sidebar": "Sidebar", "themeToggle": "Toggle Theme", "helpCenter": "Help Center", "logout": "Logout", @@ -715,6 +721,8 @@ "colonPercent": ": {percent}", "currentNode": "Current node:", "viewAllJobs": "View all jobs", + "viewList": "List view", + "viewGrid": "Grid view", "running": "running", "preview": "Preview", "interruptAll": "Interrupt all running jobs", @@ -868,7 +876,7 @@ "noResultsHint": "Try adjusting your search or filters", "allTemplates": "All Templates", "modelFilter": "Model Filter", - "useCaseFilter": "Use Case", + "useCaseFilter": "Tasks", "licenseFilter": "License", "modelsSelected": "{count} Models", "useCasesSelected": "{count} Use Cases", @@ -877,6 +885,7 @@ "resultsCount": "Showing {count} of {total} templates", "sort": { "recommended": "Recommended", + "popular": "Popular", "alphabetical": "A → Z", "newest": "Newest", "searchPlaceholder": "Search...", @@ -1032,6 +1041,8 @@ "copyErrorMessage": "Copy error message", "reportError": "Report error" }, + "toggleJobHistory": "Toggle Job History", + "jobHistory": "Job History", "jobList": { "undated": "Undated", "sortMostRecent": "Most recent", @@ -1134,6 +1145,7 @@ "Toggle the Custom Nodes Manager Progress Bar": "Toggle the Custom Nodes Manager Progress Bar", "Decrease Brush Size in MaskEditor": "Decrease Brush Size in MaskEditor", "Increase Brush Size in MaskEditor": "Increase Brush Size in MaskEditor", + "Open Color Picker in MaskEditor": "Open Color Picker in MaskEditor", "Open Mask Editor for Selected Node": "Open Mask Editor for Selected Node", "Unload Models": "Unload Models", "Unload Models and Execution Cache": "Unload Models and Execution Cache", @@ -1387,6 +1399,8 @@ "conditioning": "conditioning", "loaders": "loaders", "guiders": "guiders", + "latent": "latent", + "mask": "mask", "api node": "api node", "video": "video", "ByteDance": "ByteDance", @@ -1403,17 +1417,16 @@ "kandinsky5": "kandinsky5", "hooks": "hooks", "combine": "combine", + "logic": "logic", "cond single": "cond single", "context": "context", "controlnet": "controlnet", "inpaint": "inpaint", "scheduling": "scheduling", "create": "create", - "mask": "mask", "deprecated": "deprecated", "debug": "debug", "model": "model", - "latent": "latent", "3d": "3d", "ltxv": "ltxv", "qwen": "qwen", @@ -1482,6 +1495,9 @@ "CLIP_VISION": "CLIP_VISION", "CLIP_VISION_OUTPUT": "CLIP_VISION_OUTPUT", "COMBO": "COMBO", + "COMFY_AUTOGROW_V3": "COMFY_AUTOGROW_V3", + "COMFY_DYNAMICCOMBO_V3": "COMFY_DYNAMICCOMBO_V3", + "COMFY_MATCHTYPE_V3": "COMFY_MATCHTYPE_V3", "CONDITIONING": "CONDITIONING", "CONTROL_NET": "CONTROL_NET", "FLOAT": "FLOAT", @@ -1691,6 +1707,7 @@ "pleaseSelectNodesToGroup": "Please select the nodes (or other groups) to create a group for", "emptyCanvas": "Empty canvas", "fileUploadFailed": "File upload failed", + "fileTooLarge": "File too large ({size} MB). Maximum supported size is {maxSize} MB", "unableToGetModelFilePath": "Unable to get model file path", "couldNotDetermineFileType": "Could not determine file type", "errorLoadingModel": "Error loading model", @@ -2272,14 +2289,16 @@ "noAssetsFound": "No assets found", "noModelsInFolder": "No {type} available in this folder", "notSureLeaveAsIs": "Not sure? Just leave this as is", + "noValidSourceDetected": "No valid import source detected", "onlyCivitaiUrlsSupported": "Only Civitai URLs are supported", "ownership": "Ownership", "ownershipAll": "All", "ownershipMyModels": "My models", "ownershipPublicModels": "Public models", + "processingModel": "Download started", + "processingModelDescription": "You can close this dialog. The download will continue in the background.", "providerCivitai": "Civitai", "providerHuggingFace": "Hugging Face", - "noValidSourceDetected": "No valid import source detected", "selectFrameworks": "Select Frameworks", "selectModelType": "Select model type", "selectProjects": "Select Projects", @@ -2304,8 +2323,8 @@ "uploadModelDescription1": "Paste a Civitai model download link to add it to your library.", "uploadModelDescription1Generic": "Paste a model download link to add it to your library.", "uploadModelDescription2": "Only links from {link} are supported at the moment", - "uploadModelDescription2Link": "https://civitai.com/models", "uploadModelDescription2Generic": "Only URLs from the following providers are supported:", + "uploadModelDescription2Link": "https://civitai.com/models", "uploadModelDescription3": "Max file size: {size}", "uploadModelFailedToRetrieveMetadata": "Failed to retrieve metadata. Please check the link and try again.", "uploadModelFromCivitai": "Import a model from Civitai", @@ -2329,6 +2348,11 @@ "complete": "{assetName} has been deleted.", "failed": "{assetName} could not be deleted." }, + "download": { + "complete": "Download complete", + "failed": "Download failed", + "inProgress": "Downloading {assetName}..." + }, "rename": { "failed": "Could not rename asset." } @@ -2446,4 +2470,4 @@ "recentReleases": "Recent releases", "helpCenterMenu": "Help Center Menu" } -} \ No newline at end of file +} diff --git a/src/locales/en/nodeDefs.json b/src/locales/en/nodeDefs.json index b9c846bfc..6e098793a 100644 --- a/src/locales/en/nodeDefs.json +++ b/src/locales/en/nodeDefs.json @@ -267,6 +267,45 @@ } } }, + "BatchImagesNode": { + "display_name": "Batch Images", + "inputs": { + "images": { + "name": "images" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "BatchLatentsNode": { + "display_name": "Batch Latents", + "inputs": { + "latents": { + "name": "latents" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "BatchMasksNode": { + "display_name": "Batch Masks", + "inputs": { + "masks": { + "name": "masks" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, "BetaSamplingScheduler": { "display_name": "BetaSamplingScheduler", "inputs": { @@ -519,7 +558,7 @@ } }, "ByteDanceSeedreamNode": { - "display_name": "ByteDance Seedream 4", + "display_name": "ByteDance Seedream 4.5", "description": "Unified text-to-image generation and precise single-sentence editing at up to 4K resolution.", "inputs": { "model": { @@ -1247,6 +1286,26 @@ } } }, + "ComfySwitchNode": { + "display_name": "Switch", + "inputs": { + "switch": { + "name": "switch" + }, + "on_false": { + "name": "on_false" + }, + "on_true": { + "name": "on_true" + } + }, + "outputs": { + "0": { + "name": "output", + "tooltip": null + } + } + }, "ConditioningAverage": { "display_name": "ConditioningAverage", "inputs": { @@ -1956,6 +2015,20 @@ } } }, + "CustomCombo": { + "display_name": "Custom Combo", + "inputs": { + "choice": { + "name": "choice" + }, + "option0": {} + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, "DiffControlNetLoader": { "display_name": "Load ControlNet Model (diff)", "inputs": { @@ -3183,13 +3256,16 @@ }, "outputs": { "0": { - "name": "width" + "name": "width", + "tooltip": null }, "1": { - "name": "height" + "name": "height", + "tooltip": null }, "2": { - "name": "batch_size" + "name": "batch_size", + "tooltip": null } } }, @@ -3725,6 +3801,11 @@ "control_after_generate": { "name": "control after generate" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "ImageBatch": { @@ -3841,6 +3922,11 @@ "y": { "name": "y" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "ImageDeduplication": { @@ -3871,6 +3957,11 @@ "flip_method": { "name": "flip_method" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "ImageFromBatch": { @@ -3885,6 +3976,11 @@ "length": { "name": "length" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "ImageGrid": { @@ -4024,6 +4120,11 @@ "rotation": { "name": "rotation" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "ImageScale": { @@ -4072,6 +4173,11 @@ "largest_size": { "name": "largest_size" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "ImageScaleToTotalPixels": { @@ -4120,7 +4226,7 @@ }, "ImageStitch": { "display_name": "Image Stitch", - "description": "\nStitches image2 to image1 in the specified direction.\nIf image2 is not provided, returns image1 unchanged.\nOptional spacing can be added between images.\n", + "description": "Stitches image2 to image1 in the specified direction.\nIf image2 is not provided, returns image1 unchanged.\nOptional spacing can be added between images.", "inputs": { "image1": { "name": "image1" @@ -4140,6 +4246,11 @@ "image2": { "name": "image2" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "ImageToMask": { @@ -4687,6 +4798,36 @@ } } }, + "KlingMotionControl": { + "display_name": "Kling Motion Control", + "inputs": { + "prompt": { + "name": "prompt" + }, + "reference_image": { + "name": "reference_image" + }, + "reference_video": { + "name": "reference_video", + "tooltip": "Motion reference video used to drive movement/expression.\nDuration limits depend on character_orientation:\n - image: 3–10s (max 10s)\n - video: 3–30s (max 30s)" + }, + "keep_original_sound": { + "name": "keep_original_sound" + }, + "character_orientation": { + "name": "character_orientation", + "tooltip": "Controls where the character's facing/orientation comes from.\nvideo: movements, expressions, camera moves, and orientation follow the motion reference video (other details via prompt).\nimage: movements and expressions still follow the motion reference video, but the character orientation matches the reference image (camera/other details via prompt)." + }, + "mode": { + "name": "mode" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, "KlingOmniProEditVideoNode": { "display_name": "Kling Omni Edit Video (Pro)", "description": "Edit an existing video with the latest model from Kling.", @@ -4708,6 +4849,9 @@ "reference_images": { "name": "reference_images", "tooltip": "Up to 4 additional reference images." + }, + "resolution": { + "name": "resolution" } }, "outputs": { @@ -4740,6 +4884,9 @@ "reference_images": { "name": "reference_images", "tooltip": "Up to 6 additional reference images." + }, + "resolution": { + "name": "resolution" } }, "outputs": { @@ -4796,6 +4943,9 @@ "reference_images": { "name": "reference_images", "tooltip": "Up to 7 reference images." + }, + "resolution": { + "name": "resolution" } }, "outputs": { @@ -4820,6 +4970,9 @@ }, "duration": { "name": "duration" + }, + "resolution": { + "name": "resolution" } }, "outputs": { @@ -4855,6 +5008,9 @@ "reference_images": { "name": "reference_images", "tooltip": "Up to 4 additional reference images." + }, + "resolution": { + "name": "resolution" } }, "outputs": { @@ -6390,7 +6546,7 @@ } }, "Mahiro": { - "display_name": "Mahiro is so cute that she deserves a better guidance function!! (。・ω・。)", + "display_name": "Mahiro CFG", "description": "Modify the guidance to scale more on the 'direction' of the positive prompt rather than the difference between the negative prompt.", "inputs": { "model": { @@ -6435,6 +6591,19 @@ } } }, + "ManualSigmas": { + "display_name": "ManualSigmas", + "inputs": { + "sigmas": { + "name": "sigmas" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, "MaskComposite": { "display_name": "MaskComposite", "inputs": { @@ -10452,6 +10621,11 @@ "amount": { "name": "amount" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "RepeatLatentBatch": { @@ -10539,6 +10713,34 @@ "interpolation": { "name": "interpolation" } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "ResizeImageMaskNode": { + "display_name": "Resize Image/Mask", + "inputs": { + "input": { + "name": "input" + }, + "resize_type": { + "name": "resize_type" + }, + "scale_method": { + "name": "scale_method" + }, + "resize_type_multiplier": { + "name": "multiplier" + } + }, + "outputs": { + "0": { + "name": "resized", + "tooltip": null + } } }, "ResizeImagesByLongerEdge": { @@ -13838,7 +14040,7 @@ }, "enhance_prompt": { "name": "enhance_prompt", - "tooltip": "Whether to enhance the prompt with AI assistance" + "tooltip": "This parameter is deprecated and ignored." }, "person_generation": { "name": "person_generation", diff --git a/src/locales/zh/commands.json b/src/locales/zh/commands.json index 6255e1aef..144df6c18 100644 --- a/src/locales/zh/commands.json +++ b/src/locales/zh/commands.json @@ -80,6 +80,9 @@ "Comfy_Canvas_ToggleMinimap": { "label": "画布切换小地图" }, + "Comfy_Canvas_ToggleSelected_Pin": { + "label": "固定/取消固定选中项" + }, "Comfy_Canvas_ToggleSelectedNodes_Bypass": { "label": "忽略/取消忽略选中节点" }, @@ -92,9 +95,6 @@ "Comfy_Canvas_ToggleSelectedNodes_Pin": { "label": "固定/取消固定选中节点" }, - "Comfy_Canvas_ToggleSelected_Pin": { - "label": "固定/取消固定选中项" - }, "Comfy_Canvas_Unlock": { "label": "解锁画布" }, @@ -290,6 +290,9 @@ "Workspace_ToggleBottomPanel": { "label": "切换底部面板" }, + "Workspace_ToggleBottomPanel_Shortcuts": { + "label": "显示快捷键对话框" + }, "Workspace_ToggleBottomPanelTab_command-terminal": { "label": "切换终端底部面板" }, @@ -302,9 +305,6 @@ "Workspace_ToggleBottomPanelTab_shortcuts-view-controls": { "label": "切换检视控制底部面板" }, - "Workspace_ToggleBottomPanel_Shortcuts": { - "label": "显示快捷键对话框" - }, "Workspace_ToggleFocusMode": { "label": "切换焦点模式" }, @@ -324,4 +324,4 @@ "label": "切换工作流侧边栏", "tooltip": "工作流" } -} +} \ No newline at end of file diff --git a/src/locales/zh/main.json b/src/locales/zh/main.json index cc0e5cae9..7b5decab8 100644 --- a/src/locales/zh/main.json +++ b/src/locales/zh/main.json @@ -1,691 +1,698 @@ { "g": { - "1x": "1倍", - "2x": "2倍", - "about": "关于", - "add": "添加", - "addNodeFilterCondition": "添加节点筛选条件", - "all": "全部", - "amount": "数量", - "apply": "应用", - "architecture": "架构", - "audioFailedToLoad": "音频加载失败", - "audioProgress": "音频进度", - "author": "作者", - "back": "返回", - "batchRename": "批量重命名", - "beta": "测试版", - "bookmark": "保存到库", - "calculatingDimensions": "正在计算尺寸", - "cancel": "取消", - "cancelled": "已取消", - "capture": "捕获", - "category": "类别", - "chart": "图表", - "chartLowercase": "图表", - "choose_file_to_upload": "选择要上传的文件", - "clear": "清除", - "clearAll": "全部清除", - "clearFilters": "清除筛选", - "close": "关闭", - "color": "颜色", - "comfy": "舒适", - "comfyOrgLogoAlt": "ComfyOrg 徽标", - "comingSoon": "即将推出", - "command": "指令", - "commandProhibited": "命令 {command} 被禁止。请联系管理员了解更多信息。", - "community": "社区", - "completed": "已完成", - "confirm": "确认", - "confirmed": "已确认", - "content": "内容", - "continue": "继续", - "control_after_generate": "生成后控制", - "control_before_generate": "生成前控制", - "copied": "已复制", - "copy": "复制", - "copyJobId": "复制队列 ID", - "copyToClipboard": "复制到剪贴板", - "copyURL": "复制链接", - "core": "核心", + "user": "用户", "currentUser": "当前用户", - "custom": "自定义", - "customBackground": "自定义背景", - "customize": "自定义", - "customizeFolder": "自定义文件夹", - "defaultBanner": "默认横幅", - "delete": "删除", - "deleteAudioFile": "删除音频文件", - "deleteImage": "删除图片", - "deprecated": "已弃用", - "description": "描述", - "devices": "设备", - "disableAll": "禁用全部", - "disableSelected": "禁用选中项", - "disableThirdParty": "禁用第三方", - "disabling": "禁用中", - "dismiss": "关闭", + "empty": "空", + "noWorkflowsFound": "未找到工作流。", + "comingSoon": "即将推出", "download": "下载", "downloadImage": "下载图片", "downloadVideo": "下载视频", - "dropYourFileOr": "拖放您的文件或", - "duplicate": "复制", - "edit": "编辑", - "editImage": "编辑图片", "editOrMaskImage": "编辑或遮罩图片", - "emDash": "-", - "empty": "空", - "enableAll": "启用全部", - "enableOrDisablePack": "启用或禁用包", - "enableSelected": "启用选中项", - "enabled": "已启用", - "enabling": "启用中", - "enterBaseName": "输入基础名称", - "enterNewName": "输入新名称", - "error": "错误", - "errorLoadingImage": "图片加载出错", - "errorLoadingVideo": "视频加载出错", - "experimental": "测试版", - "export": "导出", - "extensionName": "扩展名称", - "failed": "失败", - "failedToCopyJobId": "未能复制队列 ID", - "failedToDownloadImage": "图片下载失败", - "failedToDownloadVideo": "视频下载失败", - "feedback": "反馈", - "file": "文件", - "filter": "过滤", - "findIssues": "查找问题", - "frameNodes": "框选节点", - "frontendNewer": "前端版本 {frontendVersion} 可能与后端版本 {backendVersion} 不相容。", - "frontendOutdated": "前端版本 {frontendVersion} 已过时。后端需要 {requiredVersion} 或更高版本。", - "galleryImage": "图库图片", - "galleryThumbnail": "图库缩略图", - "goToNode": "转到节点", - "graphNavigation": "图形导航", - "halfSpeed": "0.5倍", - "icon": "图标", - "imageFailedToLoad": "图像加载失败", - "imagePreview": "图片预览 - 使用方向键切换图片", - "imageUrl": "图片网址", - "import": "导入", - "inProgress": "进行中", - "info": "节点信息", - "insert": "插入", - "install": "安装", - "installed": "已安装", - "installing": "正在安装", - "interrupted": "已中断", - "itemSelected": "已选择 {selectedCount} 项", - "itemsCopiedToClipboard": "已复制到剪贴板", - "itemsSelected": "已选择 {selectedCount} 项", - "job": "任务", - "jobIdCopied": "队列 ID 已复制到剪贴板", - "keybinding": "按键绑定", - "keybindingAlreadyExists": "快捷键已存在", - "learnMore": "了解更多", - "listening": "正在监听...", - "liveSamplingPreview": "实时采样预览", - "loadAllFolders": "加载所有文件夹", - "loadWorkflow": "加载工作流", - "loading": "加载中", - "loadingPanel": "正在加载{panel}面板...", - "login": "登录", - "logoAlt": "ComfyUI 标志", - "logs": "日志", - "markdown": "markdown", - "micPermissionDenied": "麦克风权限被拒绝", - "migrate": "迁移", - "missing": "缺失", - "more": "更多", - "moreOptions": "更多选项", - "moreWorkflows": "更多工作流", - "multiSelectDropdown": "多选下拉框", - "name": "名称", - "newFolder": "新文件夹", - "next": "下一个", - "no": "否", - "noAudioRecorded": "未录制音频", - "noItems": "无项目", - "noResults": "无结果", - "noResultsFound": "未找到结果", - "noTasksFound": "未找到任务", - "noTasksFoundMessage": "队列中没有任务。", - "noWorkflowsFound": "未找到工作流。", - "nodeContentError": "节点内容错误", - "nodeHeaderError": "节点标题错误", - "nodeRenderError": "节点渲染错误", - "nodeSlotsError": "节点插槽错误", - "nodeWidgetsError": "节点控件错误", - "nodes": "节点", - "nodesRunning": "节点正在运行", - "none": "无", - "nothingToCopy": "没有可以复制的内容", - "nothingToDelete": "没有可以删除的内容", - "nothingToDuplicate": "Nothing to duplicate", - "nothingToRename": "没有可以重命名的内容", - "ok": "确定", - "openManager": "打开管理器", - "openNewIssue": "打开新问题", - "or": "或", - "overwrite": "覆盖", - "playPause": "开启/暂停", - "playRecording": "播放录音", - "playbackSpeed": "播放速度", - "playing": "播放中", - "pressKeysForNewBinding": "按下按键设置新绑定", - "preview": "预览", - "profile": "档案", - "progressCountOf": "共", - "queued": "已执行", - "ready": "就绪", - "reconnected": "已重新连接", - "reconnecting": "重新连接中", - "refresh": "刷新", - "refreshNode": "刷新节点", - "relativeTime": { - "daysAgo": "{count}天 前", - "hoursAgo": "{count}时 前", - "minutesAgo": "{count}分 前", - "monthsAgo": "{count}月 前", - "now": "刚才", - "weeksAgo": "{count}周 前", - "yearsAgo": "{count}年 前" - }, - "releaseTitle": "{package} {version} 发布", - "reloadToApplyChanges": "重新加载以应用更改", + "editImage": "编辑图片", + "deleteImage": "删除图片", + "deleteAudioFile": "删除音频文件", "removeImage": "移除图片", "removeVideo": "移除视频", - "rename": "重命名", + "chart": "图表", + "chartLowercase": "图表", + "file": "文件", + "selectedFile": "已选文件", + "none": "无", + "markdown": "markdown", + "content": "内容", + "audioProgress": "音频进度", + "viewImageOfTotal": "查看第 {index} 张图片,共 {total} 张", + "viewVideoOfTotal": "查看第 {index} 个视频,共 {total} 个", + "imagePreview": "图片预览 - 使用方向键切换图片", + "videoPreview": "视频预览 - 使用方向键切换视频", + "galleryImage": "图库图片", + "galleryThumbnail": "图库缩略图", + "errorLoadingImage": "图片加载出错", + "errorLoadingVideo": "视频加载出错", + "failedToDownloadImage": "图片下载失败", + "failedToDownloadVideo": "视频下载失败", + "calculatingDimensions": "正在计算尺寸", + "import": "导入", + "loadAllFolders": "加载所有文件夹", + "logoAlt": "ComfyUI 标志", + "comfyOrgLogoAlt": "ComfyOrg 徽标", + "comfy": "舒适", + "refresh": "刷新", + "refreshNode": "刷新节点", + "vitePreloadErrorTitle": "新版本可用", + "vitePreloadErrorMessage": "应用已发布新版本。是否立即重新加载?\n如果不重新加载,应用的某些功能可能无法正常工作。\n您可以先拒绝,保存进度后再重新加载。", + "terminal": "终端", + "logs": "日志", + "videoFailedToLoad": "视频加载失败", + "audioFailedToLoad": "音频加载失败", + "liveSamplingPreview": "实时采样预览", + "extensionName": "扩展名称", + "reloadToApplyChanges": "重新加载以应用更改", + "insert": "插入", + "systemInfo": "系统信息", + "devices": "设备", + "about": "关于", + "add": "添加", + "confirm": "确认", + "confirmed": "已确认", + "reset": "重置", + "resetAll": "重置所有", + "clearFilters": "清除筛选", + "resetAllKeybindingsTooltip": "将所有键绑定重置为默认", + "customizeFolder": "自定义文件夹", + "icon": "图标", + "color": "颜色", + "error": "错误", + "resizeFromBottomRight": "从右下角调整大小", + "resizeFromTopRight": "从右上角调整大小", + "resizeFromBottomLeft": "从左下角调整大小", + "resizeFromTopLeft": "从左上角调整大小", + "info": "节点信息", + "bookmark": "保存到库", + "moreOptions": "更多选项", + "more": "更多", + "loading": "加载中", + "loadingPanel": "正在加载{panel}面板...", + "preview": "预览", + "addNodeFilterCondition": "添加节点筛选条件", + "architecture": "架构", + "author": "作者", + "usageHint": "使用提示", + "triggerPhrase": "触发短语", + "findIssues": "查找问题", "reportIssue": "发送报告", "reportIssueTooltip": "向 Comfy Org 提交错误报告", "reportSent": "报告已提交", - "reset": "重置", - "resetAll": "重置所有", - "resetAllKeybindingsTooltip": "将所有键绑定重置为默认", - "resizeFromBottomLeft": "从左下角调整大小", - "resizeFromBottomRight": "从右下角调整大小", - "resizeFromTopLeft": "从左上角调整大小", - "resizeFromTopRight": "从右上角调整大小", - "restart": "重新启动", - "resultsCount": "找到 {count} 个结果", - "running": "正在运行", + "copyToClipboard": "复制到剪贴板", + "openNewIssue": "打开新问题", + "showReport": "显示报告", + "imageFailedToLoad": "图像加载失败", + "reconnecting": "重新连接中", + "reconnected": "已重新连接", + "delete": "删除", + "rename": "重命名", "save": "保存", "saving": "正在保存", - "search": "搜索", - "searchExtensions": "搜索扩展", - "searchFailedMessage": "我们找不到任何与您的搜索匹配的设置。请尝试调整您的搜索词。", - "searchKeybindings": "搜索快捷键", - "searchModels": "搜索模型", - "searchNodes": "搜索节点", - "searchPlaceholder": "搜索占位符", - "searchSettings": "搜索设置", - "searchWorkflows": "搜索工作流", - "seeTutorial": "查看教程", - "selectItemsToCopy": "选择复制", - "selectItemsToDelete": "选择删除", - "selectItemsToDuplicate": "选择复制", - "selectItemsToRename": "选择重命名", - "selectedFile": "已选文件", - "setAsBackground": "设为背景", - "settings": "设置", - "showReport": "显示报告", - "singleSelectDropdown": "单选下拉框", - "sort": "排序", - "source": "来源", - "startRecording": "开始录音", - "status": "状态", - "stopPlayback": "停止播放", - "stopRecording": "停止录音", + "no": "否", + "cancel": "取消", + "close": "关闭", + "or": "或", + "pressKeysForNewBinding": "按下按键设置新绑定", + "defaultBanner": "默认横幅", + "enableOrDisablePack": "启用或禁用包", + "openManager": "打开管理器", + "graphNavigation": "图形导航", + "dropYourFileOr": "拖放您的文件或", + "back": "返回", + "next": "下一个", "submit": "提交", - "success": "成功", - "systemInfo": "系统信息", - "terminal": "终端", - "title": "标题", - "triggerPhrase": "触发短语", - "unknownError": "未知错误", - "untitled": "无标题", - "update": "更新", - "updateAvailable": "有更新可用", - "updateFrontend": "更新前端", - "updated": "已更新", - "updating": "更新中", + "install": "安装", + "installing": "正在安装", + "overwrite": "覆盖", + "customize": "自定义", + "experimental": "测试版", + "deprecated": "已弃用", + "loadWorkflow": "加载工作流", + "goToNode": "转到节点", + "setAsBackground": "设为背景", + "customBackground": "自定义背景", + "settings": "设置", + "searchWorkflows": "搜索工作流", + "searchSettings": "搜索设置", + "searchNodes": "搜索节点", + "searchModels": "搜索模型", + "searchKeybindings": "搜索快捷键", + "searchExtensions": "搜索扩展", + "search": "搜索", + "searchPlaceholder": "搜索占位符", + "noResultsFound": "未找到结果", + "noResults": "无结果", + "searchFailedMessage": "我们找不到任何与您的搜索匹配的设置。请尝试调整您的搜索词。", + "noTasksFound": "未找到任务", + "noTasksFoundMessage": "队列中没有任务。", + "newFolder": "新文件夹", + "enableAll": "启用全部", + "disableAll": "禁用全部", + "enableSelected": "启用选中项", + "disableSelected": "禁用选中项", + "disableThirdParty": "禁用第三方", + "core": "核心", + "custom": "自定义", + "command": "指令", + "keybinding": "按键绑定", "upload": "上传", - "usageHint": "使用提示", - "user": "用户", + "export": "导出", + "workflow": "工作流", + "success": "成功", + "ok": "确定", + "feedback": "反馈", + "continue": "继续", + "control_after_generate": "生成后控制", + "control_before_generate": "生成前控制", + "choose_file_to_upload": "选择要上传的文件", + "capture": "捕获", + "nodes": "节点", + "community": "社区", + "all": "全部", "versionMismatchWarning": "版本兼容性警告", "versionMismatchWarningMessage": "{warning}:{detail} 请参阅 https://docs.comfy.org/installation/update_comfyui#common-update-issues 以取得更新说明。", - "videoFailedToLoad": "视频加载失败", - "videoPreview": "视频预览 - 使用方向键切换视频", - "viewImageOfTotal": "查看第 {index} 张图片,共 {total} 张", - "viewVideoOfTotal": "查看第 {index} 个视频,共 {total} 个", - "vitePreloadErrorMessage": "应用已发布新版本。是否立即重新加载?\n如果不重新加载,应用的某些功能可能无法正常工作。\n您可以先拒绝,保存进度后再重新加载。", - "vitePreloadErrorTitle": "新版本可用", - "volume": "音量", + "frontendOutdated": "前端版本 {frontendVersion} 已过时。后端需要 {requiredVersion} 或更高版本。", + "frontendNewer": "前端版本 {frontendVersion} 可能与后端版本 {backendVersion} 不相容。", + "updateFrontend": "更新前端", + "dismiss": "关闭", + "update": "更新", + "updated": "已更新", + "resultsCount": "找到 {count} 个结果", + "status": "状态", + "description": "描述", "warning": "警告", - "workflow": "工作流" + "name": "名称", + "category": "类别", + "sort": "排序", + "source": "来源", + "filter": "过滤", + "apply": "应用", + "enabled": "已启用", + "installed": "已安装", + "restart": "重新启动", + "missing": "缺失", + "inProgress": "进行中", + "completed": "已完成", + "interrupted": "已中断", + "queued": "已执行", + "running": "正在运行", + "failed": "失败", + "cancelled": "已取消", + "job": "任务", + "untitled": "无标题", + "emDash": "-", + "enabling": "启用中", + "disabling": "禁用中", + "updating": "更新中", + "migrate": "迁移", + "updateAvailable": "有更新可用", + "login": "登录", + "learnMore": "了解更多", + "amount": "数量", + "unknownError": "未知错误", + "title": "标题", + "edit": "编辑", + "copy": "复制", + "copyJobId": "复制队列 ID", + "copied": "已复制", + "relativeTime": { + "now": "刚才", + "yearsAgo": "{count}年 前", + "monthsAgo": "{count}月 前", + "weeksAgo": "{count}周 前", + "daysAgo": "{count}天 前", + "hoursAgo": "{count}时 前", + "minutesAgo": "{count}分 前" + }, + "jobIdCopied": "队列 ID 已复制到剪贴板", + "failedToCopyJobId": "未能复制队列 ID", + "imageUrl": "图片网址", + "clear": "清除", + "clearAll": "全部清除", + "copyURL": "复制链接", + "releaseTitle": "{package} {version} 发布", + "itemSelected": "已选择 {selectedCount} 项", + "itemsSelected": "已选择 {selectedCount} 项", + "multiSelectDropdown": "多选下拉框", + "singleSelectDropdown": "单选下拉框", + "progressCountOf": "共", + "keybindingAlreadyExists": "快捷键已存在", + "commandProhibited": "命令 {command} 被禁止。请联系管理员了解更多信息。", + "startRecording": "开始录音", + "stopRecording": "停止录音", + "micPermissionDenied": "麦克风权限被拒绝", + "noAudioRecorded": "未录制音频", + "nodesRunning": "节点正在运行", + "duplicate": "复制", + "itemsCopiedToClipboard": "已复制到剪贴板", + "selectItemsToCopy": "选择复制", + "nothingToCopy": "没有可以复制的内容", + "selectItemsToDuplicate": "选择复制", + "nothingToDuplicate": "Nothing to duplicate", + "selectItemsToDelete": "选择删除", + "nothingToDelete": "没有可以删除的内容", + "batchRename": "批量重命名", + "enterBaseName": "输入基础名称", + "enterNewName": "输入新名称", + "selectItemsToRename": "选择重命名", + "nothingToRename": "没有可以重命名的内容", + "moreWorkflows": "更多工作流", + "seeTutorial": "查看教程", + "nodeRenderError": "节点渲染错误", + "nodeContentError": "节点内容错误", + "nodeHeaderError": "节点标题错误", + "nodeSlotsError": "节点插槽错误", + "nodeWidgetsError": "节点控件错误", + "frameNodes": "框选节点", + "listening": "正在监听...", + "ready": "就绪", + "playPause": "开启/暂停", + "playRecording": "播放录音", + "playing": "播放中", + "stopPlayback": "停止播放", + "playbackSpeed": "播放速度", + "volume": "音量", + "halfSpeed": "0.5倍", + "1x": "1倍", + "2x": "2倍", + "beta": "测试版", + "profile": "档案", + "noItems": "无项目" }, "manager": { - "allMissingNodesInstalled": "所有缺失节点已成功安装", - "applyChanges": "应用更改", - "changingVersion": "将版本从 {from} 更改为 {to}", - "clickToFinishSetup": "点击", - "conflicts": { - "conflictInfoTitle": "为什么会发生这种情况?", - "conflictMessages": { - "accelerator": "GPU/加速器不受支持(可用:{current},要求:{required})", - "banned": "该软件包因安全原因被禁用", - "comfyui_version": "ComfyUI 版本不匹配(当前:{current},要求:{required})", - "frontend_version": "前端版本不匹配(当前:{current},要求:{required})", - "generic": "兼容性问题(当前:{current},要求:{required})", - "import_failed": "导入失败", - "os": "操作系统不受支持(当前:{current},要求:{required})", - "pending": "安全验证待定 - 无法验证兼容性" - }, - "conflicts": "冲突", - "description": "我们检测到您的部分扩展与新版 ComfyUI 存在冲突。更新后,依赖这些扩展的工作流可能会被破坏。", - "enableAnyway": "仍然启用", - "extensionAtRisk": "有风险的扩展", - "importFailedExtensions": "导入失败的扩展", - "info": "如果继续更新,冲突的扩展将被自动禁用。您可以随时在 ComfyUI 管理器中查看和管理它们。", - "installAnyway": "仍然安装", - "title": "检测到节点包问题!", - "understood": "我已了解", - "warningBanner": { - "button": "了解更多...", - "message": "这些扩展需要与您当前环境不同版本的系统包。安装它们可能会覆盖核心依赖,并影响其他扩展或工作流。", - "title": "部分扩展因与当前环境不兼容而被禁用" - }, - "warningTooltip": "该软件包可能与您当前的环境存在兼容性问题" - }, - "createdBy": "创建者", - "dependencies": "依赖关系", - "disabledNodesWontUpdate": "已禁用的节点不会被更新", - "discoverCommunityContent": "发现社区制作的节点包,扩展等等...", - "downloads": "下载", - "enablePackToChangeVersion": "启用此包以更改版本", - "errorConnecting": "连接到Comfy节点注册表时出错。", - "extensionsSuccessfullyInstalled": "扩展已成功安装并可使用!", - "failed": "失败 ({count})", - "failedToInstall": "安装失败", - "filter": { - "disabled": "已禁用", - "enabled": "已启用", - "nodePack": "节点包" - }, - "gettingInfo": "正在获取信息...", - "importFailedGenericError": "软件包导入失败。请查看控制台获取更多信息。", - "inWorkflow": "在工作流中", - "infoPanelEmpty": "点击一个项目查看信息", - "installAllMissingNodes": "安装所有缺失节点", - "installError": "安装错误", - "installSelected": "安装选定", - "installationQueue": "安装队列", - "installingDependencies": "正在安装依赖项...", - "lastUpdated": "最后更新", - "latestVersion": "最新", + "title": "自定义节点管理器", + "legacyMenuNotAvailable": "传统管理器菜单不可用,已切换为新管理器菜单。", "legacyManagerUI": "使用传统界面", "legacyManagerUIDescription": "如需使用传统管理器界面,请以 --enable-manager-legacy-ui 参数启动 ComfyUI", - "legacyMenuNotAvailable": "传统管理器菜单不可用,已切换为新管理器菜单。", - "license": "许可证", - "loadingVersions": "正在加载版本...", - "mixedSelectionMessage": "无法对混合选择执行批量操作", - "nightlyVersion": "每夜", - "noDescription": "无可用描述", + "failed": "失败 ({count})", + "failedToInstall": "安装失败", + "installError": "安装错误", + "importFailedGenericError": "软件包导入失败。请查看控制台获取更多信息。", "noNodesFound": "未找到节点", "noNodesFoundDescription": "无法解析包的节点,或者该包仅为前端扩展,没有任何节点。", - "noResultsFound": "未找到符合您搜索的结果。", - "nodePack": "节点包", - "notAvailable": "不可用", - "packsSelected": "选定的包", - "repository": "仓库", + "installationQueue": "安装队列", + "changingVersion": "将版本从 {from} 更改为 {to}", + "dependencies": "依赖关系", + "inWorkflow": "在工作流中", + "infoPanelEmpty": "点击一个项目查看信息", + "applyChanges": "应用更改", "restartToApplyChanges": "要应用更改,请重新启动ComfyUI", - "restartingBackend": "正在重启后端以应用更改...", - "searchPlaceholder": "搜索", - "selectVersion": "选择版本", - "sort": { - "created": "最新", - "downloads": "最受欢迎", - "publisher": "出版商", - "updated": "最近更新" - }, - "status": { - "active": "活跃", - "banned": "已禁止", - "conflicting": "冲突", - "deleted": "已删除", - "flagged": "已标记", - "importFailed": "安装错误", - "pending": "待定", - "unknown": "未知" - }, - "title": "自定义节点管理器", + "clickToFinishSetup": "点击", "toFinishSetup": "以完成设置", - "totalNodes": "节点总数", - "tryAgainLater": "请稍后再试。", - "tryDifferentSearch": "请尝试不同的搜索查询。", - "tryUpdate": "尝试更新", - "tryUpdateTooltip": "从库中拉取更新。测试版本可能有无法自动检测到更新。", + "restartingBackend": "正在重启后端以应用更改...", + "extensionsSuccessfullyInstalled": "扩展已成功安装并可使用!", + "installingDependencies": "正在安装依赖项...", + "loadingVersions": "正在加载版本...", + "selectVersion": "选择版本", + "downloads": "下载", + "repository": "仓库", "uninstall": "卸载", - "uninstallSelected": "卸载所选", "uninstalling": "正在卸载", "update": "更新", - "updateAll": "全部更新", + "tryUpdate": "尝试更新", + "tryUpdateTooltip": "从库中拉取更新。测试版本可能有无法自动检测到更新。", + "uninstallSelected": "卸载所选", "updateSelected": "更新所选", + "updateAll": "全部更新", "updatingAllPacks": "更新所有包", - "version": "版本" + "disabledNodesWontUpdate": "已禁用的节点不会被更新", + "enablePackToChangeVersion": "启用此包以更改版本", + "license": "许可证", + "nightlyVersion": "每夜", + "latestVersion": "最新", + "createdBy": "创建者", + "totalNodes": "节点总数", + "discoverCommunityContent": "发现社区制作的节点包,扩展等等...", + "errorConnecting": "连接到Comfy节点注册表时出错。", + "noResultsFound": "未找到符合您搜索的结果。", + "tryDifferentSearch": "请尝试不同的搜索查询。", + "tryAgainLater": "请稍后再试。", + "gettingInfo": "正在获取信息...", + "nodePack": "节点包", + "searchPlaceholder": "搜索", + "version": "版本", + "lastUpdated": "最后更新", + "noDescription": "无可用描述", + "installSelected": "安装选定", + "installAllMissingNodes": "安装所有缺失节点", + "allMissingNodesInstalled": "所有缺失节点已成功安装", + "packsSelected": "选定的包", + "mixedSelectionMessage": "无法对混合选择执行批量操作", + "notAvailable": "不可用", + "status": { + "active": "活跃", + "pending": "待定", + "flagged": "已标记", + "deleted": "已删除", + "banned": "已禁止", + "unknown": "未知", + "conflicting": "冲突", + "importFailed": "安装错误" + }, + "sort": { + "downloads": "最受欢迎", + "publisher": "出版商", + "created": "最新", + "updated": "最近更新" + }, + "filter": { + "nodePack": "节点包", + "enabled": "已启用", + "disabled": "已禁用" + }, + "conflicts": { + "title": "检测到节点包问题!", + "description": "我们检测到您的部分扩展与新版 ComfyUI 存在冲突。更新后,依赖这些扩展的工作流可能会被破坏。", + "info": "如果继续更新,冲突的扩展将被自动禁用。您可以随时在 ComfyUI 管理器中查看和管理它们。", + "extensionAtRisk": "有风险的扩展", + "conflicts": "冲突", + "importFailedExtensions": "导入失败的扩展", + "conflictInfoTitle": "为什么会发生这种情况?", + "installAnyway": "仍然安装", + "enableAnyway": "仍然启用", + "understood": "我已了解", + "warningBanner": { + "title": "部分扩展因与当前环境不兼容而被禁用", + "message": "这些扩展需要与您当前环境不同版本的系统包。安装它们可能会覆盖核心依赖,并影响其他扩展或工作流。", + "button": "了解更多..." + }, + "conflictMessages": { + "comfyui_version": "ComfyUI 版本不匹配(当前:{current},要求:{required})", + "frontend_version": "前端版本不匹配(当前:{current},要求:{required})", + "os": "操作系统不受支持(当前:{current},要求:{required})", + "accelerator": "GPU/加速器不受支持(可用:{current},要求:{required})", + "generic": "兼容性问题(当前:{current},要求:{required})", + "banned": "该软件包因安全原因被禁用", + "pending": "安全验证待定 - 无法验证兼容性", + "import_failed": "导入失败" + }, + "warningTooltip": "该软件包可能与您当前的环境存在兼容性问题" + } }, "issueReport": { "helpFix": "帮助修复这个" }, "color": { - "black": "黑色", - "blue": "蓝色", - "brown": "棕色", - "custom": "自定义", - "cyan": "青色", - "default": "默认", - "green": "绿色", "noColor": "无色", - "pale_blue": "淡蓝色", - "pink": "粉色", - "purple": "紫色", + "default": "默认", + "blue": "蓝色", + "green": "绿色", "red": "红色", - "yellow": "黄色" + "pink": "粉色", + "yellow": "黄色", + "brown": "棕色", + "pale_blue": "淡蓝色", + "cyan": "青色", + "purple": "紫色", + "black": "黑色", + "custom": "自定义" }, "contextMenu": { - "Add Group": "添加组", - "Add Group For Selected Nodes": "为选定节点添加组", - "Add Node": "添加节点", - "Add Subgraph to Library": "添加子工作流到节点库", - "Adjust Size": "调整尺寸", - "Align Selected To": "对齐选中项到", - "Bottom": "底部", - "Bypass": "绕过", - "Clone": "克隆", - "Collapse": "折叠", - "Color": "颜色", - "Colors": "颜色", - "Convert to Group Node": "转换为组节点", - "Convert to Subgraph": "转换为子工作流", - "Copy": "复制", - "Copy (Clipspace)": "复制 (Clipspace)", - "Copy Image": "复制图像", - "Delete": "删除", - "Distribute Nodes": "分布节点", - "Duplicate": "复制", - "Edit Subgraph Widgets": "编辑子工作流组件", - "Expand": "展开", - "Expand Node": "展开节点", - "Extensions": "扩展", - "Horizontal": "水平", "Inputs": "输入", - "Left": "左侧", - "Manage": "管理", - "Manage Group Nodes": "管理组节点", - "Minimize Node": "最小化节点", - "Mode": "模式", - "Node Info": "节点信息", - "Node Templates": "节点模板", - "Open Image": "打开图像", - "Open in Mask Editor": "用遮罩编辑器打开", "Outputs": "输出", - "Paste": "站贴", - "Pin": "固定", "Properties": "属性", "Properties Panel": "属性面板", + "Title": "标题", + "Mode": "模式", + "Resize": "调整大小", + "Collapse": "折叠", + "Expand": "展开", + "Pin": "固定", + "Unpin": "取消固定", + "Clone": "克隆", "Remove": "删除", - "Remove Bypass": "删除所有忽略节点", + "Colors": "颜色", + "Shapes": "形状", + "Bypass": "绕过", + "Copy (Clipspace)": "复制 (Clipspace)", + "Add Node": "添加节点", + "Add Group": "添加组", + "Convert to Group Node": "转换为组节点", + "Convert to Group Node (Deprecated)": "转换为组节点(已弃用)", + "Manage Group Nodes": "管理组节点", + "Add Group For Selected Nodes": "为选定节点添加组", + "Save Selected as Template": "将选定节点另存为模板", + "Node Templates": "节点模板", + "Manage": "管理", + "Search": "搜索", + "Open in Mask Editor": "用遮罩编辑器打开", + "Open Image": "打开图像", + "Copy Image": "复制图像", + "Save Image": "保存图像", "Rename": "重命名", "RenameWidget": "重命名组件", - "Resize": "调整大小", - "Right": "右侧", - "Run Branch": "运行支流节点", - "Save Image": "保存图像", - "Save Selected as Template": "将选定节点另存为模板", - "Search": "搜索", + "Copy": "复制", + "Duplicate": "复制", + "Paste": "站贴", + "Node Info": "节点信息", + "Adjust Size": "调整尺寸", + "Minimize Node": "最小化节点", + "Expand Node": "展开节点", "Shape": "形状", - "Shapes": "形状", - "Title": "标题", - "Top": "顶部", + "Color": "颜色", + "Add Subgraph to Library": "添加子工作流到节点库", "Unpack Subgraph": "解包子工作流", - "Unpin": "取消固定", + "Edit Subgraph Widgets": "编辑子工作流组件", + "Convert to Subgraph": "转换为子工作流", + "Align Selected To": "对齐选中项到", + "Distribute Nodes": "分布节点", + "Remove Bypass": "删除所有忽略节点", + "Run Branch": "运行支流节点", + "Delete": "删除", + "Top": "顶部", + "Bottom": "底部", + "Left": "左侧", + "Right": "右侧", + "Horizontal": "水平", "Vertical": "竖直", + "new": "新", "deprecated": "弃用", - "new": "新" + "Extensions": "扩展" }, "icon": { "bookmark": "书签", + "folder": "文件夹", + "star": "星星", + "heart": "心", + "file": "文件", + "inbox": "收件箱", "box": "盒子", "briefcase": "公文包", - "exclamation-triangle": "警告", - "file": "文件", - "folder": "文件夹", - "heart": "心", - "inbox": "收件箱", - "star": "星星" + "exclamation-triangle": "警告" }, "welcome": { - "getStarted": "开始使用", - "title": "欢迎使用 ComfyUI" + "title": "欢迎使用 ComfyUI", + "getStarted": "开始使用" }, "userSelect": { + "newUser": "新用户", "enterUsername": "输入用户名", "existingUser": "用户已存在", - "newUser": "新用户", - "next": "下一步", - "selectUser": "选择用户" + "selectUser": "选择用户", + "next": "下一步" }, "notSupported": { - "continue": "继续", - "continueTooltip": "我确定我的设备是受支持的", + "title": "您的设备不受支持", + "message": "仅支持以下设备:", "illustrationAlt": "Sad girl illustration", "learnMore": "了解更多", - "message": "仅支持以下设备:", "reportIssue": "报告问题", "supportedDevices": { "macos": "MacOS (M1 或更高版本)", "windows": "Windows (支持 CUDA 的 Nvidia GPU)" }, - "title": "您的设备不受支持" + "continue": "继续", + "continueTooltip": "我确定我的设备是受支持的" }, "downloadGit": { - "gitWebsite": "下载 git", - "instructions": "请下载并安装适合您操作系统的最新版本。下面的下载 git 按钮将打开 git-scm.com 下载页面。", - "message": "无法找到 git。正常操作需要一个可用的 git 副本。", - "skip": "跳过", "title": "下载 git", - "warning": "如果您确定不需要安装 git,或者已经安装了 git,您可以点击跳过以绕过此检查。当前不支持在没有可用 git 副本的情况下运行 ComfyUI。" + "message": "无法找到 git。正常操作需要一个可用的 git 副本。", + "instructions": "请下载并安装适合您操作系统的最新版本。下面的下载 git 按钮将打开 git-scm.com 下载页面。", + "warning": "如果您确定不需要安装 git,或者已经安装了 git,您可以点击跳过以绕过此检查。当前不支持在没有可用 git 副本的情况下运行 ComfyUI。", + "gitWebsite": "下载 git", + "skip": "跳过" }, "install": { + "installLocation": "安装位置", + "migration": "迁移", + "desktopSettings": "桌面设置", + "chooseInstallationLocation": "选择安装位置", + "gpuPicker": { + "title": "选择您的硬件配置", + "recommended": "推荐", + "nvidiaSubtitle": "NVIDIA CUDA", + "cpuSubtitle": "CPU模式", + "manualSubtitle": "手动设置", + "appleMetalDescription": "利用您的Mac GPU以获得更快速度和更佳体验", + "nvidiaDescription": "使用NVIDIA GPU和CUDA加速以获得最佳性能。", + "cpuDescription": "当GPU加速不可用时,使用CPU模式以获得兼容性", + "manualDescription": "为高级配置或不受支持的硬件手动配置ComfyUI" + }, + "locationPicker": { + "title": "选择ComfyUI的安装位置", + "subtitle": "选择一个文件夹用于存放ComfyUI文件。我们也会自动在此处设置Python。", + "pathPlaceholder": "/Users/username/Documents/ComfyUI", + "migrationPathPlaceholder": "选择已有的ComfyUI安装(可选)", + "migrateFromExisting": "从现有安装迁移", + "migrateDescription": "从之前的ComfyUI安装复制或链接您的模型、自定义节点和配置。", + "chooseDownloadServers": "手动选择下载服务器", + "downloadServersDescription": "根据您的位置选择用于下载Python、PyPI包和PyTorch的特定镜像服务器。" + }, + "systemLocations": "系统位置", + "failedToSelectDirectory": "选择目录失败", + "pathValidationFailed": "路径验证失败", + "pathExists": "目录已存在 - 请确保您已备份全部数据", + "cannotWrite": "无法写入所选路径。", + "insufficientFreeSpace": "空间不足 - 最小可用空间", + "isOneDrive": "在OneDrive中安装可能会导致问题。强烈建议在非OneDrive位置安装。", + "insideAppInstallDir": "该文件夹位于 ComfyUI Desktop 应用程序包中,程序更新时会删除该文件夹。选择安装文件夹之外的目录,例如 Documents/ComfyUI。", + "insideUpdaterCache": "该文件夹位于 ComfyUI 更新缓存中,程序更新时会清除该缓存。为您的数据选择一个不同的位置。", + "nonDefaultDrive": "请在您的系统驱动器上安装ComfyUI(例如C:\\)。具有不同文件系统的驱动器可能会导致不可预测的问题。安装后,模型和其他文件可以存储在其他驱动器上。", + "parentMissing": "路径不存在 - 请先创建包含该路径的目录", + "unhandledError": "未知错误", + "installLocationDescription": "选择 ComfyUI 用户数据的存放目录。将安装一个 Python 环境到所选位置。请确保所选磁盘有足够的空间(约 15GB)。", + "installLocationTooltip": "ComfyUI 的用户数据目录。存储:\n- Python 环境\n- 模型\n- 自定义节点\n", "appDataLocationTooltip": "ComfyUI 的应用数据目录。存储:\n- 日志\n- 服务器配置", "appPathLocationTooltip": "ComfyUI 的应用资产目录。存储 ComfyUI 代码和资产", - "cannotWrite": "无法写入所选路径。", - "chooseInstallationLocation": "选择安装位置", - "customNodes": "自定义节点", - "customNodesDescription": "引用现有 ComfyUI 安装的自定义节点文件并安装其依赖项。", + "migrateFromExistingInstallation": "从现有安装迁移", + "migrationSourcePathDescription": "如果您已有现有的ComfyUI安装,我们可以复制/链接您现有的用户文件和模型到新的安装。您现有的ComfyUI安装将不会受到影响。", + "selectItemsToMigrate": "选择要迁移的项目", + "migrationOptional": "迁移是可选的。如果您之前没有安装过 ComfyUI,可以跳过此步骤。", "desktopAppSettings": "桌面应用设置", "desktopAppSettingsDescription": "配置 ComfyUI 在桌面上的行为。您可以稍后更改这些设置。", - "desktopSettings": "桌面设置", - "failedToSelectDirectory": "选择目录失败", "gpu": "GPU", - "gpuPicker": { - "appleMetalDescription": "利用您的Mac GPU以获得更快速度和更佳体验", - "cpuDescription": "当GPU加速不可用时,使用CPU模式以获得兼容性", - "cpuSubtitle": "CPU模式", - "manualDescription": "为高级配置或不受支持的硬件手动配置ComfyUI", - "manualSubtitle": "手动设置", - "nvidiaDescription": "使用NVIDIA GPU和CUDA加速以获得最佳性能。", - "nvidiaSubtitle": "NVIDIA CUDA", - "recommended": "推荐", - "title": "选择您的硬件配置" - }, "gpuSelection": { + "selectGpu": "选择 GPU", + "selectGpuDescription": "选择你拥有的 GPU 类型", "cpuMode": "CPU 模式", "cpuModeDescription": "CPU 模式仅适用于开发者和极少数特殊情况。", "cpuModeDescription2": "如果你不完全确定你需要这个,忽略该选项并在上面选择你的 GPU。", - "customComfyNeedsPython": "在 python 完成设置前,ComfyUI 将无法工作", - "customInstallRequirements": "安装所有需求和依赖项(例如:自定义 torch)", - "customManualVenv": "手动配置 python 虚拟环境", - "customMayNotWork": "完全不支持,可能无法工作", - "customSkipsPython": "此选项跳过正常的 python 设置。", "enableCpuMode": "启用 CPU 模式", - "mpsDescription": "Apple Metal Performance Shaders 使用 pytorch nightly 支持。", "nvidiaDescription": "NVIDIA 设备直接支持使用 pytorch CUDA 构建。", - "selectGpu": "选择 GPU", - "selectGpuDescription": "选择你拥有的 GPU 类型" - }, - "helpImprove": "请帮助我们改进ComfyUI", - "insideAppInstallDir": "该文件夹位于 ComfyUI Desktop 应用程序包中,程序更新时会删除该文件夹。选择安装文件夹之外的目录,例如 Documents/ComfyUI。", - "insideUpdaterCache": "该文件夹位于 ComfyUI 更新缓存中,程序更新时会清除该缓存。为您的数据选择一个不同的位置。", - "installLocation": "安装位置", - "installLocationDescription": "选择 ComfyUI 用户数据的存放目录。将安装一个 Python 环境到所选位置。请确保所选磁盘有足够的空间(约 15GB)。", - "installLocationTooltip": "ComfyUI 的用户数据目录。存储:\n- Python 环境\n- 模型\n- 自定义节点\n", - "insufficientFreeSpace": "空间不足 - 最小可用空间", - "isOneDrive": "在OneDrive中安装可能会导致问题。强烈建议在非OneDrive位置安装。", - "locationPicker": { - "chooseDownloadServers": "手动选择下载服务器", - "downloadServersDescription": "根据您的位置选择用于下载Python、PyPI包和PyTorch的特定镜像服务器。", - "migrateDescription": "从之前的ComfyUI安装复制或链接您的模型、自定义节点和配置。", - "migrateFromExisting": "从现有安装迁移", - "migrationPathPlaceholder": "选择已有的ComfyUI安装(可选)", - "pathPlaceholder": "/Users/username/Documents/ComfyUI", - "subtitle": "选择一个文件夹用于存放ComfyUI文件。我们也会自动在此处设置Python。", - "title": "选择ComfyUI的安装位置" + "mpsDescription": "Apple Metal Performance Shaders 使用 pytorch nightly 支持。", + "customSkipsPython": "此选项跳过正常的 python 设置。", + "customComfyNeedsPython": "在 python 完成设置前,ComfyUI 将无法工作", + "customManualVenv": "手动配置 python 虚拟环境", + "customInstallRequirements": "安装所有需求和依赖项(例如:自定义 torch)", + "customMayNotWork": "完全不支持,可能无法工作" }, "manualConfiguration": { - "createVenv": "您需要在以下目录中创建虚拟环境", - "requirements": "依赖项", - "restartWhenFinished": "配置虚拟环境完成后,请重新启动ComfyUI。", "title": "手动配置", - "virtualEnvironmentPath": "虚拟环境路径" + "requirements": "依赖项", + "createVenv": "您需要在以下目录中创建虚拟环境", + "virtualEnvironmentPath": "虚拟环境路径", + "restartWhenFinished": "配置虚拟环境完成后,请重新启动ComfyUI。" }, - "metricsDisabled": "禁用度量", - "metricsEnabled": "启用度量", - "migrateFromExistingInstallation": "从现有安装迁移", - "migration": "迁移", - "migrationOptional": "迁移是可选的。如果您之前没有安装过 ComfyUI,可以跳过此步骤。", - "migrationSourcePathDescription": "如果您已有现有的ComfyUI安装,我们可以复制/链接您现有的用户文件和模型到新的安装。您现有的ComfyUI安装将不会受到影响。", - "moreInfo": "有关更多信息,请阅读我们的", - "nonDefaultDrive": "请在您的系统驱动器上安装ComfyUI(例如C:\\)。具有不同文件系统的驱动器可能会导致不可预测的问题。安装后,模型和其他文件可以存储在其他驱动器上。", - "parentMissing": "路径不存在 - 请先创建包含该路径的目录", - "pathExists": "目录已存在 - 请确保您已备份全部数据", - "pathValidationFailed": "路径验证失败", - "privacyPolicy": "隐私政策", - "selectItemsToMigrate": "选择要迁移的项目", "settings": { - "allowMetrics": "使用情况指标", - "allowMetricsDescription": "通过发送匿名使用情况指标来帮助改进ComfyUI。不会收集任何个人信息或工作流内容。", "autoUpdate": "自动更新", + "allowMetrics": "使用情况指标", + "errorUpdatingConsent": "更新同意错误", + "errorUpdatingConsentDetail": "无法更新度量同意设置", "autoUpdateDescription": "更新可用时自动更新。您将在安装更新之前收到通知。", - "checkingMirrors": "正在检查到Python镜像的网络访问...", + "allowMetricsDescription": "通过发送匿名使用情况指标来帮助改进ComfyUI。不会收集任何个人信息或工作流内容。", + "learnMoreAboutData": "了解更多关于数据收集的信息", "dataCollectionDialog": { + "title": "关于数据收集", + "whatWeCollect": "我们收集的内容:", + "whatWeDoNotCollect": "我们不收集的内容:", "collect": { "errorReports": "错误报告和堆栈跟踪", "systemInfo": "硬件,操作系统类型和应用版本", "userJourneyEvents": "用户旅程事件" }, "doNotCollect": { - "customNodeConfigurations": "自定义节点配置", - "fileSystemInformation": "文件系统信息", "personalInformation": "个人信息", - "workflowContents": "工作流内容" + "fileSystemInformation": "文件系统信息", + "workflowContents": "工作流内容", + "customNodeConfigurations": "自定义节点配置" }, - "title": "关于数据收集", - "viewFullPolicy": "查看完整政策", - "whatWeCollect": "我们收集的内容:", - "whatWeDoNotCollect": "我们不收集的内容:" + "viewFullPolicy": "查看完整政策" }, - "errorUpdatingConsent": "更新同意错误", - "errorUpdatingConsentDetail": "无法更新度量同意设置", - "learnMoreAboutData": "了解更多关于数据收集的信息", - "mirrorSettings": "镜像设置", + "pythonMirrorPlaceholder": "输入Python镜像URL", + "pypiMirrorPlaceholder": "输入PyPI镜像URL", + "checkingMirrors": "正在检查到Python镜像的网络访问...", "mirrorsReachable": "到Python镜像的网络访问良好", "mirrorsUnreachable": "对某些python镜像的网络访问不佳", - "pypiMirrorPlaceholder": "输入PyPI镜像URL", - "pythonMirrorPlaceholder": "输入Python镜像URL" + "mirrorSettings": "镜像设置" }, - "systemLocations": "系统位置", - "unhandledError": "未知错误", + "customNodes": "自定义节点", + "customNodesDescription": "引用现有 ComfyUI 安装的自定义节点文件并安装其依赖项。", + "helpImprove": "请帮助我们改进ComfyUI", + "moreInfo": "有关更多信息,请阅读我们的", + "privacyPolicy": "隐私政策", + "metricsEnabled": "启用度量", + "metricsDisabled": "禁用度量", "updateConsent": "您之前选择了报告崩溃。我们现在正在跟踪基于事件的度量,以帮助识别错误并改进应用程序。我们不收集任何个人可识别信息。" }, "desktopStart": { "initialising": "正在初始化..." }, "serverStart": { - "copyAllTooltip": "全部复制", + "title": "启动 ComfyUI", + "troubleshoot": "故障排除", + "reportIssue": "报告问题", + "openLogs": "打开日志", + "showTerminal": "显示终端", "copySelectionTooltip": "复制所选内容", + "copyAllTooltip": "全部复制", "errorMessage": "无法启动 ComfyUI 桌面版", "installation": { "title": "正在安装 ComfyUI" }, - "openLogs": "打开日志", "process": { - "error": "无法启动 ComfyUI 桌面版", "initial-state": "加载中...", "python-setup": "正在设置 Python 环境...", + "starting-server": "正在启动 ComfyUI 服务器...", "ready": "完成中...", - "starting-server": "正在启动 ComfyUI 服务器..." - }, - "reportIssue": "报告问题", - "showTerminal": "显示终端", - "title": "启动 ComfyUI", - "troubleshoot": "故障排除" + "error": "无法启动 ComfyUI 桌面版" + } }, "serverConfig": { "modifiedConfigs": "您已修改以下服务器配置。重启以应用更改。", + "revertChanges": "撤销更改", "restart": "重启", - "restartRequiredToastDetail": "重启软件应用设置。", "restartRequiredToastSummary": "需要重启", - "revertChanges": "撤销更改" + "restartRequiredToastDetail": "重启软件应用设置。" }, "shape": { - "CARD": "卡片", - "arrow": "箭头", - "box": "方框", - "circle": "圆形", "default": "默认", - "round": "圆角" + "round": "圆角", + "CARD": "卡片", + "circle": "圆形", + "arrow": "箭头", + "box": "方框" }, "sideToolbar": { - "assets": "资产", - "backToAssets": "返回所有资产", - "browseTemplates": "浏览示例模板", - "downloads": "下载", + "themeToggle": "切换主题", "helpCenter": "帮助中心", - "labels": { - "assets": "资产", - "console": "控制台", - "generated": "已生成", - "imported": "已导入", - "menu": "菜单", - "models": "模型", - "nodes": "节点", - "queue": "队列", - "templates": "模板", - "workflows": "工作流" - }, "logout": "登出", + "queue": "队列", + "nodeLibrary": "节点库", + "workflows": "工作流", + "templates": "模板", + "assets": "资产", "mediaAssets": { - "filter3D": "3D", - "filterAudio": "音频", - "filterImage": "图像", - "filterVideo": "视频", - "sortFastestFirst": "生成时间(最快)", - "sortLongestFirst": "生成时间(最慢)", + "title": "媒体资产", "sortNewestFirst": "最新", "sortOldestFirst": "最旧", - "title": "媒体资产" + "sortLongestFirst": "生成时间(最慢)", + "sortFastestFirst": "生成时间(最快)", + "filterImage": "图像", + "filterVideo": "视频", + "filterAudio": "音频", + "filter3D": "3D" + }, + "backToAssets": "返回所有资产", + "searchAssets": "搜索资产", + "labels": { + "queue": "队列", + "nodes": "节点", + "models": "模型", + "assets": "资产", + "workflows": "工作流", + "templates": "模板", + "console": "控制台", + "menu": "菜单", + "imported": "已导入", + "generated": "已生成" }, - "modelLibrary": "模型库", - "newBlankWorkflow": "创建空白工作流", "noFilesFound": "未找到文件", - "noFilesFoundMessage": "上传文件或生成内容以在此处查看", - "noGeneratedFiles": "未找到生成的文件", "noImportedFiles": "未找到导入的文件", - "nodeLibrary": "节点库", + "noGeneratedFiles": "未找到生成的文件", + "noFilesFoundMessage": "上传文件或生成内容以在此处查看", + "browseTemplates": "浏览示例模板", + "openWorkflow": "在本地文件系统中打开工作流", + "newBlankWorkflow": "创建空白工作流", "nodeLibraryTab": { "groupBy": "分组方式", + "sortMode": "排序模式", + "resetView": "重置视图为默认", "groupStrategies": { "category": "类别", "categoryDesc": "按节点类别分组", @@ -694,73 +701,67 @@ "source": "来源", "sourceDesc": "按来源类型分组(核心,自定义,API)" }, - "resetView": "重置视图为默认", "sortBy": { - "alphabetical": "字母顺序", - "alphabeticalDesc": "在分组内按字母顺序排序", "original": "原始顺序", - "originalDesc": "保持原始顺序" - }, - "sortMode": "排序模式" - }, - "openWorkflow": "在本地文件系统中打开工作流", - "queue": "队列", - "queueProgressOverlay": { - "activeJobsSuffix": "活跃任务", - "cancelJobTooltip": "取消任务", - "clearHistory": "清除任务记录", - "clearHistoryDialogAssetsNote": "这些任务生成的资产不会被删除,并且始终可以在资产面板中查看。", - "clearHistoryDialogDescription": "以下所有已完成或失败的任务将从队列面板中删除。", - "clearHistoryDialogTitle": "确定要清除任务记录?", - "clearQueueTooltip": "清理队列", - "clearQueued": "清除已执行", - "colonPercent": ":{percent}", - "currentNode": "当前节点:", - "expandCollapsedQueue": "展开任务队列", - "filterAllWorkflows": "全部工作流", - "filterBy": "筛选方式", - "filterCurrentWorkflow": "当前工作流", - "filterJobs": "筛选任务", - "interruptAll": "中断全部正在运行的任务", - "jobQueue": "任务队列", - "jobsCompleted": "{count} 任务完成 | {count} 任务完成", - "jobsFailed": "{count} 任务失败 | {count} 任务失败", - "moreOptions": "更多设置", - "noActiveJobs": "无活跃任务", - "preview": "预览", - "queuedSuffix": "已执行", - "running": "运行中", - "showAssets": "显示资产", - "showAssetsPanel": "显示资产面板", - "sortBy": "排序方式", - "sortJobs": "排序任务", - "stubClipTextEncode": "CLIP文本编码:", - "title": "队列进度", - "total": "全部:{percent}", - "viewAllJobs": "查看全部任务", - "viewJobHistory": "查看任务记录" - }, - "searchAssets": "搜索资产", - "templates": "模板", - "themeToggle": "切换主题", - "workflowTab": { - "confirmDelete": "您确定要删除此工作流吗?", - "confirmDeleteTitle": "删除工作流?", - "confirmOverwrite": "下面的文件已经存在。您想要覆盖它吗?", - "confirmOverwriteTitle": "覆盖现有文件?", - "deleteFailed": "尝试删除工作流失败。", - "deleteFailedTitle": "删除失败", - "deleted": "工作流已删除", - "dirtyClose": "以下文件已被更改。您想在关闭之前保存它们吗?", - "dirtyCloseHint": "按住 Shift 关闭而不提示", - "dirtyCloseTitle": "保存更改?", - "workflowTreeType": { - "bookmarks": "书签", - "browse": "浏览", - "open": "打开" + "originalDesc": "保持原始顺序", + "alphabetical": "字母顺序", + "alphabeticalDesc": "在分组内按字母顺序排序" } }, - "workflows": "工作流" + "modelLibrary": "模型库", + "downloads": "下载", + "queueProgressOverlay": { + "title": "队列进度", + "total": "全部:{percent}", + "colonPercent": ":{percent}", + "currentNode": "当前节点:", + "viewAllJobs": "查看全部任务", + "running": "运行中", + "preview": "预览", + "interruptAll": "中断全部正在运行的任务", + "moreOptions": "更多设置", + "showAssets": "显示资产", + "showAssetsPanel": "显示资产面板", + "queuedSuffix": "已执行", + "clearQueued": "清除已执行", + "clearHistory": "清除任务记录", + "filterJobs": "筛选任务", + "filterBy": "筛选方式", + "filterAllWorkflows": "全部工作流", + "filterCurrentWorkflow": "当前工作流", + "sortJobs": "排序任务", + "sortBy": "排序方式", + "activeJobsSuffix": "活跃任务", + "jobQueue": "任务队列", + "expandCollapsedQueue": "展开任务队列", + "viewJobHistory": "查看任务记录", + "noActiveJobs": "无活跃任务", + "stubClipTextEncode": "CLIP文本编码:", + "jobsCompleted": "{count} 任务完成 | {count} 任务完成", + "jobsFailed": "{count} 任务失败 | {count} 任务失败", + "cancelJobTooltip": "取消任务", + "clearQueueTooltip": "清理队列", + "clearHistoryDialogTitle": "确定要清除任务记录?", + "clearHistoryDialogDescription": "以下所有已完成或失败的任务将从队列面板中删除。", + "clearHistoryDialogAssetsNote": "这些任务生成的资产不会被删除,并且始终可以在资产面板中查看。" + }, + "workflowTab": { + "confirmDeleteTitle": "删除工作流?", + "confirmDelete": "您确定要删除此工作流吗?", + "deleted": "工作流已删除", + "deleteFailedTitle": "删除失败", + "deleteFailed": "尝试删除工作流失败。", + "dirtyCloseTitle": "保存更改?", + "dirtyClose": "以下文件已被更改。您想在关闭之前保存它们吗?", + "dirtyCloseHint": "按住 Shift 关闭而不提示", + "confirmOverwriteTitle": "覆盖现有文件?", + "confirmOverwrite": "下面的文件已经存在。您想要覆盖它吗?", + "workflowTreeType": { + "browse": "浏览", + "bookmarks": "书签", + "open": "打开" + } + } }, "helpCenter": { "feedback": "提交反馈", @@ -793,100 +794,100 @@ "description": "在此更新中尝试最新的改进和功能。" }, "menu": { - "autoQueue": "自动执行", + "hideMenu": "隐藏菜单", + "showMenu": "显示菜单", "batchCount": "批次数量", "batchCountTooltip": "工作流生成次数", - "clear": "清空工作流", - "clipspace": "打开剪贴板", - "dark": "深色", + "autoQueue": "自动执行", "disabled": "禁用", "disabledTooltip": "工作流将不会自动执行", - "execute": "执行", - "help": "说明", - "hideMenu": "隐藏菜单", "instant": "实时", "instantTooltip": "工作流将会在生成完成后立即执行", - "interrupt": "取消当前任务", - "light": "淺色", - "manageExtensions": "管理扩展功能", "onChange": "更改时", "onChangeTooltip": "一旦进行更改,工作流将添加到执行队列", - "queue": "队列面板", - "refresh": "刷新节点", - "resetView": "重置视图", - "run": "运行", "runWorkflow": "运行工作流(Shift排在前面)", - "runWorkflowDisabled": "工作流包含不支持的节点(已用红色突出显示)。删除这些节点以运行工作流。", "runWorkflowFront": "运行工作流(排在前面)", - "settings": "设定", - "showMenu": "显示菜单", - "theme": "主题", + "runWorkflowDisabled": "工作流包含不支持的节点(已用红色突出显示)。删除这些节点以运行工作流。", + "run": "运行", + "execute": "执行", + "interrupt": "取消当前任务", + "refresh": "刷新节点", + "clipspace": "打开剪贴板", + "resetView": "重置视图", + "clear": "清空工作流", "toggleBottomPanel": "底部面板", - "customNodesManager": "自定义节点管理器" + "theme": "主题", + "dark": "深色", + "light": "淺色", + "manageExtensions": "管理扩展功能", + "customNodesManager": "自定义节点管理器", + "settings": "设定", + "help": "说明", + "queue": "队列面板" }, "tabMenu": { - "addToBookmarks": "添加到书签", - "closeOtherTabs": "关闭其他标签", + "duplicateTab": "复制标签", "closeTab": "关闭标签", "closeTabsToLeft": "关闭左侧标签", "closeTabsToRight": "关闭右侧标签", - "duplicateTab": "复制标签", + "closeOtherTabs": "关闭其他标签", + "addToBookmarks": "添加到书签", "removeFromBookmarks": "从书签中移除" }, "templateWorkflows": { - "activeFilters": "筛选条件:", - "allTemplates": "全部模板", - "categories": "分类", + "title": "从模板开始", + "loadingMore": "正在加载更多模板...", + "searchPlaceholder": "搜索模板...", "category": { - "3D": "3D", - "All": "所有模板", - "Area Composition": "区域合成", - "Audio": "音频生成", - "Basics": "基础", "ComfyUI Examples": "ComfyUI示例", - "ControlNet": "ControlNet", "Custom Nodes": "自定义节点", - "Extensions": "扩展", - "Flux": "Flux", - "Generation Type": "生成类型", + "Basics": "基础", "GettingStarted": "入门", - "Image": "图像生成", - "Image API": "图像 API", - "LLM API": "LLM API", - "LLMs": "LLMs", - "Partner Nodes": "合作伙伴节点", + "Flux": "Flux", + "ControlNet": "ControlNet", "Upscaling": "图像放大", "Video": "视频生成", - "Video API": "视频 API" + "Image": "图像生成", + "Area Composition": "区域合成", + "3D": "3D", + "Audio": "音频生成", + "LLMs": "LLMs", + "Image API": "图像 API", + "Video API": "视频 API", + "LLM API": "LLM API", + "All": "所有模板", + "Extensions": "扩展", + "Partner Nodes": "合作伙伴节点", + "Generation Type": "生成类型" + }, + "categories": "分类", + "resetFilters": "清除筛选", + "sorting": "排序方式", + "activeFilters": "筛选条件:", + "loading": "正在加载模板...", + "noResults": "未找到模板", + "noResultsHint": "请尝试调整搜索或筛选条件", + "allTemplates": "全部模板", + "modelFilter": "模型筛选", + "useCaseFilter": "使用例", + "licenseFilter": "许可证", + "modelsSelected": "已选 {count} 个模型", + "useCasesSelected": "已选 {count} 个用例", + "runsOnSelected": "{count} 次运行", + "runsOnFilter": "运行于", + "resultsCount": "显示 {count} / 共 {total} 个模板", + "sort": { + "recommended": "推荐", + "alphabetical": "A → Z", + "newest": "最新", + "searchPlaceholder": "搜索...", + "vramLowToHigh": "VRAM 使用量(从低到高)", + "modelSizeLowToHigh": "模型大小(从低到高)", + "default": "默认" }, "error": { "templateNotFound": "未找到模板 \"{templateName}\"" - }, - "licenseFilter": "许可证", - "loading": "正在加载模板...", - "loadingMore": "正在加载更多模板...", - "modelFilter": "模型筛选", - "modelsSelected": "已选 {count} 个模型", - "noResults": "未找到模板", - "noResultsHint": "请尝试调整搜索或筛选条件", - "resetFilters": "清除筛选", - "resultsCount": "显示 {count} / 共 {total} 个模板", - "runsOnFilter": "运行于", - "runsOnSelected": "{count} 次运行", - "searchPlaceholder": "搜索模板...", - "sort": { - "alphabetical": "A → Z", - "default": "默认", - "modelSizeLowToHigh": "模型大小(从低到高)", - "newest": "最新", - "recommended": "推荐", - "searchPlaceholder": "搜索...", - "vramLowToHigh": "VRAM 使用量(从低到高)" - }, - "sorting": "排序方式", - "title": "从模板开始", - "useCaseFilter": "使用例", - "useCasesSelected": "已选 {count} 个用例" + } }, "templateWidgets": { "sort": { @@ -894,172 +895,172 @@ } }, "graphCanvasMenu": { - "fitView": "适应视图", - "focusMode": "专注模式", - "hand": "拖拽", - "hideLinks": "隐藏链接", - "panMode": "平移模式", - "resetView": "重置视图", - "select": "选择", - "selectMode": "选择模式", - "showLinks": "显示链接", - "toggleLinkVisibility": "切换链接可见性", - "toggleMinimap": "切换小地图", "zoomIn": "放大", + "zoomOut": "缩小", + "resetView": "重置视图", + "fitView": "适应视图", + "selectMode": "选择模式", + "panMode": "平移模式", + "toggleMinimap": "切换小地图", + "select": "选择", + "hand": "拖拽", "zoomOptions": "缩放选项", - "zoomOut": "缩小" + "focusMode": "专注模式", + "hideLinks": "隐藏链接", + "showLinks": "显示链接", + "toggleLinkVisibility": "切换链接可见性" }, "zoomControls": { - "hideMinimap": "隐藏小地图", "label": "缩放控制", + "zoomToFit": "适合画面", "showMinimap": "显示小地图", - "zoomToFit": "适合画面" + "hideMinimap": "隐藏小地图" }, "groupNode": { "create": "创建组节点", "enterName": "输入名称" }, "nodeTemplates": { - "enterName": "输入名称", - "saveAsTemplate": "另存为模板" + "saveAsTemplate": "另存为模板", + "enterName": "输入名称" }, "workflowService": { - "enterFilename": "输入文件名", "exportWorkflow": "导出工作流", + "enterFilename": "输入文件名", "saveWorkflow": "保存工作流" }, "subgraphStore": { - "blueprintName": "子工作流名称", - "confirmDelete": "此操作将永久从您的库中移除该子工作流", "confirmDeleteTitle": "删除子工作流?", - "hidden": "隐藏/嵌套参数", - "hideAll": "全部隐藏", - "loadFailure": "加载子工作流蓝图失败", - "overwriteBlueprint": "保存将用您的更改覆盖当前子工作流", + "confirmDelete": "此操作将永久从您的库中移除该子工作流", + "saveBlueprint": "保存子工作流到节点库", "overwriteBlueprintTitle": "覆盖现有子工作流?", + "overwriteBlueprint": "保存将用您的更改覆盖当前子工作流", + "blueprintName": "子工作流名称", "promoteOutsideSubgraph": "不在子工作流中时无法提升小部件", "publish": "发布子工作流", "publishSuccess": "已保存到节点库", "publishSuccessMessage": "您可以在节点库的“子工作流蓝图”下找到您的子工作流蓝图", - "saveBlueprint": "保存子工作流到节点库", + "loadFailure": "加载子工作流蓝图失败", + "shown": "节点上显示", "showAll": "全部显示", - "showRecommended": "显示推荐控件", - "shown": "节点上显示" + "hidden": "隐藏/嵌套参数", + "hideAll": "全部隐藏", + "showRecommended": "显示推荐控件" }, "electronFileDownload": { - "cancel": "取消下载", - "cancelled": "已取消", "inProgress": "进行中", "pause": "暂停下载", "paused": "已暂停", - "resume": "恢复下载" + "resume": "恢复下载", + "cancel": "取消下载", + "cancelled": "已取消" }, "maskEditor": { - "activateLayer": "活跃层", - "applyToWholeImage": "应用到图像整体", - "baseImageLayer": "基础图像层", - "baseLayerPreview": "基础图像层预览", - "black": "黑", + "title": "遮罩编辑器", + "invert": "反转", + "clear": "清除", + "undo": "撤回", + "redo": "重做", + "clickToResetZoom": "点击重置缩放", "brushSettings": "笔刷设置", "brushShape": "笔刷形状", - "clear": "清除", - "clickToResetZoom": "点击重置缩放", - "colorSelectSettings": "色彩选取设置", "colorSelector": "色彩选取", - "fillOpacity": "填充不透明度", + "thickness": "厚度", + "opacity": "不透明度", "hardness": "硬度", - "imageLayer": "图像层", - "invert": "反转", - "layers": "图层", + "stepSize": "间距", + "smoothingPrecision": "预测平滑", + "resetToDefault": "重置为默认", + "paintBucketSettings": "填充设置", + "tolerance": "阈值", + "fillOpacity": "填充不透明度", + "colorSelectSettings": "色彩选取设置", + "selectionOpacity": "选取不透明度", "livePreview": "实时预览", - "maskBlendingOptions": "遮罩混合设置", + "applyToWholeImage": "应用到图像整体", + "method": "方法", + "stopAtMask": "遇到遮罩时停止", + "maskTolerance": "遮罩阈值", + "layers": "图层", "maskLayer": "遮罩层", "maskOpacity": "遮罩不透明度", - "maskTolerance": "遮罩阈值", - "method": "方法", - "negative": "负面", - "opacity": "不透明度", - "paintBucketSettings": "填充设置", + "imageLayer": "图像层", + "maskBlendingOptions": "遮罩混合设置", "paintLayer": "绘画层", - "redo": "重做", - "resetToDefault": "重置为默认", - "selectionOpacity": "选取不透明度", - "smoothingPrecision": "预测平滑", - "stepSize": "间距", - "stopAtMask": "遇到遮罩时停止", - "thickness": "厚度", - "title": "遮罩编辑器", - "tolerance": "阈值", - "undo": "撤回", - "white": "白" + "baseImageLayer": "基础图像层", + "activateLayer": "活跃层", + "baseLayerPreview": "基础图像层预览", + "black": "黑", + "white": "白", + "negative": "负面" }, "commands": { - "clear": "清空工作流", - "clipspace": "打开 Clipspace", - "dark": "深色", - "execute": "执行", - "help": "帮助", - "interrupt": "取消当前运行", - "light": "浅色", - "manageExtensions": "管理扩展", - "queue": "队列面板", - "refresh": "刷新节点定义", - "resetView": "重置画布视图", - "run": "运行", "runWorkflow": "运行工作流", "runWorkflowFront": "运行工作流(队列前端)", - "settings": "设置", + "run": "运行", + "execute": "执行", + "interrupt": "取消当前运行", + "refresh": "刷新节点定义", + "clipspace": "打开 Clipspace", + "resetView": "重置画布视图", + "clear": "清空工作流", + "toggleBottomPanel": "切换底部面板", "theme": "主题", - "toggleBottomPanel": "切换底部面板" + "dark": "深色", + "light": "浅色", + "manageExtensions": "管理扩展", + "settings": "设置", + "help": "帮助", + "queue": "队列面板" }, "queue": { - "completedIn": "{duration} 后完成", - "inQueue": "正在执行...", "initializingAlmostReady": "初始化中 - 即将完成", + "inQueue": "正在执行...", "jobAddedToQueue": "任务添加到队列", - "jobDetails": { - "computeHoursUsed": "计算耗时", - "errorMessage": "报错信息", - "estimatedFinishIn": "预计完成于", - "estimatedStartIn": "预计开始于", - "eta": { - "minutes": "~{count} 分钟 | ~{count} 分钟", - "minutesRange": "~{lo}-{hi} 分钟", - "seconds": "~{count} 秒 | ~{count} 秒", - "secondsRange": "~{lo}-{hi} 秒" - }, - "failedAfter": "失败于", - "generatedOn": "生成于", - "header": "任务细节", - "jobId": "任务ID", - "queuePosition": "队列位置", - "queuePositionValue": "在您前方有 ~{count} 个任务 | 在您前方有 ~{count} 个任务", - "queuedAt": "执行于", - "report": "反馈", - "timeElapsed": "耗时", - "totalGenerationTime": "总生成时间", - "workflow": "工作流" - }, - "jobList": { - "sortComputeHoursUsed": "计算用时(最先)", - "sortMostRecent": "最新", - "sortTotalGenerationTime": "生成时间(最慢)", - "undated": "无日期" - }, + "completedIn": "{duration} 后完成", "jobMenu": { - "addToCurrentWorkflow": "添加到当前工作流", - "cancelJob": "取消任务", - "copyErrorMessage": "复制报错信息", - "copyJobId": "复制任务ID", - "delete": "删除", - "deleteAsset": "删除资产", - "download": "下载", - "exportWorkflow": "导出工作流", - "inspectAsset": "查看资产", "openAsWorkflowNewTab": "在新标签页中读取工作流", "openWorkflowNewTab": "在新标签页中打开工作流", + "copyJobId": "复制任务ID", + "cancelJob": "取消任务", + "inspectAsset": "查看资产", + "addToCurrentWorkflow": "添加到当前工作流", + "download": "下载", + "exportWorkflow": "导出工作流", + "delete": "删除", + "deleteAsset": "删除资产", "removeJob": "移除任务", + "copyErrorMessage": "复制报错信息", "reportError": "反馈报错" + }, + "jobList": { + "undated": "无日期", + "sortMostRecent": "最新", + "sortTotalGenerationTime": "生成时间(最慢)", + "sortComputeHoursUsed": "计算用时(最先)" + }, + "jobDetails": { + "header": "任务细节", + "workflow": "工作流", + "jobId": "任务ID", + "queuedAt": "执行于", + "queuePosition": "队列位置", + "timeElapsed": "耗时", + "estimatedStartIn": "预计开始于", + "estimatedFinishIn": "预计完成于", + "generatedOn": "生成于", + "totalGenerationTime": "总生成时间", + "computeHoursUsed": "计算耗时", + "failedAfter": "失败于", + "errorMessage": "报错信息", + "report": "反馈", + "queuePositionValue": "在您前方有 ~{count} 个任务 | 在您前方有 ~{count} 个任务", + "eta": { + "seconds": "~{count} 秒 | ~{count} 秒", + "secondsRange": "~{lo}-{hi} 秒", + "minutes": "~{count} 分钟 | ~{count} 分钟", + "minutesRange": "~{lo}-{hi} 分钟" + } } }, "menuLabels": { @@ -1176,10 +1177,10 @@ "Workflows": "工作流" }, "desktopMenu": { - "confirmQuit": "有未保存的工作流开启;任何未保存的更改都将丢失。忽略此警告并退出?", + "reinstall": "重新安装", "confirmReinstall": "这将清除您的 extra_models_config.yaml 文件,并重新开始安装。您确定吗?", "quit": "退出", - "reinstall": "重新安装" + "confirmQuit": "有未保存的工作流开启;任何未保存的更改都将丢失。忽略此警告并退出?" }, "settingsCategories": { "Comfy-Desktop": "Comfy桌面版", @@ -1364,15 +1365,15 @@ } }, "serverConfigCategories": { - "Attention": "注意力", + "Network": "网络", "CUDA": "CUDA", - "Cache": "缓存", - "Directories": "目录", - "General": "常规", "Inference": "推理", "Memory": "内存", - "Network": "网络", - "Preview": "预览" + "Preview": "预览", + "Cache": "缓存", + "Attention": "注意力", + "General": "常规", + "Directories": "目录" }, "nodeCategories": { "_for_testing": "_用于测试", @@ -1532,31 +1533,31 @@ "WEBCAM": "摄像头" }, "maintenance": { + "title": "维护", + "allOk": "未检测到任何问题。", + "status": "状态", + "detected": "检测到", + "refreshing": "刷新中", "None": "无", "OK": "确定", "Skipped": "跳过", - "allOk": "未检测到任何问题。", - "confirmTitle": "你确定吗?", - "consoleLogs": "控制台日志", - "detected": "检测到", - "error": { - "cannotContinue": "无法继续 - 仍有错误", - "defaultDescription": "运行维护任务时发生错误。", - "taskFailed": "任务运行失败。", - "toastTitle": "任务错误" - }, - "refreshing": "刷新中", "showManual": "显示维护任务", - "status": "状态", + "confirmTitle": "你确定吗?", "terminalDefaultMessage": "当你运行一个故障排除命令时,任何输出都会在这里显示。", - "title": "维护", + "consoleLogs": "控制台日志", + "error": { + "toastTitle": "任务错误", + "taskFailed": "任务运行失败。", + "cannotContinue": "无法继续 - 仍有错误", + "defaultDescription": "运行维护任务时发生错误。" + }, "unsafeMigration": { - "action": "使用下方的 \"基本路径\" 维护将路径移动到安全位置。", - "appInstallDir": "您当前的 ComfyUI 基本路径位于 ComfyUI Desktop 应用程序包中,程序更新时会删除该文件夹。选择安装文件夹之外的目录,例如 Documents/ComfyUI。", - "generic": "您当前的 ComfyUI 基本路径所在的位置可能会在更新期间被删除或修改。为避免数据丢失,请将其移至安全文件夹。", - "oneDrive": "您当前的 ComfyUI 基本路径在 OneDrive上,这可能会导致同步问题和意外的数据丢失。选择一个不受 OneDrive 管理的本地文件夹。", "title": "检测到安装路径不安全", - "updaterCache": "您当前的 ComfyUI 基本路径位于 ComfyUI 更新缓存中,程序更新时会清除该缓存。为您的数据选择一个不同的位置。" + "generic": "您当前的 ComfyUI 基本路径所在的位置可能会在更新期间被删除或修改。为避免数据丢失,请将其移至安全文件夹。", + "appInstallDir": "您当前的 ComfyUI 基本路径位于 ComfyUI Desktop 应用程序包中,程序更新时会删除该文件夹。选择安装文件夹之外的目录,例如 Documents/ComfyUI。", + "updaterCache": "您当前的 ComfyUI 基本路径位于 ComfyUI 更新缓存中,程序更新时会清除该缓存。为您的数据选择一个不同的位置。", + "oneDrive": "您当前的 ComfyUI 基本路径在 OneDrive上,这可能会导致同步问题和意外的数据丢失。选择一个不受 OneDrive 管理的本地文件夹。", + "action": "使用下方的 \"基本路径\" 维护将路径移动到安全位置。" } }, "missingModelsDialog": { @@ -1565,47 +1566,50 @@ "missingModelsMessage": "加载工作流时,未找到以下模型" }, "versionMismatchWarning": { - "dismiss": "关闭", - "frontendNewer": "前端版本 {frontendVersion} 可能与后端版本 {backendVersion} 不相容。", - "frontendOutdated": "前端版本 {frontendVersion} 已过时。后端需要 {requiredVersion} 版或更高版本。", "title": "版本相容性警告", - "updateFrontend": "更新前端" + "frontendOutdated": "前端版本 {frontendVersion} 已过时。后端需要 {requiredVersion} 版或更高版本。", + "frontendNewer": "前端版本 {frontendVersion} 可能与后端版本 {backendVersion} 不相容。", + "updateFrontend": "更新前端", + "dismiss": "关闭" }, "loadWorkflowWarning": { - "coreNodesFromVersion": "核心节点来源于 {version} 版本。", "outdatedVersion": "这个工作流由新版 ComfyUI({version})创建,部分节点可能无法正常运行。", - "outdatedVersionGeneric": "这个工作流由新版 ComfyUI 创建,部分节点可能无法正常运行。" + "outdatedVersionGeneric": "这个工作流由新版 ComfyUI 创建,部分节点可能无法正常运行。", + "coreNodesFromVersion": "核心节点来源于 {version} 版本。" }, "errorDialog": { "defaultTitle": "发生错误", - "extensionFileHint": "这可能是由于以下脚本", "loadWorkflowTitle": "由于重新加载工作流数据出错,加载被中止", "noStackTrace": "无可用堆栈跟踪", + "extensionFileHint": "这可能是由于以下脚本", "promptExecutionError": "提示执行失败" }, "apiNodesSignInDialog": { - "message": "此工作流包含API节点,需要您登录账户才能运行。", - "title": "使用API节点需要登录" + "title": "使用API节点需要登录", + "message": "此工作流包含API节点,需要您登录账户才能运行。" }, "apiNodesCostBreakdown": { - "costPerRun": "每次运行的成本", "title": "API节点", + "costPerRun": "每次运行的成本", "totalCost": "总成本" }, "desktopUpdate": { - "description": "ComfyUI桌面正在安装新的依赖项。这可能需要几分钟的时间。", - "errorCheckingUpdate": "检查更新时出错", - "errorInstallingUpdate": "安装更新时出错", - "noUpdateFound": "未发现更新", - "terminalDefaultMessage": "更新过程中的任何控制台输出都将在这里显示。", "title": "正在更新ComfyUI桌面", + "description": "ComfyUI桌面正在安装新的依赖项。这可能需要几分钟的时间。", + "terminalDefaultMessage": "更新过程中的任何控制台输出都将在这里显示。", + "updateFoundTitle": "找到更新 (v{version})", "updateAvailableMessage": "有可用的更新。您现在要重启并更新吗?", - "updateFoundTitle": "找到更新 (v{version})" + "noUpdateFound": "未发现更新", + "errorCheckingUpdate": "检查更新时出错", + "errorInstallingUpdate": "安装更新时出错" }, "clipboard": { + "successMessage": "已复制到剪贴板", "errorMessage": "复制到剪贴板失败", - "errorNotSupported": "您的浏览器不支持剪贴板API", - "successMessage": "已复制到剪贴板" + "errorNotSupported": "您的浏览器不支持剪贴板API" + }, + "imageCompare": { + "noImages": "没有可以对比的图像" }, "load3d": { "switchCamera": "切换摄影机类型", @@ -1634,12 +1638,12 @@ "uploadTexture": "上传纹理", "applyingTexture": "应用纹理中...", "materialModes": { - "depth": "深度", - "lineart": "线稿", "normal": "法线", + "wireframe": "线框", "original": "原始", "pointCloud": "点云", - "wireframe": "线框" + "depth": "深度", + "lineart": "线稿" }, "upDirections": { "original": "原始" @@ -1651,19 +1655,19 @@ "resizeNodeMatchOutput": "调整节点以匹配输出", "loadingBackgroundImage": "正在加载背景图像", "cameraType": { - "orthographic": "正交", - "perspective": "透视" + "perspective": "透视", + "orthographic": "正交" }, "viewer": { + "title": "3D 查看器(测试版)", "apply": "应用", - "cameraSettings": "相机设置", - "cameraType": "相机类型", "cancel": "取消", - "exportSettings": "导出设置", - "lightSettings": "灯光设置", - "modelSettings": "模型设置", + "cameraType": "相机类型", "sceneSettings": "场景设置", - "title": "3D 查看器(测试版)" + "cameraSettings": "相机设置", + "lightSettings": "灯光设置", + "exportSettings": "导出设置", + "modelSettings": "模型设置" }, "openIn3DViewer": "在 3D 查看器中打开", "dropToLoad": "拖放 3D 模型以加载", @@ -1730,142 +1734,142 @@ "failedToUpdateBackgroundRenderMode": "切换背景模式到 {mode} 失败" }, "nodeErrors": { + "render": "节点渲染错误", "content": "节点内容错误", "header": "节点头错误", - "render": "节点渲染错误", "slots": "节点接口错误", "widgets": "节点组件错误" }, "auth": { "apiKey": { - "cleared": "API 密钥已清除", - "clearedDetail": "您的 API 密钥已成功清除", - "description": "使用您的 Comfy API 密钥以启用 API 节点", - "error": "无效的 API 密钥", - "generateKey": "在这里获取", - "helpText": "需要 API 密钥?", - "invalid": "无效的 API 密钥", - "invalidDetail": "请输入有效的 API 密钥", + "title": "API 密钥", "label": "API 密钥", + "description": "使用您的 Comfy API 密钥以启用 API 节点", "placeholder": "请输入您的 API 密钥", + "error": "无效的 API 密钥", "storageFailed": "API 密钥存储失败", "storageFailedDetail": "请重试。", "stored": "API 密钥已存储", "storedDetail": "您的 API 密钥已成功存储", - "title": "API 密钥", + "cleared": "API 密钥已清除", + "clearedDetail": "您的 API 密钥已成功清除", + "invalid": "无效的 API 密钥", + "invalidDetail": "请输入有效的 API 密钥", + "helpText": "需要 API 密钥?", + "generateKey": "在这里获取", "whitelistInfo": "关于非白名单网站" }, - "deleteAccount": { - "cancel": "取消", - "confirm": "删除账户", - "confirmMessage": "您确定要删除您的账户吗?此操作无法撤销,并且会永久删除您的所有数据。", - "confirmTitle": "删除账户", - "deleteAccount": "删除账户", - "success": "账户已删除", - "successDetail": "您的账户已成功删除。" - }, - "errors": { - "auth/cancelled-popup-request": "登录已取消。请重试。", - "auth/email-already-in-use": "已存在使用此电子邮件的账户。请尝试登录。", - "auth/invalid-credential": "登录凭据无效。请检查您的邮箱和密码。", - "auth/invalid-email": "请输入有效的电子邮件地址。", - "auth/network-request-failed": "网络错误。请检查您的连接并重试。", - "auth/operation-not-allowed": "此登录方法目前不受支持。", - "auth/popup-closed-by-user": "登录已取消。请重试。", - "auth/too-many-requests": "登录尝试次数过多。请稍等片刻再试。", - "auth/user-disabled": "此账户已被禁用。请联系客服。", - "auth/user-not-found": "未找到使用此电子邮件的账户。您想要创建一个新账户吗?", - "auth/weak-password": "密码强度太弱。请使用至少6个字符的更强密码。", - "auth/wrong-password": "您输入的密码不正确,请重试。" - }, "login": { - "andText": "和", - "backToLogin": "返回登录", - "confirmPasswordLabel": "确认密码", - "confirmPasswordPlaceholder": "再次输入相同的密码", - "didntReceiveEmail": "没有收到邮件?请联系我们:", - "emailLabel": "电子邮件", - "emailPlaceholder": "输入您的电子邮件", - "failed": "登录失败", - "forgotPassword": "忘记密码?", - "forgotPasswordError": "发送重置密码邮件失败", - "insecureContextWarning": "此连接不安全(HTTP)—如果继续登录,您的凭据可能会被攻击者拦截。", - "loginButton": "登录", - "loginWithGithub": "使用Github登录", - "loginWithGoogle": "使用Google登录", - "newUser": "新用户?", - "noAssociatedUser": "所提供的 API 密钥未关联任何 Comfy 用户", - "orContinueWith": "或者继续使用", - "passwordLabel": "密码", - "passwordPlaceholder": "输入您的密码", - "passwordResetError": "发送密码重置邮件失败。请重试。", - "passwordResetInstructions": "请输入您的电子邮件地址,我们将向您发送重置密码的链接。", - "passwordResetSent": "重置密码邮件已发送", - "passwordResetSentDetail": "请查收您的电子邮件,点击链接重置密码。", - "privacyLink": "隐私政策", - "questionsContactPrefix": "有疑问?请联系我们:", - "sendResetLink": "发送重置链接", - "signInOrSignUp": "登录 / 注册", - "signUp": "注册", - "success": "登录成功", - "termsLink": "使用条款", - "termsText": "点击“下一步”或“注册”即表示您同意我们的", "title": "登录您的账户", "useApiKey": "Comfy API 密钥", - "userAvatar": "用户头像" + "signInOrSignUp": "登录 / 注册", + "forgotPasswordError": "发送重置密码邮件失败", + "passwordResetSent": "重置密码邮件已发送", + "passwordResetSentDetail": "请查收您的电子邮件,点击链接重置密码。", + "newUser": "新用户?", + "userAvatar": "用户头像", + "signUp": "注册", + "emailLabel": "电子邮件", + "emailPlaceholder": "输入您的电子邮件", + "passwordLabel": "密码", + "passwordPlaceholder": "输入您的密码", + "confirmPasswordLabel": "确认密码", + "confirmPasswordPlaceholder": "再次输入相同的密码", + "forgotPassword": "忘记密码?", + "passwordResetInstructions": "请输入您的电子邮件地址,我们将向您发送重置密码的链接。", + "sendResetLink": "发送重置链接", + "backToLogin": "返回登录", + "didntReceiveEmail": "没有收到邮件?请联系我们:", + "passwordResetError": "发送密码重置邮件失败。请重试。", + "loginButton": "登录", + "orContinueWith": "或者继续使用", + "loginWithGoogle": "使用Google登录", + "loginWithGithub": "使用Github登录", + "termsText": "点击“下一步”或“注册”即表示您同意我们的", + "termsLink": "使用条款", + "andText": "和", + "privacyLink": "隐私政策", + "success": "登录成功", + "failed": "登录失败", + "insecureContextWarning": "此连接不安全(HTTP)—如果继续登录,您的凭据可能会被攻击者拦截。", + "questionsContactPrefix": "有疑问?请联系我们:", + "noAssociatedUser": "所提供的 API 密钥未关联任何 Comfy 用户" }, - "loginButton": { - "tooltipHelp": "登录以使用“API 节点”", - "tooltipLearnMore": "了解更多..." - }, - "passwordUpdate": { - "success": "密码已更新", - "successDetail": "您的密码已成功更新" - }, - "reauthRequired": { - "cancel": "取消", - "confirm": "重新登录", - "message": "出于安全原因,此操作需要您重新登录。是否继续?", - "title": "需要重新认证" + "signup": { + "title": "创建一个账户", + "alreadyHaveAccount": "已经有账户了?", + "emailLabel": "电子邮件", + "emailPlaceholder": "输入您的电子邮件", + "passwordLabel": "密码", + "passwordPlaceholder": "输入新密码", + "signUpButton": "注册", + "signIn": "登录", + "signUpWithGoogle": "使用Google注册", + "signUpWithGithub": "使用Github注册", + "regionRestrictionChina": "根据当地法规要求,我们暂时无法为中国地区的用户提供服务。", + "personalDataConsentLabel": "我同意处理我的个人数据。" }, "signOut": { "signOut": "退出登录", "success": "成功退出登录", "successDetail": "您已成功退出账户。" }, - "signup": { - "alreadyHaveAccount": "已经有账户了?", - "emailLabel": "电子邮件", - "emailPlaceholder": "输入您的电子邮件", - "passwordLabel": "密码", - "passwordPlaceholder": "输入新密码", - "personalDataConsentLabel": "我同意处理我的个人数据。", - "regionRestrictionChina": "根据当地法规要求,我们暂时无法为中国地区的用户提供服务。", - "signIn": "登录", - "signUpButton": "注册", - "signUpWithGithub": "使用Github注册", - "signUpWithGoogle": "使用Google注册", - "title": "创建一个账户" + "passwordUpdate": { + "success": "密码已更新", + "successDetail": "您的密码已成功更新" + }, + "errors": { + "auth/invalid-email": "请输入有效的电子邮件地址。", + "auth/user-disabled": "此账户已被禁用。请联系客服。", + "auth/user-not-found": "未找到使用此电子邮件的账户。您想要创建一个新账户吗?", + "auth/wrong-password": "您输入的密码不正确,请重试。", + "auth/email-already-in-use": "已存在使用此电子邮件的账户。请尝试登录。", + "auth/weak-password": "密码强度太弱。请使用至少6个字符的更强密码。", + "auth/too-many-requests": "登录尝试次数过多。请稍等片刻再试。", + "auth/operation-not-allowed": "此登录方法目前不受支持。", + "auth/invalid-credential": "登录凭据无效。请检查您的邮箱和密码。", + "auth/network-request-failed": "网络错误。请检查您的连接并重试。", + "auth/popup-closed-by-user": "登录已取消。请重试。", + "auth/cancelled-popup-request": "登录已取消。请重试。" + }, + "deleteAccount": { + "deleteAccount": "删除账户", + "confirmTitle": "删除账户", + "confirmMessage": "您确定要删除您的账户吗?此操作无法撤销,并且会永久删除您的所有数据。", + "confirm": "删除账户", + "cancel": "取消", + "success": "账户已删除", + "successDetail": "您的账户已成功删除。" + }, + "reauthRequired": { + "title": "需要重新认证", + "message": "出于安全原因,此操作需要您重新登录。是否继续?", + "confirm": "重新登录", + "cancel": "取消" + }, + "loginButton": { + "tooltipHelp": "登录以使用“API 节点”", + "tooltipLearnMore": "了解更多..." } }, "validation": { - "descriptionRequired": "描述是必填的", "invalidEmail": "无效的电子邮件地址", - "length": "必须为{length}个字符", - "maxLength": "不能超过{length}个字符", + "required": "必填", "minLength": "必须至少有{length}个字符", - "password": { - "lowercase": "必须包含至少一个小写字母", - "match": "密码必须匹配", - "minLength": "必须在8到32个字符之间", - "number": "必须包含至少一个数字", - "requirements": "密码要求", - "special": "必须包含至少一个特殊字符", - "uppercase": "必须包含至少一个大写字母" - }, - "personalDataConsentRequired": "您必须同意处理您的个人数据。", + "maxLength": "不能超过{length}个字符", "prefix": "必须以 {prefix} 开头", - "required": "必填" + "descriptionRequired": "描述是必填的", + "length": "必须为{length}个字符", + "password": { + "requirements": "密码要求", + "minLength": "必须在8到32个字符之间", + "uppercase": "必须包含至少一个大写字母", + "lowercase": "必须包含至少一个小写字母", + "number": "必须包含至少一个数字", + "special": "必须包含至少一个特殊字符", + "match": "密码必须匹配" + }, + "personalDataConsentRequired": "您必须同意处理您的个人数据。" }, "credits": { "activity": "活动", @@ -1878,24 +1882,24 @@ "messageSupport": "联系客服", "lastUpdated": "最近更新", "topUp": { + "insufficientTitle": "积分不足", + "insufficientMessage": "您的积分不足,无法运行此工作流。", + "quickPurchase": "快速购买", + "maxAmount": "(最高 $1,000 美元)", + "buyNow": "立即购买", + "seeDetails": "查看详情", + "topUp": "充值", "addMoreCredits": "获取更多积分", "addMoreCreditsToRun": "获取更多积分来运行", - "buy": "购买", - "buyNow": "立即购买", + "insufficientWorkflowMessage": "您的积分不足以运行该工作流。", "creditsDescription": "该工作流需要积分运行。", "howManyCredits": "您想要多少积分?", - "insufficientMessage": "您的积分不足,无法运行此工作流。", - "insufficientTitle": "积分不足", - "insufficientWorkflowMessage": "您的积分不足以运行该工作流。", - "maxAmount": "(最高 $1,000 美元)", + "videosEstimate": "~{count} 个视频*", + "templateNote": "*使用 Wan Fun Control 模板生成", + "buy": "购买", "purchaseError": "购买失败", "purchaseErrorDetail": "购买积分失败:{error}", - "quickPurchase": "快速购买", - "seeDetails": "查看详情", - "templateNote": "*使用 Wan Fun Control 模板生成", - "topUp": "充值", - "unknownError": "发生未知错误", - "videosEstimate": "~{count} 个视频*" + "unknownError": "发生未知错误" }, "creditsAvailable": "积分可用", "refreshes": "于 {date} 刷新", @@ -1968,9 +1972,9 @@ } }, "required": { - "subscribe": "订阅", "title": "订阅", - "waitingForSubscription": "请在新标签页中完成订阅。我们会自动检测到您已完成!" + "waitingForSubscription": "请在新标签页中完成订阅。我们会自动检测到您已完成!", + "subscribe": "订阅" }, "subscribeToRun": "订阅", "subscribeToRunFull": "订阅 Run", @@ -2001,10 +2005,10 @@ "upgradeTo": "升级到 {plan}", "changeTo": "更改为 {plan}", "maxDuration": { + "standard": "30 分钟", "creator": "30 分钟", - "founder": "30 分钟", "pro": "1 小时", - "standard": "30 分钟" + "founder": "30 分钟" } }, "userSettings": { @@ -2017,56 +2021,56 @@ "updatePassword": "更新密码" }, "selectionToolbox": { - "Bypass Group Nodes": "绕过分组节点", - "Set Group Nodes to Always": "将分组节点设置为始终", - "Set Group Nodes to Never": "将分组节点设置为从不", "executeButton": { - "disabledTooltip": "未选择输出节点", - "tooltip": "执行到选定的输出节点(用橙色边框高亮显示)" - } + "tooltip": "执行到选定的输出节点(用橙色边框高亮显示)", + "disabledTooltip": "未选择输出节点" + }, + "Set Group Nodes to Never": "将分组节点设置为从不", + "Bypass Group Nodes": "绕过分组节点", + "Set Group Nodes to Always": "将分组节点设置为始终" }, "widgets": { "selectModel": "选择模型", "uploadSelect": { "placeholder": "请选择...", - "placeholderAudio": "请选择音频...", "placeholderImage": "请选择图片...", + "placeholderAudio": "请选择音频...", + "placeholderVideo": "请选择视频...", "placeholderModel": "请选择模型...", - "placeholderUnknown": "请选择媒体...", - "placeholderVideo": "请选择视频..." + "placeholderUnknown": "请选择媒体..." }, "valueControl": { - "decrement": "递减值", - "decrementDesc": "数值-1或切换到上一个选项", - "editSettings": "改变控制设置", - "fixed": "固定值", - "fixedDesc": "数值不变", "header": { + "prefix": "自动更新该值", "after": "之后", "before": "之前", - "postfix": "正在运行工作流:", - "prefix": "自动更新该值" + "postfix": "正在运行工作流:" }, + "linkToGlobal": "连接到", + "linkToGlobalSeed": "全局值", + "linkToGlobalDesc": "唯一值连接到全局值控制设置", + "randomize": "随机值", + "randomizeDesc": "每次运行后随机化该值", "increment": "递增值", "incrementDesc": "数值+1或切换到下一个选项", - "linkToGlobal": "连接到", - "linkToGlobalDesc": "唯一值连接到全局值控制设置", - "linkToGlobalSeed": "全局值", - "randomize": "随机值", - "randomizeDesc": "每次运行后随机化该值" + "decrement": "递减值", + "decrementDesc": "数值-1或切换到上一个选项", + "fixed": "固定值", + "fixedDesc": "数值不变", + "editSettings": "改变控制设置" } }, "widgetFileUpload": { - "browseFiles": "浏览文件", - "dropPrompt": "将文件拖到此处或" + "dropPrompt": "将文件拖到此处或", + "browseFiles": "浏览文件" }, "nodeHelpPage": { - "documentationPage": "文档页面", "inputs": "输入", - "loadError": "加载帮助失败:{error}", - "moreHelp": "如需更多帮助,请访问", "outputs": "输出", - "type": "类型" + "type": "类型", + "moreHelp": "如需更多帮助,请访问", + "documentationPage": "文档页面", + "loadError": "加载帮助失败:{error}" }, "whatsNewPopup": { "learnMore": "了解更多", @@ -2082,29 +2086,111 @@ "missingNodesWarning": "工作流包含不支持的节点(红色突出显示)。" }, "shortcuts": { + "shortcuts": "快捷键", "essentials": "常用", - "keyboardShortcuts": "键盘快捷键", + "viewControls": "视图控制", "manageShortcuts": "管理快捷键", "noKeybinding": "无快捷键", - "shortcuts": "快捷键", + "keyboardShortcuts": "键盘快捷键", "subcategories": { + "workflow": "工作流", "node": "节点", - "panelControls": "面板控制", "queue": "队列", "view": "视图", - "workflow": "工作流" - }, - "viewControls": "视图控制" + "panelControls": "面板控制" + } }, "minimap": { "nodeColors": "节点颜色", - "renderBypassState": "渲染绕过状态", - "renderErrorState": "渲染错误状态", + "showLinks": "显示连接", "showGroups": "显示框架/分组", - "showLinks": "显示连接" + "renderBypassState": "渲染绕过状态", + "renderErrorState": "渲染错误状态" }, "cloudOnboarding": { + "survey": { + "title": "云调研", + "placeholder": "调查问题占位符", + "steps": { + "familiarity": "你对 ComfyUI 有多熟悉?", + "purpose": "您将主要使用 ComfyUI 做什么?", + "industry": "您的主要行业是什么?", + "making": "你打算做什么?" + }, + "questions": { + "familiarity": "你对 ComfyUI 有多熟悉?", + "purpose": "您主要将使用 ComfyUI 做什么?", + "industry": "您的主要行业是什么?", + "making": "你打算做什么?" + }, + "options": { + "familiarity": { + "new": "ComfyUI 新手(从未使用过)", + "starting": "刚刚开始(正在学习教程)", + "basics": "熟练掌握基础知识", + "advanced": "高级用户(自定义工作流)", + "expert": "专家(帮助他人)" + }, + "purpose": { + "personal": "个人项目 / 爱好", + "community": "社区贡献(节点、工作流等)", + "client": "客户工作(自由职业)", + "inhouse": "我自己的工作场所(内部)", + "research": "学术研究" + }, + "industry": { + "film_tv_animation": "电影、电视与动画", + "gaming": "游戏", + "marketing": "营销与广告", + "architecture": "架构", + "product_design": "产品与平面设计", + "fine_art": "美术与插画", + "software": "软件与技术", + "education": "教育", + "other": "其他", + "otherPlaceholder": "请指定" + }, + "making": { + "images": "图片", + "video": "视频与动画", + "3d": "3D 资产", + "audio": "音频 / 音乐", + "custom_nodes": "自定义节点和工作流" + } + } + }, + "forgotPassword": { + "title": "忘记密码", + "instructions": "请输入您的电子邮件地址,我们将向您发送重置密码的链接。", + "emailLabel": "电子邮件", + "emailPlaceholder": "输入您的邮箱", + "sendResetLink": "发送重置链接", + "backToLogin": "返回登录", + "didntReceiveEmail": "没有收到邮件?请联系我们:", + "passwordResetSent": "密码重置邮件已发送", + "passwordResetError": "发送密码重置邮件失败,请重试。", + "emailRequired": "邮箱为必填项" + }, + "privateBeta": { + "title": "云服务目前处于内测阶段", + "desc": "登录以加入等候名单。轮到您时我们会通知您。已经收到通知?登录开始使用 Cloud。" + }, + "start": { + "title": "几秒内开始创作", + "desc": "无需任何设置。可在任何设备上使用。", + "explain": "一次生成多个输出。轻松分享工作流。", + "learnAboutButton": "了解云服务", + "wantToRun": "想在本机运行 ComfyUI 吗?", + "download": "下载 ComfyUI" + }, + "checkingStatus": "正在检查您的账户状态...", + "retrying": "正在重试...", + "retry": "重试", "authTimeout": { + "title": "连接时间过长", + "message": "我们无法连接到 ComfyUI 云端服务。这可能是由于网络连接缓慢或临时服务问题导致的。", + "restart": "退出并重试", + "troubleshooting": "常见原因:", "causes": [ "Corporate firewall or proxy blocking authentication services", "VPN or network restrictions", @@ -2112,91 +2198,9 @@ "Regional network limitations", "Try a different browser or network" ], - "helpText": "需要帮助?联系", - "message": "我们无法连接到 ComfyUI 云端服务。这可能是由于网络连接缓慢或临时服务问题导致的。", - "restart": "退出并重试", - "supportLink": "支持", "technicalDetails": "技术细节", - "title": "连接时间过长", - "troubleshooting": "常见原因:" - }, - "checkingStatus": "正在检查您的账户状态...", - "forgotPassword": { - "backToLogin": "返回登录", - "didntReceiveEmail": "没有收到邮件?请联系我们:", - "emailLabel": "电子邮件", - "emailPlaceholder": "输入您的邮箱", - "emailRequired": "邮箱为必填项", - "instructions": "请输入您的电子邮件地址,我们将向您发送重置密码的链接。", - "passwordResetError": "发送密码重置邮件失败,请重试。", - "passwordResetSent": "密码重置邮件已发送", - "sendResetLink": "发送重置链接", - "title": "忘记密码" - }, - "privateBeta": { - "desc": "登录以加入等候名单。轮到您时我们会通知您。已经收到通知?登录开始使用 Cloud。", - "title": "云服务目前处于内测阶段" - }, - "retry": "重试", - "retrying": "正在重试...", - "start": { - "desc": "无需任何设置。可在任何设备上使用。", - "download": "下载 ComfyUI", - "explain": "一次生成多个输出。轻松分享工作流。", - "learnAboutButton": "了解云服务", - "title": "几秒内开始创作", - "wantToRun": "想在本机运行 ComfyUI 吗?" - }, - "survey": { - "options": { - "familiarity": { - "advanced": "高级用户(自定义工作流)", - "basics": "熟练掌握基础知识", - "expert": "专家(帮助他人)", - "new": "ComfyUI 新手(从未使用过)", - "starting": "刚刚开始(正在学习教程)" - }, - "industry": { - "architecture": "架构", - "education": "教育", - "film_tv_animation": "电影、电视与动画", - "fine_art": "美术与插画", - "gaming": "游戏", - "marketing": "营销与广告", - "other": "其他", - "otherPlaceholder": "请指定", - "product_design": "产品与平面设计", - "software": "软件与技术" - }, - "making": { - "3d": "3D 资产", - "audio": "音频 / 音乐", - "custom_nodes": "自定义节点和工作流", - "images": "图片", - "video": "视频与动画" - }, - "purpose": { - "client": "客户工作(自由职业)", - "community": "社区贡献(节点、工作流等)", - "inhouse": "我自己的工作场所(内部)", - "personal": "个人项目 / 爱好", - "research": "学术研究" - } - }, - "placeholder": "调查问题占位符", - "questions": { - "familiarity": "你对 ComfyUI 有多熟悉?", - "industry": "您的主要行业是什么?", - "making": "你打算做什么?", - "purpose": "您主要将使用 ComfyUI 做什么?" - }, - "steps": { - "familiarity": "你对 ComfyUI 有多熟悉?", - "industry": "您的主要行业是什么?", - "making": "你打算做什么?", - "purpose": "您将主要使用 ComfyUI 做什么?" - }, - "title": "云调研" + "helpText": "需要帮助?联系", + "supportLink": "支持" } }, "cloudFooter_needHelp": "需要帮助?", @@ -2316,15 +2320,15 @@ "loadingAsset": "正在加载资产" }, "media": { - "audioPlaceholder": "音频", - "threeDModelPlaceholder": "3D 模型" + "threeDModelPlaceholder": "3D 模型", + "audioPlaceholder": "音频" }, "deletion": { - "body": "从资产库永久移除这个模型。", - "complete": "{assetName} 已经删除。", - "failed": "{assetName} 无法删除。", "header": "删除该模型?", - "inProgress": "正在删除 {assetName}..." + "body": "从资产库永久移除这个模型。", + "inProgress": "正在删除 {assetName}...", + "complete": "{assetName} 已经删除。", + "failed": "{assetName} 无法删除。" }, "rename": { "failed": "无法重命名资产。" @@ -2339,32 +2343,32 @@ "deletingImportedFilesCloudOnly": "删除导入文件仅支持云版本", "failedToDeleteAsset": "删除资产失败", "actions": { - "addToWorkflow": "添加到当前工作流", - "copyJobId": "复制任务ID", - "delete": "删除", - "download": "下载", - "exportWorkflow": "导出工作流", "inspect": "查看资产", "more": "更多设置", + "seeMoreOutputs": "查看更多输出", + "addToWorkflow": "添加到当前工作流", + "download": "下载", "openWorkflow": "在新标签页中读取工作流", - "seeMoreOutputs": "查看更多输出" + "exportWorkflow": "导出工作流", + "copyJobId": "复制任务ID", + "delete": "删除" }, "jobIdToast": { - "copied": "已复制", - "error": "错误", "jobIdCopied": "任务 ID 已复制到剪贴板", - "jobIdCopyFailed": "复制队列 ID 失败" + "jobIdCopyFailed": "复制队列 ID 失败", + "copied": "已复制", + "error": "错误" }, "selection": { - "assetsDeletedSuccessfully": "已成功删除 {count} 个资产", - "deleteSelected": "删除", + "selectedCount": "已选择资产:{count}", "deselectAll": "取消全选", "downloadSelected": "下载", + "deleteSelected": "删除", "downloadStarted": "正在下载 {count} 个文件...", "downloadsStarted": "开始下载 {count} 个文件", + "assetsDeletedSuccessfully": "已成功删除 {count} 个资产", "failedToDeleteAssets": "未能删除所选资产", - "partialDeleteSuccess": "{succeeded} 删除成功, {failed} 失败", - "selectedCount": "已选择资产:{count}" + "partialDeleteSuccess": "{succeeded} 删除成功, {failed} 失败" }, "noJobIdFound": "该资产不包含任务ID", "unsupportedFileType": "加载节点不支持该类型文件", @@ -2383,64 +2387,64 @@ }, "desktopDialogs": { "": { + "title": "无效对话框", + "message": "提供的对话 ID 无效。", "buttons": { "Close": "关闭" - }, - "message": "提供的对话 ID 无效。", - "title": "无效对话框" + } } }, "vueNodesBanner": { - "message": "- 更灵活的工作流,强大的新组件,为可扩展性而构建", "title": "介绍 Nodes 2.0", + "desc": "– 更灵活的工作流,强力的新组件,为拓展性而生", "tryItOut": "试试看" }, "vueNodesMigration": { - "button": "打开设置", - "message": "是否偏好经典节点设计?" + "message": "是否偏好经典节点设计?", + "button": "打开设置" }, "vueNodesMigrationMainMenu": { "message": "在主菜单中随时切换回 Nodes 2.0" }, "linearMode": { - "openWorkflow": "打开工作流", - "share": "分享" + "share": "分享", + "openWorkflow": "打开工作流" }, "missingNodes": { "cloud": { + "title": "Comfy Cloud 目前不支持这些节点", "description": "该工作流包含 Comfy Cloud 目前不支持的节点", - "gotIt": "好的", - "learnMore": "查看更多", "priorityMessage": "我们已经标记这些节点,将会优先支持它们。", "replacementInstruction": "同时,如果可能的话,将这些节点(红色突出显示)替换为已经支持的节点,或者尝试不同的工作流。", - "title": "Comfy Cloud 目前不支持这些节点" + "learnMore": "查看更多", + "gotIt": "好的" }, "oss": { + "title": "该工作流含有缺失节点", "description": "该工作流包含您未安装的自定义节点", - "replacementInstruction": "安装这些节点后运行此工作流,或者用已安装的节点替换它们。缺失的节点在画布上以红色突出显示。", - "title": "该工作流含有缺失节点" + "replacementInstruction": "安装这些节点后运行此工作流,或者用已安装的节点替换它们。缺失的节点在画布上以红色突出显示。" } }, "rightSidePanel": { - "bypass": "忽略", - "color": "节点颜色", + "togglePanel": "开关属性面板", + "noSelection": "选择一个节点查看其属性信息。", + "title": "无选中节点 | 选中了 1 个节点 | 选中了 {count} 个节点", + "parameters": "参数", "info": "信息", + "color": "节点颜色", + "pinned": "顶固", + "bypass": "忽略", + "normal": "正常", + "mute": "禁用", "inputs": "输入", "inputsNone": "无输入", "inputsNoneTooltip": "节点没有输入", - "mute": "禁用", - "noSelection": "选择一个节点查看其属性信息。", - "nodeState": "节点状态", - "normal": "正常", - "parameters": "参数", - "pinned": "顶固", "properties": "属性", - "settings": "设置", - "title": "无选中节点 | 选中了 1 个节点 | 选中了 {count} 个节点", - "togglePanel": "开关属性面板" + "nodeState": "节点状态", + "settings": "设置" }, "help": { - "helpCenterMenu": "帮助中心菜单", - "recentReleases": "最近发布" + "recentReleases": "最近发布", + "helpCenterMenu": "帮助中心菜单" } } \ No newline at end of file diff --git a/src/locales/zh/nodeDefs.json b/src/locales/zh/nodeDefs.json index 5b27ef9d7..3cc201f77 100644 --- a/src/locales/zh/nodeDefs.json +++ b/src/locales/zh/nodeDefs.json @@ -1,35 +1,7 @@ { - "APG": { - "display_name": "自适应投影引导", - "inputs": { - "eta": { - "name": "预计到达时间", - "tooltip": "控制平行引导向量的缩放比例。默认 CFG 行为设置为 1。" - }, - "model": { - "name": "模型" - }, - "momentum": { - "name": "动量", - "tooltip": "控制扩散过程中的引导运行平均值,设置为0时禁用。" - }, - "norm_threshold": { - "name": "向量归一化", - "tooltip": "将引导向量归一化到此值,设置为 0 时禁用归一化。" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, "AddNoise": { "display_name": "添加噪波", "inputs": { - "latent_image": { - "name": "Latent" - }, "model": { "name": "模型" }, @@ -38,20 +10,129 @@ }, "sigmas": { "name": "Sigmas" + }, + "latent_image": { + "name": "Latent" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "AddTextPrefix": { + "display_name": "文本前添加", + "inputs": { + "texts": { + "name": "文本", + "tooltip": "需要被添加的文本。" + }, + "prefix": { + "name": "前缀", + "tooltip": "要添加的内容。" + } + }, + "outputs": { + "0": { + "name": "文本", + "tooltip": "处理后的文本" + } + } + }, + "AddTextSuffix": { + "display_name": "文本后添加", + "inputs": { + "texts": { + "name": "文本", + "tooltip": "需要被添加的文本。" + }, + "suffix": { + "name": "后缀", + "tooltip": "要添加的内容。" + } + }, + "outputs": { + "0": { + "name": "文本", + "tooltip": "处理后的文本" + } + } + }, + "AdjustBrightness": { + "display_name": "调整亮度", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要调整的图像" + }, + "factor": { + "name": "系数", + "tooltip": "亮度系数。1.0表示无变化,<1.0表示更暗,>1.0表示更亮。" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "调整后的图像" + } + } + }, + "AdjustContrast": { + "display_name": "调整对比度", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要调整的图像" + }, + "factor": { + "name": "系数", + "tooltip": "对比度系数。1.0表示无变化,<1.0表示更低,>1.0表示更高。" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "调整后的图像" } } }, "AlignYourStepsScheduler": { "display_name": "AlignYourSteps调度器", "inputs": { - "denoise": { - "name": "降噪" - }, "model_type": { "name": "模型类型" }, "steps": { "name": "步数" + }, + "denoise": { + "name": "降噪" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "APG": { + "display_name": "自适应投影引导", + "inputs": { + "model": { + "name": "模型" + }, + "eta": { + "name": "预计到达时间", + "tooltip": "控制平行引导向量的缩放比例。默认 CFG 行为设置为 1。" + }, + "norm_threshold": { + "name": "向量归一化", + "tooltip": "将引导向量归一化到此值,设置为 0 时禁用归一化。" + }, + "momentum": { + "name": "动量", + "tooltip": "控制扩散过程中的引导运行平均值,设置为0时禁用。" } }, "outputs": { @@ -70,6 +151,11 @@ "name": "音量", "tooltip": "音量调整,单位为分贝 (dB)。0 = 无变化,+6 = 加倍,-6 = 减半,等等" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "AudioConcat": { @@ -86,16 +172,21 @@ "name": "方向", "tooltip": "音频2 在 音频1 之前或之后。" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "AudioEncoderEncode": { "display_name": "音频编码器编码", "inputs": { - "audio": { - "name": "音频" - }, "audio_encoder": { "name": "音频编码器" + }, + "audio": { + "name": "音频" } }, "outputs": { @@ -109,9 +200,6 @@ "inputs": { "audio_encoder_name": { "name": "音频编码器" - }, - "audio": { - "name": "音频" } }, "outputs": { @@ -134,25 +222,32 @@ "name": "合并方法", "tooltip": "用于组合音频波形的方法。" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "BasicGuider": { "display_name": "基本引导器", "inputs": { - "conditioning": { - "name": "条件" - }, "model": { "name": "模型" + }, + "conditioning": { + "name": "条件" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "BasicScheduler": { "display_name": "基本调度器", "inputs": { - "denoise": { - "name": "降噪" - }, "model": { "name": "模型" }, @@ -161,44 +256,49 @@ }, "steps": { "name": "步数" + }, + "denoise": { + "name": "降噪" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "BetaSamplingScheduler": { "display_name": "Beta采样调度器", "inputs": { - "alpha": { - "name": "alpha" - }, - "beta": { - "name": "beta" - }, "model": { "name": "模型" }, "steps": { "name": "步数" + }, + "alpha": { + "name": "alpha" + }, + "beta": { + "name": "beta" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "ByteDanceFirstLastFrameNode": { - "description": "使用提示词和首尾帧生成视频。", "display_name": "字节跳动首尾帧转视频", + "description": "使用提示词和首尾帧生成视频。", "inputs": { - "aspect_ratio": { - "name": "宽高比", - "tooltip": "输出视频的宽高比。" + "model": { + "name": "模型" }, - "camera_fixed": { - "name": "相机固定", - "tooltip": "指定是否固定相机。平台会在您的提示词中附加固定相机的指令,但不保证实际效果。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "输出视频的时长(以秒为单位)。" + "prompt": { + "name": "提示", + "tooltip": "用于生成视频的文本提示。" }, "first_frame": { "name": "第一帧", @@ -208,24 +308,32 @@ "name": "最后一帧", "tooltip": "用于视频的最后一帧。" }, - "model": { - "name": "模型" - }, - "prompt": { - "name": "提示", - "tooltip": "用于生成视频的文本提示。" - }, "resolution": { "name": "分辨率", "tooltip": "输出视频的分辨率。" }, + "aspect_ratio": { + "name": "宽高比", + "tooltip": "输出视频的宽高比。" + }, + "duration": { + "name": "时长", + "tooltip": "输出视频的时长(以秒为单位)。" + }, "seed": { "name": "种子", "tooltip": "用于生成的种子。" }, + "camera_fixed": { + "name": "相机固定", + "tooltip": "指定是否固定相机。平台会在您的提示词中附加固定相机的指令,但不保证实际效果。" + }, "watermark": { "name": "水印", "tooltip": "是否在视频中添加“AI 生成”水印。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -235,23 +343,16 @@ } }, "ByteDanceImageEditNode": { - "description": "通过基于提示的API使用字节跳动模型编辑图像", "display_name": "字节跳动图片编辑", + "description": "通过基于提示的API使用字节跳动模型编辑图像", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "guidance_scale": { - "name": "引导尺度", - "tooltip": "数值越高,图像越紧密地遵循提示" + "model": { + "name": "模型" }, "image": { "name": "图片", "tooltip": "要编辑的基础图像" }, - "model": { - "name": "模型" - }, "prompt": { "name": "提示", "tooltip": "编辑图像的指令" @@ -260,9 +361,16 @@ "name": "种子", "tooltip": "用于生成的种子" }, + "guidance_scale": { + "name": "引导尺度", + "tooltip": "数值越高,图像越紧密地遵循提示" + }, "watermark": { "name": "水印", "tooltip": "是否在图像上添加“AI生成”水印" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -272,20 +380,9 @@ } }, "ByteDanceImageNode": { - "description": "通过基于提示的API使用字节跳动模型生成图像", "display_name": "字节跳动图片", + "description": "通过基于提示的API使用字节跳动模型生成图像", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "guidance_scale": { - "name": "引导尺度", - "tooltip": "数值越高,图像越紧密地遵循提示" - }, - "height": { - "name": "高度", - "tooltip": "图像的自定义高度。仅当 `size_preset` 设置为 `Custom` 时该值才生效" - }, "model": { "name": "模型" }, @@ -293,21 +390,32 @@ "name": "提示", "tooltip": "用于生成图像的文本提示" }, + "size_preset": { + "name": "尺寸预设", + "tooltip": "选择一个推荐尺寸。选择自定义以使用下方的宽度和高度" + }, + "width": { + "name": "宽度", + "tooltip": "图像的自定义宽度。仅当 `size_preset` 设置为 `Custom` 时该值才生效" + }, + "height": { + "name": "高度", + "tooltip": "图像的自定义高度。仅当 `size_preset` 设置为 `Custom` 时该值才生效" + }, "seed": { "name": "种子", "tooltip": "用于生成的种子" }, - "size_preset": { - "name": "尺寸预设", - "tooltip": "选择一个推荐尺寸。选择自定义以使用下方的宽度和高度" + "guidance_scale": { + "name": "引导尺度", + "tooltip": "数值越高,图像越紧密地遵循提示" }, "watermark": { "name": "水印", "tooltip": "是否在图像上添加“AI生成”水印" }, - "width": { - "name": "宽度", - "tooltip": "图像的自定义宽度。仅当 `size_preset` 设置为 `Custom` 时该值才生效" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -317,24 +425,9 @@ } }, "ByteDanceImageReferenceNode": { - "description": "使用提示和参考图像生成视频。", "display_name": "字节跳动参考图像转视频", + "description": "使用提示和参考图像生成视频。", "inputs": { - "aspect_ratio": { - "name": "宽高比", - "tooltip": "输出视频的宽高比。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "输出视频的时长(以秒为单位)。" - }, - "images": { - "name": "图片", - "tooltip": "一到四张图片。" - }, "model": { "name": "模型" }, @@ -342,10 +435,22 @@ "name": "提示", "tooltip": "用于生成视频的文本提示。" }, + "images": { + "name": "图片", + "tooltip": "一到四张图片。" + }, "resolution": { "name": "分辨率", "tooltip": "输出视频的分辨率。" }, + "aspect_ratio": { + "name": "宽高比", + "tooltip": "输出视频的宽高比。" + }, + "duration": { + "name": "时长", + "tooltip": "输出视频的时长(以秒为单位)。" + }, "seed": { "name": "种子", "tooltip": "用于生成的种子。" @@ -353,6 +458,9 @@ "watermark": { "name": "水印", "tooltip": "是否在视频中添加“AI 生成”水印。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -362,28 +470,9 @@ } }, "ByteDanceImageToVideoNode": { - "description": "通过API基于图像和提示使用字节跳动模型生成视频", "display_name": "字节跳动图片转视频", + "description": "通过API基于图像和提示使用字节跳动模型生成视频", "inputs": { - "aspect_ratio": { - "name": "宽高比", - "tooltip": "输出视频的宽高比。" - }, - "camera_fixed": { - "name": "摄像头已固定", - "tooltip": "指定是否固定相机。平台会在您的提示词中附加固定相机的指令,但不保证实际效果。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "输出视频的时长(以秒为单位)。" - }, - "image": { - "name": "图片", - "tooltip": "用于视频的第一帧。" - }, "model": { "name": "模型" }, @@ -391,17 +480,36 @@ "name": "提示", "tooltip": "用于生成视频的文本提示。" }, + "image": { + "name": "图片", + "tooltip": "用于视频的第一帧。" + }, "resolution": { "name": "分辨率", "tooltip": "输出视频的分辨率。" }, + "aspect_ratio": { + "name": "宽高比", + "tooltip": "输出视频的宽高比。" + }, + "duration": { + "name": "时长", + "tooltip": "输出视频的时长(以秒为单位)。" + }, "seed": { "name": "种子", "tooltip": "用于生成的种子。" }, + "camera_fixed": { + "name": "摄像头已固定", + "tooltip": "指定是否固定相机。平台会在您的提示词中附加固定相机的指令,但不保证实际效果。" + }, "watermark": { "name": "水印", "tooltip": "是否在视频中添加“AI生成”水印。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -411,28 +519,9 @@ } }, "ByteDanceSeedreamNode": { - "description": "统一文本到图像生成,支持高达4K分辨率的精确单句编辑。", "display_name": "字节跳动Seedream 4", + "description": "统一文本到图像生成,支持高达4K分辨率的精确单句编辑。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "fail_on_partial": { - "name": "部分失败时停止", - "tooltip": "如果启用,当任何请求的图像缺失或返回错误时,将中止执行。" - }, - "height": { - "name": "高度", - "tooltip": "图像的自定义高度。仅当 `size_preset` 设置为 `Custom` 时该值生效" - }, - "image": { - "name": "图像", - "tooltip": "用于图像到图像生成的输入图像。用于单参考或多参考生成的1-10张图像列表。" - }, - "max_images": { - "name": "最大图片数", - "tooltip": "当 sequential_image_generation='auto' 时生成图像的最大数量。总图像数(输入+生成)不能超过 15。" - }, "model": { "name": "模型", "tooltip": "模型名称" @@ -441,25 +530,44 @@ "name": "提示", "tooltip": "用于创建或编辑图像的文本提示。" }, - "seed": { - "name": "种子", - "tooltip": "用于生成的种子。" + "size_preset": { + "name": "尺寸预设", + "tooltip": "选择一个推荐尺寸。选择“自定义”以使用下面的宽度和高度。" + }, + "image": { + "name": "图像", + "tooltip": "用于图像到图像生成的输入图像。用于单参考或多参考生成的1-10张图像列表。" + }, + "width": { + "name": "宽度", + "tooltip": "图像的自定义宽度。仅当 `size_preset` 设置为 `Custom` 时该值生效" + }, + "height": { + "name": "高度", + "tooltip": "图像的自定义高度。仅当 `size_preset` 设置为 `Custom` 时该值生效" }, "sequential_image_generation": { "name": "顺序图像生成", "tooltip": "分组图像生成模式。'disabled' 生成单张图像。'auto' 由模型决定是否生成多张相关图像(例如故事场景、角色变体)。" }, - "size_preset": { - "name": "尺寸预设", - "tooltip": "选择一个推荐尺寸。选择“自定义”以使用下面的宽度和高度。" + "max_images": { + "name": "最大图片数", + "tooltip": "当 sequential_image_generation='auto' 时生成图像的最大数量。总图像数(输入+生成)不能超过 15。" + }, + "seed": { + "name": "种子", + "tooltip": "用于生成的种子。" }, "watermark": { "name": "水印", "tooltip": "是否在图像上添加“AI 生成”水印。" }, - "width": { - "name": "宽度", - "tooltip": "图像的自定义宽度。仅当 `size_preset` 设置为 `Custom` 时该值生效" + "fail_on_partial": { + "name": "部分失败时停止", + "tooltip": "如果启用,当任何请求的图像缺失或返回错误时,将中止执行。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -469,24 +577,9 @@ } }, "ByteDanceTextToVideoNode": { - "description": "通过API基于提示使用字节跳动模型生成视频", "display_name": "字节跳动文生视频", + "description": "通过API基于提示使用字节跳动模型生成视频", "inputs": { - "aspect_ratio": { - "name": "宽高比", - "tooltip": "输出视频的宽高比。" - }, - "camera_fixed": { - "name": "固定相机", - "tooltip": "指定是否固定相机。平台会在您的提示后附加固定相机的指令,但不保证实际效果。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "输出视频的时长(秒)。" - }, "model": { "name": "模型" }, @@ -498,13 +591,28 @@ "name": "分辨率", "tooltip": "输出视频的分辨率。" }, + "aspect_ratio": { + "name": "宽高比", + "tooltip": "输出视频的宽高比。" + }, + "duration": { + "name": "时长", + "tooltip": "输出视频的时长(秒)。" + }, "seed": { "name": "种子", "tooltip": "用于生成的种子值。" }, + "camera_fixed": { + "name": "固定相机", + "tooltip": "指定是否固定相机。平台会在您的提示后附加固定相机的指令,但不保证实际效果。" + }, "watermark": { "name": "水印", "tooltip": "是否在视频中添加“AI生成”水印。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -513,20 +621,83 @@ } } }, + "Canny": { + "display_name": "Canny边缘检测", + "inputs": { + "image": { + "name": "图像" + }, + "low_threshold": { + "name": "低阈值" + }, + "high_threshold": { + "name": "高阈值" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "CaseConverter": { + "display_name": "大小写转换器", + "inputs": { + "string": { + "name": "字符串" + }, + "mode": { + "name": "模式" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "CenterCropImages": { + "display_name": "裁剪图像(中心)", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要调整的图像" + }, + "width": { + "name": "宽度", + "tooltip": "裁剪框宽度" + }, + "height": { + "name": "高度", + "tooltip": "裁剪框高度" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "调整后的图像" + } + } + }, "CFGGuider": { "display_name": "CFG引导器", "inputs": { - "cfg": { - "name": "CFG" - }, "model": { "name": "模型" }, + "positive": { + "name": "正面条件" + }, "negative": { "name": "负面条件" }, - "positive": { - "name": "正面条件" + "cfg": { + "name": "CFG" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, @@ -561,23 +732,102 @@ } } }, + "CheckpointLoader": { + "display_name": "Ckeckpoint加载器(已弃用)", + "inputs": { + "config_name": { + "name": "配置名称" + }, + "ckpt_name": { + "name": "Checkpoint名称" + } + } + }, + "CheckpointLoaderSimple": { + "display_name": "Checkpoint加载器(简易)", + "description": "加载扩散模型 Checkpoint,用于去除 Latent 噪波。", + "inputs": { + "ckpt_name": { + "name": "Checkpoint名称", + "tooltip": "要加载的Checkpoint模型的名称。" + } + }, + "outputs": { + "0": { + "tooltip": "用于去除 Latent 噪波的模型。" + }, + "1": { + "tooltip": "用于编码文本提示的 CLIP 模型。" + }, + "2": { + "tooltip": "用于将图像编码和解码到 Latent 的 VAE 模型。" + } + } + }, + "CheckpointSave": { + "display_name": "保存Checkpoint", + "inputs": { + "model": { + "name": "模型" + }, + "clip": { + "name": "clip" + }, + "vae": { + "name": "vae" + }, + "filename_prefix": { + "name": "文件名前缀" + } + } + }, + "ChromaRadianceOptions": { + "display_name": "ChromaRadiance选项", + "description": "允许为Chroma Radiance模型设置高级选项。", + "inputs": { + "model": { + "name": "模型" + }, + "preserve_wrapper": { + "name": "保留包装器", + "tooltip": "启用时,如果存在现有模型函数包装器,将委托给该包装器。通常应保持启用状态。" + }, + "start_sigma": { + "name": "起始sigma", + "tooltip": "这些选项生效的第一个sigma值。" + }, + "end_sigma": { + "name": "结束sigma", + "tooltip": "这些选项生效的最后一个sigma值。" + }, + "nerf_tile_size": { + "name": "NeRF瓦片大小", + "tooltip": "允许覆盖默认的NeRF瓦片大小。-1表示使用默认值(32)。0表示使用非平铺模式(可能需要大量显存)。" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, "CLIPAttentionMultiply": { "display_name": "CLIP注意力相乘", "inputs": { "clip": { "name": "CLIP" }, - "k": { - "name": "k" - }, - "out": { - "name": "输出" - }, "q": { "name": "q" }, + "k": { + "name": "k" + }, "v": { "name": "v" + }, + "out": { + "name": "输出" } }, "outputs": { @@ -593,11 +843,11 @@ "clip_name": { "name": "CLIP名称" }, - "device": { - "name": "设备" - }, "type": { "name": "类型" + }, + "device": { + "name": "设备" } } }, @@ -663,16 +913,16 @@ } }, "CLIPTextEncode": { - "description": "使用 CLIP 模型将文本编码成嵌入组(embedding),用于引导扩散模型生成图像。", "display_name": "CLIP文本编码", + "description": "使用 CLIP 模型将文本编码成嵌入组(embedding),用于引导扩散模型生成图像。", "inputs": { - "clip": { - "name": "clip", - "tooltip": "用于编码文本的 CLIP 模型。" - }, "text": { "name": "文本", "tooltip": "要编码的文本。" + }, + "clip": { + "name": "clip", + "tooltip": "用于编码文本的 CLIP 模型。" } }, "outputs": { @@ -682,7 +932,7 @@ } }, "CLIPTextEncodeControlnet": { - "display_name": "CLIP文本编码ControlNet", + "display_name": "CLIP文本编码(ControlNet)", "inputs": { "clip": { "name": "clip" @@ -701,7 +951,7 @@ } }, "CLIPTextEncodeFlux": { - "display_name": "CLIP文本编码Flux", + "display_name": "CLIP文本编码(Flux)", "inputs": { "clip": { "name": "clip" @@ -709,11 +959,11 @@ "clip_l": { "name": "clip_l" }, - "guidance": { - "name": "引导" - }, "t5xxl": { "name": "t5xxl" + }, + "guidance": { + "name": "引导" } }, "outputs": { @@ -723,22 +973,22 @@ } }, "CLIPTextEncodeHiDream": { - "display_name": "CLIP文本编码HiDream", + "display_name": "CLIP文本编码(HiDream)", "inputs": { "clip": { "name": "clip" }, - "clip_g": { - "name": "clip_g" - }, "clip_l": { "name": "clip_l" }, - "llama": { - "name": "llama" + "clip_g": { + "name": "clip_g" }, "t5xxl": { "name": "t5xxl" + }, + "llama": { + "name": "llama" } }, "outputs": { @@ -748,14 +998,14 @@ } }, "CLIPTextEncodeHunyuanDiT": { - "display_name": "CLIP文本编码混元DiT", + "display_name": "CLIP文本编码(混元DiT)", "inputs": { - "bert": { - "name": "bert" - }, "clip": { "name": "clip" }, + "bert": { + "name": "bert" + }, "mt5xl": { "name": "mt5xl" } @@ -766,14 +1016,29 @@ } } }, - "CLIPTextEncodeLumina2": { - "display_name": "CLIP文本编码Lumina2", - "description": "使用CLIP模型将系统提示和用户提示编码成可以用来引导扩散模型生成特定图像的嵌入。", + "CLIPTextEncodeKandinsky5": { + "display_name": "CLIP文本编码(Kandinsky5)", "inputs": { "clip": { - "name": "clip", - "tooltip": "用于编码文本的CLIP模型。" + "name": "clip" }, + "clip_l": { + "name": "clip_l" + }, + "qwen25_7b": { + "name": "qwen25_7b" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "CLIPTextEncodeLumina2": { + "display_name": "CLIP文本编码(Lumina2)", + "description": "使用CLIP模型将系统提示和用户提示编码成可以用来引导扩散模型生成特定图像的嵌入。", + "inputs": { "system_prompt": { "name": "系统提示词", "tooltip": "Lumina2提供两种类型的系统提示:优越:你是一个设计来根据文本提示或用户提示生成优越图像的助手,这些图像具有基于文本提示的优越度的图像-文本对齐。对齐:你是一个设计来根据文本提示生成高质量图像的助手,这些图像具有基于文本提示的最高度的图像-文本对齐。" @@ -781,6 +1046,10 @@ "user_prompt": { "name": "提示词", "tooltip": "需要编码的文本。" + }, + "clip": { + "name": "clip", + "tooltip": "用于编码文本的CLIP模型。" } }, "outputs": { @@ -790,11 +1059,11 @@ } }, "CLIPTextEncodePixArtAlpha": { - "display_name": "CLIP文本编码PixArtAlpha", + "display_name": "CLIP文本编码(PixArtAlpha)", "description": "编码文本并设置PixArt Alpha的分辨率条件。不适用于PixArt Sigma。", "inputs": { - "clip": { - "name": "剪辑" + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -802,8 +1071,8 @@ "text": { "name": "文本" }, - "width": { - "name": "宽度" + "clip": { + "name": "剪辑" } }, "outputs": { @@ -813,22 +1082,22 @@ } }, "CLIPTextEncodeSD3": { - "display_name": "CLIP文本编码SD3", + "display_name": "CLIP文本编码(SD3)", "inputs": { "clip": { "name": "clip" }, - "clip_g": { - "name": "clip_g" - }, "clip_l": { "name": "clip_l" }, - "empty_padding": { - "name": "空白填充" + "clip_g": { + "name": "clip_g" }, "t5xxl": { "name": "t5xxl" + }, + "empty_padding": { + "name": "空白填充" } }, "outputs": { @@ -838,34 +1107,34 @@ } }, "CLIPTextEncodeSDXL": { - "display_name": "CLIP文本编码SDXL", + "display_name": "CLIP文本编码(SDXL)", "inputs": { "clip": { "name": "clip" }, - "crop_h": { - "name": "裁剪高" - }, - "crop_w": { - "name": "裁剪宽" + "width": { + "name": "宽度" }, "height": { "name": "高度" }, - "target_height": { - "name": "目标高度" + "crop_w": { + "name": "裁剪宽" + }, + "crop_h": { + "name": "裁剪高" }, "target_width": { "name": "目标宽度" }, + "target_height": { + "name": "目标高度" + }, "text_g": { "name": "文本_g" }, "text_l": { "name": "文本_l" - }, - "width": { - "name": "宽度" } }, "outputs": { @@ -875,13 +1144,13 @@ } }, "CLIPTextEncodeSDXLRefiner": { - "display_name": "CLIP文本编码SDXL精炼器", + "display_name": "CLIP文本编码(SDXLRefiner)", "inputs": { "ascore": { "name": "美学分数" }, - "clip": { - "name": "clip" + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -889,8 +1158,8 @@ "text": { "name": "文本" }, - "width": { - "name": "宽度" + "clip": { + "name": "clip" } }, "outputs": { @@ -905,11 +1174,11 @@ "clip_vision": { "name": "clip视觉" }, - "crop": { - "name": "裁剪" - }, "image": { "name": "图像" + }, + "crop": { + "name": "裁剪" } } }, @@ -921,120 +1190,6 @@ } } }, - "Canny": { - "display_name": "Canny边缘检测", - "inputs": { - "high_threshold": { - "name": "高阈值" - }, - "image": { - "name": "图像" - }, - "low_threshold": { - "name": "低阈值" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, - "CaseConverter": { - "display_name": "大小写转换器", - "inputs": { - "mode": { - "name": "模式" - }, - "string": { - "name": "字符串" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, - "CheckpointLoader": { - "display_name": "Ckeckpoint加载器(已弃用)", - "inputs": { - "ckpt_name": { - "name": "Checkpoint名称" - }, - "config_name": { - "name": "配置名称" - } - } - }, - "CheckpointLoaderSimple": { - "description": "加载扩散模型 Checkpoint,用于去除 Latent 噪波。", - "display_name": "Checkpoint加载器(简易)", - "inputs": { - "ckpt_name": { - "name": "Checkpoint名称", - "tooltip": "要加载的Checkpoint模型的名称。" - } - }, - "outputs": { - "0": { - "tooltip": "用于去除 Latent 噪波的模型。" - }, - "1": { - "tooltip": "用于编码文本提示的 CLIP 模型。" - }, - "2": { - "tooltip": "用于将图像编码和解码到 Latent 的 VAE 模型。" - } - } - }, - "CheckpointSave": { - "display_name": "保存Checkpoint", - "inputs": { - "clip": { - "name": "clip" - }, - "filename_prefix": { - "name": "文件名前缀" - }, - "model": { - "name": "模型" - }, - "vae": { - "name": "vae" - } - } - }, - "ChromaRadianceOptions": { - "description": "允许为Chroma Radiance模型设置高级选项。", - "display_name": "ChromaRadiance选项", - "inputs": { - "end_sigma": { - "name": "结束sigma", - "tooltip": "这些选项生效的最后一个sigma值。" - }, - "model": { - "name": "模型" - }, - "nerf_tile_size": { - "name": "NeRF瓦片大小", - "tooltip": "允许覆盖默认的NeRF瓦片大小。-1表示使用默认值(32)。0表示使用非平铺模式(可能需要大量显存)。" - }, - "preserve_wrapper": { - "name": "保留包装器", - "tooltip": "启用时,如果存在现有模型函数包装器,将委托给该包装器。通常应保持启用状态。" - }, - "start_sigma": { - "name": "起始sigma", - "tooltip": "这些选项生效的第一个sigma值。" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, "CombineHooks2": { "display_name": "组合约束 [2]", "inputs": { @@ -1095,12 +1250,12 @@ "ConditioningAverage": { "display_name": "条件平均", "inputs": { - "conditioning_from": { - "name": "条件从" - }, "conditioning_to": { "name": "条件到" }, + "conditioning_from": { + "name": "条件从" + }, "conditioning_to_strength": { "name": "条件到强度" } @@ -1120,11 +1275,11 @@ "ConditioningConcat": { "display_name": "条件连接", "inputs": { - "conditioning_from": { - "name": "条件从" - }, "conditioning_to": { "name": "条件到" + }, + "conditioning_from": { + "name": "条件从" } } }, @@ -1134,20 +1289,20 @@ "conditioning": { "name": "条件" }, - "height": { - "name": "高度" - }, - "strength": { - "name": "强度" - }, "width": { "name": "宽度" }, + "height": { + "name": "高度" + }, "x": { "name": "x" }, "y": { "name": "y" + }, + "strength": { + "name": "强度" } } }, @@ -1157,20 +1312,20 @@ "conditioning": { "name": "条件化" }, - "height": { - "name": "高度" - }, - "strength": { - "name": "强度" - }, "width": { "name": "宽度" }, + "height": { + "name": "高度" + }, "x": { "name": "x" }, "y": { "name": "y" + }, + "strength": { + "name": "强度" } } }, @@ -1180,18 +1335,15 @@ "conditioning": { "name": "调节" }, + "width": { + "name": "宽度" + }, "height": { "name": "高度" }, - "strength": { - "name": "强度" - }, "temporal": { "name": "时间" }, - "width": { - "name": "宽度" - }, "x": { "name": "x" }, @@ -1200,6 +1352,9 @@ }, "z": { "name": "z" + }, + "strength": { + "name": "强度" } } }, @@ -1237,11 +1392,11 @@ "mask": { "name": "遮罩" }, - "set_cond_area": { - "name": "设置条件区域" - }, "strength": { "name": "强度" + }, + "set_cond_area": { + "name": "设置条件区域" } } }, @@ -1251,17 +1406,17 @@ "cond_NEW": { "name": "新条件" }, - "hooks": { - "name": "约束" - }, - "mask": { - "name": "遮罩" + "strength": { + "name": "强度" }, "set_cond_area": { "name": "设置条件区域" }, - "strength": { - "name": "强度" + "mask": { + "name": "遮罩" + }, + "hooks": { + "name": "约束" }, "timesteps": { "name": "间隔" @@ -1277,17 +1432,17 @@ "cond_NEW": { "name": "新条件" }, - "hooks": { - "name": "约束" - }, - "mask": { - "name": "遮罩" + "strength": { + "name": "强度" }, "set_cond_area": { "name": "设置条件区域" }, - "strength": { - "name": "强度" + "mask": { + "name": "遮罩" + }, + "hooks": { + "name": "约束" }, "timesteps": { "name": "间隔" @@ -1300,23 +1455,23 @@ "conditioning": { "name": "条件" }, - "end": { - "name": "结束" - }, "start": { "name": "开始" + }, + "end": { + "name": "结束" } } }, "ConditioningStableAudio": { "display_name": "StableAudio条件", "inputs": { - "negative": { - "name": "负面条件" - }, "positive": { "name": "正面条件" }, + "negative": { + "name": "负面条件" + }, "seconds_start": { "name": "开始秒数" }, @@ -1326,21 +1481,23 @@ }, "outputs": { "0": { - "name": "正面条件" + "name": "正面条件", + "tooltip": null }, "1": { - "name": "负面条件" + "name": "负面条件", + "tooltip": null } } }, "ConditioningTimestepsRange": { "display_name": "条件间隔范围", "inputs": { - "end_percent": { - "name": "结束百分比" - }, "start_percent": { "name": "开始百分比" + }, + "end_percent": { + "name": "结束百分比" } }, "outputs": { @@ -1361,12 +1518,12 @@ } }, "ContextWindowsManual": { - "description": "手动设置上下文窗口。", "display_name": "上下文窗口(手动)", + "description": "手动设置上下文窗口。", "inputs": { - "closed_loop": { - "name": "闭环", - "tooltip": "是否闭合上下文窗口循环;仅适用于循环调度。" + "model": { + "name": "模型", + "tooltip": "在采样期间应用上下文窗口的模型。" }, "context_length": { "name": "上下文长度", @@ -1384,17 +1541,21 @@ "name": "上下文步幅", "tooltip": "上下文窗口的步幅;仅适用于均匀调度。" }, - "dim": { - "name": "维度", - "tooltip": "应用上下文窗口的维度。" + "closed_loop": { + "name": "闭环", + "tooltip": "是否闭合上下文窗口循环;仅适用于循环调度。" }, "fuse_method": { "name": "融合方法", "tooltip": "用于融合上下文窗口的方法。" }, - "model": { - "name": "模型", - "tooltip": "在采样期间应用上下文窗口的模型。" + "dim": { + "name": "维度", + "tooltip": "应用上下文窗口的维度。" + }, + "freenoise": { + "name": "Freenoise", + "tooltip": "是否应用 Freenoise,优化窗口融合。" } }, "outputs": { @@ -1423,26 +1584,26 @@ "ControlNetApplyAdvanced": { "display_name": "应用ControlNet(旧版高级)", "inputs": { - "control_net": { - "name": "ControlNet" - }, - "end_percent": { - "name": "结束百分比" - }, - "image": { - "name": "图像" + "positive": { + "name": "正面条件" }, "negative": { "name": "负面条件" }, - "positive": { - "name": "正面条件" + "control_net": { + "name": "ControlNet" + }, + "image": { + "name": "图像" + }, + "strength": { + "name": "强度" }, "start_percent": { "name": "开始百分比" }, - "strength": { - "name": "强度" + "end_percent": { + "name": "结束百分比" }, "vae": { "name": "vae" @@ -1460,29 +1621,29 @@ "ControlNetApplySD3": { "display_name": "应用ControlNet", "inputs": { - "control_net": { - "name": "ControlNet" - }, - "end_percent": { - "name": "结束百分比" - }, - "image": { - "name": "图像" + "positive": { + "name": "正面条件" }, "negative": { "name": "负面条件" }, - "positive": { - "name": "正面条件" + "control_net": { + "name": "ControlNet" }, - "start_percent": { - "name": "开始百分比" + "vae": { + "name": "vae" + }, + "image": { + "name": "图像" }, "strength": { "name": "强度" }, - "vae": { - "name": "vae" + "start_percent": { + "name": "开始百分比" + }, + "end_percent": { + "name": "结束百分比" } }, "outputs": { @@ -1499,11 +1660,17 @@ "ControlNetInpaintingAliMamaApply": { "display_name": "应用ControlNet(阿里妈妈局部重绘)", "inputs": { + "positive": { + "name": "正面条件" + }, + "negative": { + "name": "负面条件" + }, "control_net": { "name": "ControlNet" }, - "end_percent": { - "name": "结束百分比" + "vae": { + "name": "vae" }, "image": { "name": "图像" @@ -1511,20 +1678,14 @@ "mask": { "name": "遮罩" }, - "negative": { - "name": "负面条件" - }, - "positive": { - "name": "正面条件" + "strength": { + "name": "强度" }, "start_percent": { "name": "开始百分比" }, - "strength": { - "name": "强度" - }, - "vae": { - "name": "vae" + "end_percent": { + "name": "结束百分比" } }, "outputs": { @@ -1547,13 +1708,13 @@ } }, "CosmosImageToVideoLatent": { - "display_name": "Cosmos图像到视频潜在", + "display_name": "图像到视频Latent(Cosmos)", "inputs": { - "batch_size": { - "name": "批量大小" + "vae": { + "name": "vae" }, - "end_image": { - "name": "结束图像" + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -1561,14 +1722,14 @@ "length": { "name": "长度" }, + "batch_size": { + "name": "批量大小" + }, "start_image": { "name": "开始图像" }, - "vae": { - "name": "vae" - }, - "width": { - "name": "宽度" + "end_image": { + "name": "结束图像" } }, "outputs": { @@ -1578,13 +1739,13 @@ } }, "CosmosPredict2ImageToVideoLatent": { - "display_name": "CosmosPredict2图像到视频Latent", + "display_name": "图像到视频Latent(CosmosPredict2)", "inputs": { - "batch_size": { - "name": "批次大小" + "vae": { + "name": "vae" }, - "end_image": { - "name": "结束图像" + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -1592,14 +1753,14 @@ "length": { "name": "长度" }, + "batch_size": { + "name": "批次大小" + }, "start_image": { "name": "起始图像" }, - "vae": { - "name": "vae" - }, - "width": { - "name": "宽度" + "end_image": { + "name": "结束图像" } }, "outputs": { @@ -1611,14 +1772,14 @@ "CreateHookKeyframe": { "display_name": "创建约束关键帧", "inputs": { - "prev_hook_kf": { - "name": "前一个约束关键帧" + "strength_mult": { + "name": "强度倍数" }, "start_percent": { "name": "开始百分比" }, - "strength_mult": { - "name": "强度倍数" + "prev_hook_kf": { + "name": "前一个约束关键帧" } }, "outputs": { @@ -1630,20 +1791,20 @@ "CreateHookKeyframesFromFloats": { "display_name": "从浮点数创建约束关键帧", "inputs": { - "end_percent": { - "name": "结束百分比" - }, "floats_strength": { "name": "浮点强度" }, - "prev_hook_kf": { - "name": "前一个约束关键帧" + "start_percent": { + "name": "开始百分比" + }, + "end_percent": { + "name": "结束百分比" }, "print_keyframes": { "name": "打印关键帧" }, - "start_percent": { - "name": "开始百分比" + "prev_hook_kf": { + "name": "前一个约束关键帧" } }, "outputs": { @@ -1655,29 +1816,29 @@ "CreateHookKeyframesInterpolated": { "display_name": "创建约束关键帧插值", "inputs": { - "end_percent": { - "name": "结束百分比" - }, - "interpolation": { - "name": "插值" - }, - "keyframes_count": { - "name": "关键帧数量" - }, - "prev_hook_kf": { - "name": "前一个约束关键帧" - }, - "print_keyframes": { - "name": "打印关键帧" - }, - "start_percent": { - "name": "开始百分比" + "strength_start": { + "name": "开始强度" }, "strength_end": { "name": "结束强度" }, - "strength_start": { - "name": "开始强度" + "interpolation": { + "name": "插值" + }, + "start_percent": { + "name": "开始百分比" + }, + "end_percent": { + "name": "结束百分比" + }, + "keyframes_count": { + "name": "关键帧数量" + }, + "print_keyframes": { + "name": "打印关键帧" + }, + "prev_hook_kf": { + "name": "前一个约束关键帧" } }, "outputs": { @@ -1692,14 +1853,14 @@ "lora_name": { "name": "LoRA名称" }, - "prev_hooks": { - "name": "前一个约束" + "strength_model": { + "name": "模型强度" }, "strength_clip": { "name": "CLIP强度" }, - "strength_model": { - "name": "模型强度" + "prev_hooks": { + "name": "前一个约束" } } }, @@ -1709,11 +1870,11 @@ "lora_name": { "name": "LoRA名称" }, - "prev_hooks": { - "name": "前一个约束" - }, "strength_model": { "name": "模型强度" + }, + "prev_hooks": { + "name": "前一个约束" } } }, @@ -1723,14 +1884,14 @@ "ckpt_name": { "name": "Checkpoint名称" }, - "prev_hooks": { - "name": "前一个约束" + "strength_model": { + "name": "模型强度" }, "strength_clip": { "name": "CLIP强度" }, - "strength_model": { - "name": "模型强度" + "prev_hooks": { + "name": "前一个约束" } } }, @@ -1740,28 +1901,28 @@ "ckpt_name": { "name": "Checkpoint名称" }, - "prev_hooks": { - "name": "前一个约束" - }, "strength_model": { "name": "模型强度" + }, + "prev_hooks": { + "name": "前一个约束" } } }, "CreateVideo": { - "description": "从图像创建视频。", "display_name": "创建视频", + "description": "从图像创建视频。", "inputs": { - "audio": { - "name": "音频", - "tooltip": "要添加到视频中的音频。" + "images": { + "name": "图像", + "tooltip": "用于创建视频的图像。" }, "fps": { "name": "帧率" }, - "images": { - "name": "图像", - "tooltip": "用于创建视频的图像。" + "audio": { + "name": "音频", + "tooltip": "要添加到视频中的音频。" } }, "outputs": { @@ -1773,31 +1934,36 @@ "CropMask": { "display_name": "裁剪遮罩", "inputs": { - "height": { - "name": "高度" - }, "mask": { "name": "遮罩" }, - "width": { - "name": "宽度" - }, "x": { "name": "x" }, "y": { "name": "y" + }, + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "DiffControlNetLoader": { "display_name": "加载ControlNet模型(diff)", "inputs": { - "control_net_name": { - "name": "ControlNet名称" - }, "model": { "name": "模型" + }, + "control_net_name": { + "name": "ControlNet名称" } } }, @@ -1826,16 +1992,18 @@ } }, "DisableNoise": { - "display_name": "禁用噪波" + "display_name": "禁用噪波", + "outputs": { + "0": { + "tooltip": null + } + } }, "DualCFGGuider": { "display_name": "双CFG引导器", "inputs": { - "cfg_cond2_negative": { - "name": "cfg_条件2_负面" - }, - "cfg_conds": { - "name": "cfg_条件1" + "model": { + "name": "模型" }, "cond1": { "name": "条件1" @@ -1843,20 +2011,28 @@ "cond2": { "name": "条件2" }, - "model": { - "name": "模型" - }, "negative": { "name": "负面条件" }, + "cfg_conds": { + "name": "cfg_条件1" + }, + "cfg_cond2_negative": { + "name": "cfg_条件2_负面" + }, "style": { "name": "样式" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "DualCLIPLoader": { - "description": "[配方]\n\nSDXL:clip-l,clip-g\nSD3:clip-l,clip-g / clip-l,t5 / clip-g,t5\nFlux:clip-l,t5", "display_name": "双CLIP加载器", + "description": "[配方]\n\nSDXL:clip-l,clip-g\nSD3:clip-l,clip-g / clip-l,t5 / clip-g,t5\nFlux:clip-l,t5", "inputs": { "clip_name1": { "name": "CLIP名称1" @@ -1864,11 +2040,11 @@ "clip_name2": { "name": "CLIP名称2" }, - "device": { - "name": "设备" - }, "type": { "name": "类型" + }, + "device": { + "name": "设备" } } }, @@ -1876,10 +2052,6 @@ "display_name": "EasyCache", "description": "原生 EasyCache 实现。", "inputs": { - "end_percent": { - "name": "结束位置", - "tooltip": "结束使用 EasyCache 的相对采样步数。" - }, "model": { "name": "模型", "tooltip": "要添加 EasyCache 的模型。" @@ -1892,6 +2064,10 @@ "name": "开始位置", "tooltip": "开始使用 EasyCache 的相对采样步数。" }, + "end_percent": { + "name": "结束位置", + "tooltip": "结束使用 EasyCache 的相对采样步数。" + }, "verbose": { "name": "调试信息", "tooltip": "是否记录详细信息。" @@ -1906,12 +2082,12 @@ "EmptyAceStepLatentAudio": { "display_name": "空Latent音频(AceStep)", "inputs": { + "seconds": { + "name": "秒数" + }, "batch_size": { "name": "批次大小", "tooltip": "批次中的 Latent 数量。" - }, - "seconds": { - "name": "秒数" } }, "outputs": { @@ -1923,10 +2099,6 @@ "EmptyAudio": { "display_name": "空音频", "inputs": { - "channels": { - "name": "通道", - "tooltip": "音频通道数(1 为单声道,2 为立体声)。" - }, "duration": { "name": "长度", "tooltip": "空音频片段的持续时间(秒)" @@ -1934,20 +2106,29 @@ "sample_rate": { "name": "采样率", "tooltip": "空音频片段的采样率。" + }, + "channels": { + "name": "通道", + "tooltip": "音频通道数(1 为单声道,2 为立体声)。" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "EmptyChromaRadianceLatentImage": { "display_name": "空Latent图像(ChromaRadiance)", "inputs": { - "batch_size": { - "name": "批次大小" + "width": { + "name": "宽度" }, "height": { "name": "高度" }, - "width": { - "name": "宽度" + "batch_size": { + "name": "批次大小" } }, "outputs": { @@ -1957,10 +2138,10 @@ } }, "EmptyCosmosLatentVideo": { - "display_name": "空的Cosmos潜在视频", + "display_name": "空Latent视频(Cosmos)", "inputs": { - "batch_size": { - "name": "批量大小" + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -1968,8 +2149,27 @@ "length": { "name": "长度" }, + "batch_size": { + "name": "批量大小" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "EmptyFlux2LatentImage": { + "display_name": "空Latent图像(Flux2)", + "inputs": { "width": { - "name": "宽度" + "name": "width" + }, + "height": { + "name": "height" + }, + "batch_size": { + "name": "batch_size" } }, "outputs": { @@ -1981,14 +2181,14 @@ "EmptyHunyuanImageLatent": { "display_name": "空Latent图像", "inputs": { - "batch_size": { - "name": "批次大小" + "width": { + "name": "宽度" }, "height": { "name": "高度" }, - "width": { - "name": "宽度" + "batch_size": { + "name": "批次大小" } }, "outputs": { @@ -2000,8 +2200,8 @@ "EmptyHunyuanLatentVideo": { "display_name": "空Latent视频(Hunyuan)", "inputs": { - "batch_size": { - "name": "批量大小" + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -2009,8 +2209,8 @@ "length": { "name": "长度" }, - "width": { - "name": "宽度" + "batch_size": { + "name": "批量大小" } }, "outputs": { @@ -2044,34 +2244,29 @@ "EmptyImage": { "display_name": "空图像", "inputs": { + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" + }, "batch_size": { "name": "批量大小" }, "color": { "name": "颜色" - }, - "height": { - "name": "高度" - }, - "width": { - "name": "宽度" } } }, - "EmptyLTXVLatentVideo": { - "display_name": "空Latent视频(LTXV)", + "EmptyLatentAudio": { + "display_name": "空Latent音频", "inputs": { + "seconds": { + "name": "秒" + }, "batch_size": { - "name": "批量大小" - }, - "height": { - "name": "高度" - }, - "length": { - "name": "长度" - }, - "width": { - "name": "宽度" + "name": "批量大小", + "tooltip": "批次中的Latent数量。" } }, "outputs": { @@ -2080,45 +2275,38 @@ } } }, - "EmptyLatentAudio": { - "display_name": "空Latent音频", - "inputs": { - "batch_size": { - "name": "批量大小", - "tooltip": "批次中的Latent数量。" - }, - "seconds": { - "name": "秒" - } - } - }, "EmptyLatentHunyuan3Dv2": { "display_name": "空Latent图像(Hunyuan3Dv2)", "inputs": { + "resolution": { + "name": "分辨率" + }, "batch_size": { "name": "批次大小", "tooltip": "批次中的Latent数量。" - }, - "resolution": { - "name": "分辨率" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "EmptyLatentImage": { - "description": "创建一批新的空Latent图像,以通过采样进行降噪。", "display_name": "空Latent图像", + "description": "创建一批新的空Latent图像,以通过采样进行降噪。", "inputs": { - "batch_size": { - "name": "批量大小", - "tooltip": "批次中的Latent数量。" + "width": { + "name": "宽度", + "tooltip": "Latent图像的宽度(像素)。" }, "height": { "name": "高度", "tooltip": "Latent图像的高度(像素)。" }, - "width": { - "name": "宽度", - "tooltip": "Latent图像的宽度(像素)。" + "batch_size": { + "name": "批量大小", + "tooltip": "批次中的Latent数量。" } }, "outputs": { @@ -2127,11 +2315,11 @@ } } }, - "EmptyMochiLatentVideo": { - "display_name": "空Latent视频(Mochi)", + "EmptyLTXVLatentVideo": { + "display_name": "空Latent视频(LTXV)", "inputs": { - "batch_size": { - "name": "批量大小" + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -2139,8 +2327,52 @@ "length": { "name": "长度" }, + "batch_size": { + "name": "批量大小" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "EmptyMochiLatentVideo": { + "display_name": "空Latent视频(Mochi)", + "inputs": { "width": { "name": "宽度" + }, + "height": { + "name": "高度" + }, + "length": { + "name": "长度" + }, + "batch_size": { + "name": "批量大小" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "EmptyQwenImageLayeredLatentImage": { + "display_name": "空Latent图像(QwenImageLayerd)", + "inputs": { + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" + }, + "layers": { + "name": "图层" + }, + "batch_size": { + "name": "批次大小" } }, "outputs": { @@ -2152,14 +2384,14 @@ "EmptySD3LatentImage": { "display_name": "空Latent图像(SD3)", "inputs": { - "batch_size": { - "name": "批量大小" + "width": { + "name": "宽度" }, "height": { "name": "高度" }, - "width": { - "name": "宽度" + "batch_size": { + "name": "批量大小" } }, "outputs": { @@ -2187,54 +2419,69 @@ "ExponentialScheduler": { "display_name": "Exponential调度器", "inputs": { + "steps": { + "name": "步数" + }, "sigma_max": { "name": "最大Sigma" }, "sigma_min": { - "name": "最新Sigma" - }, - "steps": { - "name": "步数" + "name": "最小Sigma" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "ExtendIntermediateSigmas": { "display_name": "插值扩展Sigmas", "inputs": { - "end_at_sigma": { - "name": "结束 sigma" - }, "sigmas": { "name": "sigmas" }, - "spacing": { - "name": "间距方式" + "steps": { + "name": "步数" }, "start_at_sigma": { "name": "起始 sigma" }, - "steps": { - "name": "步数" + "end_at_sigma": { + "name": "结束 sigma" + }, + "spacing": { + "name": "间距方式" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "FeatherMask": { "display_name": "羽化遮罩", "inputs": { - "bottom": { - "name": "底" + "mask": { + "name": "遮罩" }, "left": { "name": "左" }, - "mask": { - "name": "遮罩" + "top": { + "name": "顶" }, "right": { "name": "右" }, - "top": { - "name": "顶" + "bottom": { + "name": "底" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, @@ -2244,11 +2491,107 @@ "sigmas": { "name": "sigmas" } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "Flux2MaxImageNode": { + "display_name": "Flux.2 [max] 图像", + "description": "根据提示词和分辨率同步生成图像。", + "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "用于生成或编辑的提示词" + }, + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" + }, + "seed": { + "name": "随机种", + "tooltip": "创建噪波的随机种" + }, + "prompt_upsampling": { + "name": "提示词上采样", + "tooltip": "选择启用提示词采样,启用后会自动修改提示词生成更具创意的内容。" + }, + "images": { + "name": "图像", + "tooltip": "参考图像(最多9张)" + }, + "control_after_generate": { + "name": "生成后控制" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "Flux2ProImageNode": { + "display_name": "Flux.2 [pro] 图像", + "description": "根据提示词和分辨率同步生成图像。", + "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "用于生成或编辑的提示词" + }, + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" + }, + "seed": { + "name": "随机种", + "tooltip": "创建噪波的随机种" + }, + "prompt_upsampling": { + "name": "提示词上采样", + "tooltip": "选择启用提示词采样,启用后会自动修改提示词生成更具创意的内容。" + }, + "images": { + "name": "图像", + "tooltip": "参考图像(最多9张)" + }, + "control_after_generate": { + "name": "生成后控制" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "Flux2Scheduler": { + "display_name": "Flux2调度器", + "inputs": { + "steps": { + "name": "步数" + }, + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" + } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "FluxDisableGuidance": { "display_name": "Flux禁用指导", - "description": "此节点完全禁用Flux和类似Flux模型上的指导嵌入", + "description": "此节点完全禁用Flux和类似Flux模型上的引导嵌入", "inputs": { "conditioning": { "name": "条件" @@ -2278,7 +2621,7 @@ }, "FluxKontextImageScale": { "display_name": "图像缩放为FluxKontext", - "description": "此节点将图像调整为更适合 flux kontext 的尺寸。", + "description": "将图像调整为更适合 Flux Kontext 的尺寸。", "inputs": { "image": { "name": "图像" @@ -2294,35 +2637,35 @@ "display_name": "Flux.1 Kontext [max] 图像", "description": "使用Flux.1 Kontext [max]通过API基于提示词和宽高比编辑图像。", "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "图像生成的提示词 - 指定编辑内容和方式。" + }, "aspect_ratio": { "name": "宽高比", "tooltip": "图像宽高比;必须在1:4和4:1之间。" }, - "control_after_generate": { - "name": "生成后控制" - }, "guidance": { "name": "引导强度", "tooltip": "图像生成过程的引导强度" }, - "input_image": { - "name": "输入图像" - }, - "prompt": { - "name": "提示词", - "tooltip": "图像生成的提示词 - 指定编辑内容和方式。" - }, - "prompt_upsampling": { - "name": "提示词上采样", - "tooltip": "是否对提示词执行上采样。如果启用,会自动修改提示词以获得更具创意的生成结果,但结果具有不确定性(相同种子不会产生完全相同的结果)。" + "steps": { + "name": "步数", + "tooltip": "图像生成过程的步数" }, "seed": { "name": "种子", "tooltip": "用于创建噪声的随机种子。" }, - "steps": { - "name": "步数", - "tooltip": "图像生成过程的步数" + "prompt_upsampling": { + "name": "提示词上采样", + "tooltip": "是否对提示词执行上采样。如果启用,会自动修改提示词以获得更具创意的生成结果,但结果具有不确定性(相同种子不会产生完全相同的结果)。" + }, + "input_image": { + "name": "输入图像" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -2348,38 +2691,38 @@ } }, "FluxKontextProImageNode": { - "description": "使用Flux.1 Kontext [pro]通过API基于提示词和宽高比编辑图像。", "display_name": "Flux.1 Kontext [pro] 图像", + "description": "使用Flux.1 Kontext [pro]通过API基于提示词和宽高比编辑图像。", "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "图像生成的提示词 - 指定编辑内容和方式。" + }, "aspect_ratio": { "name": "宽高比", "tooltip": "图像宽高比;必须在1:4到4:1之间。" }, - "control_after_generate": { - "name": "生成后控制" - }, "guidance": { "name": "引导强度", "tooltip": "图像生成过程的引导强度" }, - "input_image": { - "name": "输入图像" - }, - "prompt": { - "name": "提示词", - "tooltip": "图像生成的提示词 - 指定编辑内容和方式。" - }, - "prompt_upsampling": { - "name": "提示词上采样", - "tooltip": "是否对提示词执行上采样。如果启用,会自动修改提示词以获得更具创意的生成结果,但结果具有不确定性(相同种子不会产生完全相同的结果)。" + "steps": { + "name": "步数", + "tooltip": "图像生成过程的步数" }, "seed": { "name": "种子", "tooltip": "用于创建噪声的随机种子。" }, - "steps": { - "name": "步数", - "tooltip": "图像生成过程的步数" + "prompt_upsampling": { + "name": "提示词上采样", + "tooltip": "是否对提示词执行上采样。如果启用,会自动修改提示词以获得更具创意的生成结果,但结果具有不确定性(相同种子不会产生完全相同的结果)。" + }, + "input_image": { + "name": "输入图像" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -2389,27 +2732,12 @@ } }, "FluxProExpandNode": { - "description": "根据提示词对图像进行外扩。", "display_name": "Flux.1 扩展图像", + "description": "根据提示词对图像进行外扩。", "inputs": { - "bottom": { - "name": "下方扩展", - "tooltip": "在图像底部扩展的像素数" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "guidance": { - "name": "引导强度", - "tooltip": "图像生成过程中的引导强度" - }, "image": { "name": "图像" }, - "left": { - "name": "左侧扩展", - "tooltip": "在图像左侧扩展的像素数" - }, "prompt": { "name": "提示词", "tooltip": "用于生成图像的提示词" @@ -2418,21 +2746,36 @@ "name": "提示词上采样", "tooltip": "是否对提示词进行上采样。启用后会自动修改提示词以获得更具创意的生成效果,但结果具有不确定性(相同种子不会产生完全相同的结果)。" }, + "top": { + "name": "上方扩展", + "tooltip": "在图像顶部扩展的像素数" + }, + "bottom": { + "name": "下方扩展", + "tooltip": "在图像底部扩展的像素数" + }, + "left": { + "name": "左侧扩展", + "tooltip": "在图像左侧扩展的像素数" + }, "right": { "name": "右侧扩展", "tooltip": "在图像右侧扩展的像素数" }, - "seed": { - "name": "种子", - "tooltip": "用于生成噪声的随机种子。" + "guidance": { + "name": "引导强度", + "tooltip": "图像生成过程中的引导强度" }, "steps": { "name": "步数", "tooltip": "图像生成过程的步数" }, - "top": { - "name": "上方扩展", - "tooltip": "在图像顶部扩展的像素数" + "seed": { + "name": "种子", + "tooltip": "用于生成噪声的随机种子。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -2442,16 +2785,9 @@ } }, "FluxProFillNode": { - "description": "根据 mask 和提示词对图像进行修复填充。", "display_name": "Flux.1 填充图像", + "description": "根据 mask 和提示词对图像进行修复填充。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "guidance": { - "name": "引导强度", - "tooltip": "图像生成过程中的引导强度" - }, "image": { "name": "图像" }, @@ -2466,13 +2802,20 @@ "name": "提示词上采样", "tooltip": "是否对提示词进行上采样。启用后会自动修改提示词以获得更具创意的生成效果,但结果具有不确定性(相同种子不会产生完全相同的结果)。" }, - "seed": { - "name": "种子", - "tooltip": "用于生成噪声的随机种子。" + "guidance": { + "name": "引导强度", + "tooltip": "图像生成过程中的引导强度" }, "steps": { "name": "步数", "tooltip": "图像生成过程的步数" + }, + "seed": { + "name": "种子", + "tooltip": "用于生成噪声的随机种子。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -2482,23 +2825,9 @@ } }, "FluxProUltraImageNode": { - "description": "通过 API 使用 Flux Pro 1.1 Ultra 根据提示词和分辨率生成图像。", "display_name": "Flux 1.1 [pro] Ultra Image", + "description": "通过 API 使用 Flux Pro 1.1 Ultra 根据提示词和分辨率生成图像。", "inputs": { - "aspect_ratio": { - "name": "宽高比", - "tooltip": "图像的宽高比;必须在 1:4 到 4:1 之间。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "image_prompt": { - "name": "图像提示词" - }, - "image_prompt_strength": { - "name": "图像提示词强度", - "tooltip": "在提示词和图像提示词之间进行混合。" - }, "prompt": { "name": "提示词", "tooltip": "用于图像生成的提示词" @@ -2507,13 +2836,77 @@ "name": "提示词上采样", "tooltip": "是否对提示词进行上采样。启用时,会自动修改提示词以获得更具创意的生成效果,但结果是非确定性的(相同种子不会产生完全相同的结果)。" }, + "seed": { + "name": "种子", + "tooltip": "用于生成噪声的随机种子。" + }, + "aspect_ratio": { + "name": "宽高比", + "tooltip": "图像的宽高比;必须在 1:4 到 4:1 之间。" + }, "raw": { "name": "原始", "tooltip": "为 True 时,生成更少处理、更自然的图像。" }, - "seed": { - "name": "种子", - "tooltip": "用于生成噪声的随机种子。" + "image_prompt": { + "name": "图像提示词" + }, + "image_prompt_strength": { + "name": "图像提示词强度", + "tooltip": "在提示词和图像提示词之间进行混合。" + }, + "control_after_generate": { + "name": "生成后控制" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "FreeU": { + "display_name": "FreeU", + "inputs": { + "model": { + "name": "模型" + }, + "b1": { + "name": "b1" + }, + "b2": { + "name": "b2" + }, + "s1": { + "name": "s1" + }, + "s2": { + "name": "s2" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "FreeU_V2": { + "display_name": "FreeU_V2", + "inputs": { + "model": { + "name": "模型" + }, + "b1": { + "name": "b1" + }, + "b2": { + "name": "b2" + }, + "s1": { + "name": "s1" + }, + "s2": { + "name": "s2" } }, "outputs": { @@ -2526,20 +2919,20 @@ "display_name": "FreSca", "description": "对引导应用频率相关的缩放", "inputs": { - "freq_cutoff": { - "name": "低频阈值", - "tooltip": "围绕中心被视为低频的频率索引数量" - }, "model": { "name": "模型" }, + "scale_low": { + "name": "低频缩放", + "tooltip": "低频分量的缩放因子" + }, "scale_high": { "name": "高频缩放", "tooltip": "高频分量的缩放因子" }, - "scale_low": { - "name": "低频缩放", - "tooltip": "低频分量的缩放因子" + "freq_cutoff": { + "name": "低频阈值", + "tooltip": "围绕中心被视为低频的频率索引数量" } }, "outputs": { @@ -2548,143 +2941,6 @@ } } }, - "FreeU": { - "display_name": "FreeU", - "inputs": { - "b1": { - "name": "b1" - }, - "b2": { - "name": "b2" - }, - "model": { - "name": "模型" - }, - "s1": { - "name": "s1" - }, - "s2": { - "name": "s2" - } - } - }, - "FreeU_V2": { - "display_name": "FreeU_V2", - "inputs": { - "b1": { - "name": "b1" - }, - "b2": { - "name": "b2" - }, - "model": { - "name": "模型" - }, - "s1": { - "name": "s1" - }, - "s2": { - "name": "s2" - } - } - }, - "GITSScheduler": { - "display_name": "GITS调度器", - "inputs": { - "coeff": { - "name": "系数" - }, - "denoise": { - "name": "降噪" - }, - "steps": { - "name": "步数" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, - "GLIGENLoader": { - "display_name": "GLIGEN加载器", - "inputs": { - "gligen_name": { - "name": "gligen名称" - } - } - }, - "GLIGENTextBoxApply": { - "display_name": "GLIGEN文本框应用", - "inputs": { - "clip": { - "name": "CLIP" - }, - "conditioning_to": { - "name": "条件到" - }, - "gligen_textbox_model": { - "name": "GLIGEN文本框模型" - }, - "height": { - "name": "高度" - }, - "text": { - "name": "文本" - }, - "width": { - "name": "宽度" - }, - "x": { - "name": "x" - }, - "y": { - "name": "y" - } - } - }, - "GeminiImageNode": { - "display_name": "Nano Banana (Google Gemini 图像)", - "description": "通过Google API同步编辑图像。", - "inputs": { - "aspect_ratio": { - "name": "宽高比", - "tooltip": "默认匹配输入图像的输出尺寸,否则生成1:1正方形。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "files": { - "name": "文件", - "tooltip": "可选文件,用作模型的上下文。接受来自Gemini生成内容输入文件节点的输入。" - }, - "images": { - "name": "图像", - "tooltip": "可选图像,用作模型的上下文。要包含多个图像,可以使用批量图像节点。" - }, - "model": { - "name": "模型", - "tooltip": "用于生成响应的Gemini模型。" - }, - "prompt": { - "name": "提示词", - "tooltip": "用于生成的文本提示词" - }, - "seed": { - "name": "种子", - "tooltip": "当种子固定为特定值时,模型会尽力为重复请求提供相同的响应。不能保证确定性输出。此外,更改模型或参数设置(如温度)即使使用相同的种子值也可能导致响应变化。默认使用随机种子值。" - } - }, - "outputs": { - "0": { - "tooltip": null - }, - "1": { - "tooltip": null - } - } - }, "GeminiImage2Node": { "display_name": "Nano Banana Pro(Google Gemini 图像)", "description": "通过Google API编辑图像。", @@ -2720,6 +2976,59 @@ "name": "文件", "tooltip": "模型上下文文件。接受来自 Gemini输入文件 节点的输入。" }, + "system_prompt": { + "name": "系统提示词", + "tooltip": "决定 AI 行为的基本指令。" + }, + "control_after_generate": { + "name": "生成后控制" + } + }, + "outputs": { + "0": { + "tooltip": null + }, + "1": { + "tooltip": null + } + } + }, + "GeminiImageNode": { + "display_name": "Nano Banana (Google Gemini 图像)", + "description": "通过Google API同步编辑图像。", + "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "用于生成的文本提示词" + }, + "model": { + "name": "模型", + "tooltip": "用于生成响应的Gemini模型。" + }, + "seed": { + "name": "种子", + "tooltip": "当种子固定为特定值时,模型会尽力为重复请求提供相同的响应。不能保证确定性输出。此外,更改模型或参数设置(如温度)即使使用相同的种子值也可能导致响应变化。默认使用随机种子值。" + }, + "images": { + "name": "图像", + "tooltip": "可选图像,用作模型的上下文。要包含多个图像,可以使用批量图像节点。" + }, + "files": { + "name": "文件", + "tooltip": "可选文件,用作模型的上下文。接受来自Gemini生成内容输入文件节点的输入。" + }, + "aspect_ratio": { + "name": "宽高比", + "tooltip": "默认匹配输入图像的输出尺寸,否则生成1:1正方形。" + }, + "response_modalities": { + "name": "回复模态", + "tooltip": "选择“图像”仅输出图像,选择“图像+文本”输出图像和文本。" + }, + "system_prompt": { + "name": "系统提示词", + "tooltip": "决定 AI 行为的基本指令。" + }, "control_after_generate": { "name": "生成后控制" } @@ -2737,13 +3046,13 @@ "display_name": "Gemini 输入文件", "description": "加载并准备输入文件,作为 Gemini LLM 节点的输入。文件将在生成响应时由 Gemini 模型读取。文本文件的内容计入令牌限制。🛈 提示:可与其他 Gemini 输入文件节点链式连接。", "inputs": { - "GEMINI_INPUT_FILES": { - "name": "Gemini 输入文件", - "tooltip": "与此节点加载的文件批量组合的可选附加文件。允许链式连接输入文件,以便单个消息可包含多个输入文件。" - }, "file": { "name": "文件", "tooltip": "作为模型上下文包含的输入文件。目前仅接受文本 (.txt) 和 PDF (.pdf) 文件。" + }, + "GEMINI_INPUT_FILES": { + "name": "Gemini 输入文件", + "tooltip": "与此节点加载的文件批量组合的可选附加文件。允许链式连接输入文件,以便单个消息可包含多个输入文件。" } }, "outputs": { @@ -2753,39 +3062,43 @@ } }, "GeminiNode": { - "description": "使用 Google 的 Gemini AI 模型生成文本响应。您可以提供多种类型的输入(文本、图像、音频、视频)作为上下文,以生成更相关和有意义的响应。", "display_name": "Google Gemini", + "description": "使用 Google 的 Gemini AI 模型生成文本响应。您可以提供多种类型的输入(文本、图像、音频、视频)作为上下文,以生成更相关和有意义的响应。", "inputs": { - "audio": { - "name": "音频", - "tooltip": "用作模型上下文的可选音频。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "files": { - "name": "文件", - "tooltip": "用作模型上下文的可选文件。接受来自 Gemini 生成内容输入文件节点的输入。" - }, - "images": { - "name": "图像", - "tooltip": "用作模型上下文的可选图像。要包含多个图像,可使用批处理图像节点。" + "prompt": { + "name": "提示", + "tooltip": "模型的文本输入,用于生成响应。您可以包含详细的指令、问题或模型上下文。" }, "model": { "name": "模型", "tooltip": "用于生成响应的 Gemini 模型。" }, - "prompt": { - "name": "提示", - "tooltip": "模型的文本输入,用于生成响应。您可以包含详细的指令、问题或模型上下文。" - }, "seed": { "name": "种子", "tooltip": "当种子固定为特定值时,模型会尽力为重复请求提供相同的响应。不保证确定性输出。此外,更改模型或参数设置(如温度)即使使用相同的种子值也可能导致响应变化。默认使用随机种子值。" }, + "images": { + "name": "图像", + "tooltip": "用作模型上下文的可选图像。要包含多个图像,可使用批处理图像节点。" + }, + "audio": { + "name": "音频", + "tooltip": "用作模型上下文的可选音频。" + }, "video": { "name": "视频", "tooltip": "用作模型上下文的可选视频。" + }, + "files": { + "name": "文件", + "tooltip": "用作模型上下文的可选文件。接受来自 Gemini 生成内容输入文件节点的输入。" + }, + "system_prompt": { + "name": "系统提示词", + "tooltip": "决定 AI 行为的基本指令。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -2794,9 +3107,75 @@ } } }, + "GenerateTracks": { + "display_name": "生成轨道", + "inputs": { + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" + }, + "start_x": { + "name": "起始点X", + "tooltip": "起始点的规格化X坐标(0-1)。" + }, + "start_y": { + "name": "起始点Y", + "tooltip": "起始点的规格化Y坐标(0-1)。" + }, + "end_x": { + "name": "结束点X", + "tooltip": "结束点的规格化X坐标(0-1)。" + }, + "end_y": { + "name": "结束点Y", + "tooltip": "结束点的规格化Y坐标(0-1)。" + }, + "num_frames": { + "name": "帧数" + }, + "num_tracks": { + "name": "轨迹数" + }, + "track_spread": { + "name": "轨道分布", + "tooltip": "轨道间的规格化距离。垂直于轨迹运动方向展开。" + }, + "bezier": { + "name": "贝塞尔曲线", + "tooltip": "贝塞尔曲线路径,使用中点作为控制点。" + }, + "mid_x": { + "name": "中间点Y", + "tooltip": "中间点的规格化Y坐标(0-1)。" + }, + "mid_y": { + "name": "中间点Y", + "tooltip": "中间点的规格化Y坐标(0-1)。" + }, + "interpolation": { + "name": "插值", + "tooltip": "控制轨迹沿着路径移动的时间/速度。" + }, + "track_mask": { + "name": "轨道遮罩", + "tooltip": "遮罩,用于标记可见帧" + } + }, + "outputs": { + "0": { + "tooltip": null + }, + "1": { + "name": "轨迹长度", + "tooltip": null + } + } + }, "GetImageSize": { - "description": "返回图像的宽度和高度,并原样传递图像。", "display_name": "获取图像尺寸", + "description": "返回图像的宽度和高度,并原样传递图像。", "inputs": { "image": { "name": "图像" @@ -2804,23 +3183,26 @@ }, "outputs": { "0": { - "name": "宽度" + "name": "宽度", + "tooltip": null }, "1": { - "name": "高度" + "name": "高度", + "tooltip": null }, "2": { - "name": "批处理大小" + "name": "批处理大小", + "tooltip": null } } }, "GetVideoComponents": { - "description": "提取视频中的所有组件:帧、音频和帧率。", - "display_name": "获取视频组件", + "display_name": "获取视频元素", + "description": "提取视频中的所有元素:帧、音频和帧率。", "inputs": { "video": { "name": "视频", - "tooltip": "要提取组件的视频。" + "tooltip": "要提取元素的视频。" } }, "outputs": { @@ -2838,18 +3220,79 @@ } } }, + "GITSScheduler": { + "display_name": "GITS调度器", + "inputs": { + "coeff": { + "name": "系数" + }, + "steps": { + "name": "步数" + }, + "denoise": { + "name": "降噪" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "GLIGENLoader": { + "display_name": "GLIGEN加载器", + "inputs": { + "gligen_name": { + "name": "gligen名称" + } + } + }, + "GLIGENTextBoxApply": { + "display_name": "GLIGEN文本框应用", + "inputs": { + "conditioning_to": { + "name": "条件到" + }, + "clip": { + "name": "CLIP" + }, + "gligen_textbox_model": { + "name": "GLIGEN文本框模型" + }, + "text": { + "name": "文本" + }, + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" + }, + "x": { + "name": "x" + }, + "y": { + "name": "y" + } + } + }, "GrowMask": { "display_name": "扩展遮罩", "inputs": { - "expand": { - "name": "扩展" - }, "mask": { "name": "遮罩" }, + "expand": { + "name": "扩展" + }, "tapered_corners": { "name": "倒角" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "Hunyuan3Dv2Conditioning": { @@ -2861,46 +3304,53 @@ }, "outputs": { "0": { - "name": "正向" + "name": "正向", + "tooltip": null }, "1": { - "name": "反向" + "name": "反向", + "tooltip": null } } }, "Hunyuan3Dv2ConditioningMultiView": { "display_name": "Hunyuan3Dv2条件多视角", "inputs": { - "back": { - "name": "后" - }, "front": { "name": "前" }, "left": { "name": "左" }, + "back": { + "name": "后" + }, "right": { "name": "右" } }, "outputs": { "0": { - "name": "正向" + "name": "正向", + "tooltip": null }, "1": { - "name": "反向" + "name": "反向", + "tooltip": null } } }, "HunyuanImageToVideo": { - "display_name": "Hunyuan图像到视频", + "display_name": "图像到视频(Hunyuan)", "inputs": { - "batch_size": { - "name": "批量大小" + "positive": { + "name": "正向" }, - "guidance_type": { - "name": "指导类型" + "vae": { + "name": "vae" + }, + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -2908,17 +3358,14 @@ "length": { "name": "长度" }, - "positive": { - "name": "正向" + "batch_size": { + "name": "批量大小" + }, + "guidance_type": { + "name": "指导类型" }, "start_image": { "name": "起始图像" - }, - "vae": { - "name": "vae" - }, - "width": { - "name": "宽度" } }, "outputs": { @@ -2935,17 +3382,17 @@ "HunyuanRefinerLatent": { "display_name": "HunyuanRefinerLatent", "inputs": { - "latent": { - "name": "Latent" + "positive": { + "name": "正面" }, "negative": { "name": "负面" }, + "latent": { + "name": "Latent" + }, "noise_augmentation": { "name": "噪声增强" - }, - "positive": { - "name": "正面" } }, "outputs": { @@ -2964,7 +3411,7 @@ } }, "HunyuanVideo15ImageToVideo": { - "display_name": "Hunyuan Video 15 图像到视频", + "display_name": "图像到视频(Hunyuan Video 15 )", "inputs": { "positive": { "name": "正面条件" @@ -3077,40 +3524,15 @@ } } }, - "HyperTile": { - "display_name": "超分块HyperTile", - "inputs": { - "max_depth": { - "name": "最大深度" - }, - "model": { - "name": "模型" - }, - "scale_depth": { - "name": "规模深度" - }, - "swap_size": { - "name": "分割尺寸" - }, - "tile_size": { - "name": "分块尺寸" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, "HypernetworkLoader": { "display_name": "超网络加载器", "inputs": { - "hypernetwork_name": { - "name": "HyperNetwork名称" - }, "model": { "name": "模型" }, + "hypernetwork_name": { + "name": "HyperNetwork名称" + }, "strength": { "name": "强度" } @@ -3121,21 +3543,54 @@ } } }, - "IdeogramV1": { - "description": "使用 Ideogram V1 模型同步生成图像。\n\n图片链接仅在有限时间内有效;如果您想保留图片,请务必下载。", - "display_name": "Ideogram V1", + "HyperTile": { + "display_name": "超分块HyperTile", "inputs": { + "model": { + "name": "模型" + }, + "tile_size": { + "name": "分块尺寸" + }, + "swap_size": { + "name": "分割尺寸" + }, + "max_depth": { + "name": "最大深度" + }, + "scale_depth": { + "name": "规模深度" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "IdeogramV1": { + "display_name": "Ideogram V1", + "description": "使用 Ideogram V1 模型同步生成图像。\n\n图片链接仅在有限时间内有效;如果您想保留图片,请务必下载。", + "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "用于图像生成的提示词" + }, + "turbo": { + "name": "turbo", + "tooltip": "是否启用 turbo 模式(生成更快,但可能质量较低)" + }, "aspect_ratio": { "name": "宽高比", "tooltip": "图像生成的宽高比。" }, - "control_after_generate": { - "name": "生成后控制" - }, "magic_prompt_option": { "name": "Magic Prompt", "tooltip": "确定生成时是否使用 MagicPrompt" }, + "seed": { + "name": "随机种" + }, "negative_prompt": { "name": "负面提示词", "tooltip": "描述需要从图像中排除的内容" @@ -3143,16 +3598,8 @@ "num_images": { "name": "图像数量" }, - "prompt": { - "name": "提示词", - "tooltip": "用于图像生成的提示词" - }, - "seed": { - "name": "随机种" - }, - "turbo": { - "name": "turbo", - "tooltip": "是否启用 turbo 模式(生成更快,但可能质量较低)" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -3162,35 +3609,29 @@ } }, "IdeogramV2": { - "description": "使用 Ideogram V2 模型同步生成图像。\n\n图像链接仅在有限时间内有效;如果您想保留图像,请务必下载。", "display_name": "Ideogram V2", + "description": "使用 Ideogram V2 模型同步生成图像。\n\n图像链接仅在有限时间内有效;如果您想保留图像,请务必下载。", "inputs": { - "aspect_ratio": { - "name": "宽高比", - "tooltip": "图像生成的宽高比。如果分辨率未设置为 AUTO,则此项无效。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "magic_prompt_option": { - "name": "Magic Prompt", - "tooltip": "确定生成时是否使用 MagicPrompt" - }, - "negative_prompt": { - "name": "负面提示词", - "tooltip": "描述图像中需要排除的内容" - }, - "num_images": { - "name": "图像数量" - }, "prompt": { "name": "提示词", "tooltip": "用于图像生成的提示词" }, + "turbo": { + "name": "turbo", + "tooltip": "是否启用 turbo 模式(生成更快,质量可能略低)" + }, + "aspect_ratio": { + "name": "宽高比", + "tooltip": "图像生成的宽高比。如果分辨率未设置为 AUTO,则此项无效。" + }, "resolution": { "name": "分辨率", "tooltip": "图像生成的分辨率。如果未设置为 AUTO,则会覆盖 aspect_ratio 设置。" }, + "magic_prompt_option": { + "name": "Magic Prompt", + "tooltip": "确定生成时是否使用 MagicPrompt" + }, "seed": { "name": "随机种" }, @@ -3198,9 +3639,15 @@ "name": "风格", "tooltip": "生成的风格类型(仅限 V2)" }, - "turbo": { - "name": "turbo", - "tooltip": "是否启用 turbo 模式(生成更快,质量可能略低)" + "negative_prompt": { + "name": "负面提示词", + "tooltip": "描述图像中需要排除的内容" + }, + "num_images": { + "name": "图像数量" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -3210,13 +3657,43 @@ } }, "IdeogramV3": { - "description": "使用 Ideogram V3 模型同步生成图像。\n\n支持从文本提示生成常规图像,也支持使用 mask 进行图像编辑。\n图片链接仅在有限时间内有效;如需保留图片,请务必下载。", "display_name": "Ideogram V3", + "description": "使用 Ideogram V3 模型同步生成图像。\n\n支持从文本提示生成常规图像,也支持使用 mask 进行图像编辑。\n图片链接仅在有限时间内有效;如需保留图片,请务必下载。", "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "用于图像生成或编辑的提示词" + }, + "image": { + "name": "图像", + "tooltip": "用于图像编辑的可选参考图片。" + }, + "mask": { + "name": "遮罩", + "tooltip": "用于修复的可选 mask(白色区域将被替换)" + }, "aspect_ratio": { "name": "宽高比", "tooltip": "图像生成的宽高比。如果分辨率未设置为自动,则忽略此项。" }, + "resolution": { + "name": "分辨率", + "tooltip": "图像生成的分辨率。如果未设置为自动,则覆盖 aspect_ratio 设置。" + }, + "magic_prompt_option": { + "name": "Magic Prompt", + "tooltip": "决定生成时是否使用 MagicPrompt" + }, + "seed": { + "name": "随机种" + }, + "num_images": { + "name": "图像数量" + }, + "rendering_speed": { + "name": "生成速度", + "tooltip": "控制生成速度与质量之间的权衡" + }, "character_image": { "name": "角色图像", "tooltip": "用作角色参考的图像。" @@ -3227,36 +3704,6 @@ }, "control_after_generate": { "name": "生成后控制" - }, - "image": { - "name": "图像", - "tooltip": "用于图像编辑的可选参考图片。" - }, - "magic_prompt_option": { - "name": "Magic Prompt", - "tooltip": "决定生成时是否使用 MagicPrompt" - }, - "mask": { - "name": "遮罩", - "tooltip": "用于修复的可选 mask(白色区域将被替换)" - }, - "num_images": { - "name": "图像数量" - }, - "prompt": { - "name": "提示词", - "tooltip": "用于图像生成或编辑的提示词" - }, - "rendering_speed": { - "name": "生成速度", - "tooltip": "控制生成速度与质量之间的权衡" - }, - "resolution": { - "name": "分辨率", - "tooltip": "图像生成的分辨率。如果未设置为自动,则覆盖 aspect_ratio 设置。" - }, - "seed": { - "name": "随机种" } }, "outputs": { @@ -3268,9 +3715,6 @@ "ImageAddNoise": { "display_name": "图像添加噪声", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, "image": { "name": "图像" }, @@ -3280,6 +3724,14 @@ }, "strength": { "name": "强度" + }, + "control_after_generate": { + "name": "生成后控制" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, @@ -3297,17 +3749,17 @@ "ImageBlend": { "display_name": "混合图像", "inputs": { - "blend_factor": { - "name": "系数" - }, - "blend_mode": { - "name": "混合模式" - }, "image1": { "name": "图像1" }, "image2": { "name": "图像2" + }, + "blend_factor": { + "name": "系数" + }, + "blend_mode": { + "name": "混合模式" } }, "outputs": { @@ -3319,12 +3771,12 @@ "ImageBlur": { "display_name": "模糊图像", "inputs": { - "blur_radius": { - "name": "模糊半径" - }, "image": { "name": "图像" }, + "blur_radius": { + "name": "模糊半径" + }, "sigma": { "name": "西格玛" } @@ -3338,11 +3790,16 @@ "ImageColorToMask": { "display_name": "图像颜色到遮罩", "inputs": { - "color": { - "name": "颜色" - }, "image": { "name": "图像" + }, + "color": { + "name": "颜色" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, @@ -3352,12 +3809,6 @@ "destination": { "name": "目标图像" }, - "mask": { - "name": "遮罩" - }, - "resize_source": { - "name": "缩放来源图像" - }, "source": { "name": "来源图像" }, @@ -3366,52 +3817,128 @@ }, "y": { "name": "y" + }, + "resize_source": { + "name": "缩放来源图像" + }, + "mask": { + "name": "遮罩" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "ImageCrop": { "display_name": "裁剪图像", "inputs": { - "height": { - "name": "高度" - }, "image": { "name": "图像" }, "width": { "name": "宽度" }, + "height": { + "name": "高度" + }, "x": { "name": "x" }, "y": { "name": "y" } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "ImageDeduplication": { + "display_name": "图像去重", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要处理的图像序列。" + }, + "similarity_threshold": { + "name": "相似度阈值", + "tooltip": "相似阈值(0-1)。越高表示越相似。超过该值的图像则认定为重复图像。" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "处理后的图像" + } } }, "ImageFlip": { "display_name": "图像翻转", "inputs": { - "flip_method": { - "name": "翻转方法" - }, "image": { "name": "图像" + }, + "flip_method": { + "name": "翻转方法" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "ImageFromBatch": { "display_name": "从批次获取图像", "inputs": { - "batch_index": { - "name": "批次索引" - }, "image": { "name": "图像" }, + "batch_index": { + "name": "批次索引" + }, "length": { "name": "长度" } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "ImageGrid": { + "display_name": "图像表格", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要处理的图像序列。" + }, + "columns": { + "name": "列数", + "tooltip": "表格的列数。" + }, + "cell_width": { + "name": "单元格宽度", + "tooltip": "表格中每个单元格的宽度。" + }, + "cell_height": { + "name": "单元格高度", + "tooltip": "表格中每个单元格的高度。" + }, + "padding": { + "name": "间距", + "tooltip": "图像间距" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "处理后的图像" + } } }, "ImageInvert": { @@ -3433,54 +3960,54 @@ "ImageOnlyCheckpointSave": { "display_name": "保存Checkpoint(仅图像)", "inputs": { - "clip_vision": { - "name": "clip视觉" - }, - "filename_prefix": { - "name": "文件名前缀" - }, "model": { "name": "模型" }, + "clip_vision": { + "name": "clip视觉" + }, "vae": { "name": "vae" + }, + "filename_prefix": { + "name": "文件名前缀" } } }, "ImagePadForOutpaint": { "display_name": "外补画板", "inputs": { - "bottom": { - "name": "下" - }, - "feathering": { - "name": "羽化" - }, "image": { "name": "图像" }, "left": { "name": "左" }, + "top": { + "name": "上" + }, "right": { "name": "右" }, - "top": { - "name": "上" + "bottom": { + "name": "下" + }, + "feathering": { + "name": "羽化" } } }, "ImageQuantize": { "display_name": "量化图像", "inputs": { + "image": { + "name": "图像" + }, "colors": { "name": "颜色" }, "dither": { "name": "抖动" - }, - "image": { - "name": "图像" } }, "outputs": { @@ -3520,17 +4047,16 @@ "rotation": { "name": "旋转" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "ImageScale": { "display_name": "缩放图像", "inputs": { - "crop": { - "name": "裁剪" - }, - "height": { - "name": "高度" - }, "image": { "name": "图像" }, @@ -3539,6 +4065,12 @@ }, "width": { "name": "宽度" + }, + "height": { + "name": "高度" + }, + "crop": { + "name": "裁剪" } } }, @@ -3548,11 +4080,11 @@ "image": { "name": "图像" }, - "scale_by": { - "name": "缩放系数" - }, "upscale_method": { "name": "缩放算法" + }, + "scale_by": { + "name": "缩放系数" } } }, @@ -3562,11 +4094,16 @@ "image": { "name": "图像" }, - "largest_size": { - "name": "最大尺寸" - }, "upscale_method": { "name": "放大方法" + }, + "largest_size": { + "name": "最大尺寸" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, @@ -3576,11 +4113,14 @@ "image": { "name": "图像" }, + "upscale_method": { + "name": "缩放算法" + }, "megapixels": { "name": "像素数量" }, - "upscale_method": { - "name": "缩放算法" + "resolution_steps": { + "name": "分辨率步数" } }, "outputs": { @@ -3592,9 +4132,6 @@ "ImageSharpen": { "display_name": "锐化图像", "inputs": { - "alpha": { - "name": "alpha" - }, "image": { "name": "图像" }, @@ -3603,6 +4140,9 @@ }, "sigma": { "name": "Sigma" + }, + "alpha": { + "name": "alpha" } }, "outputs": { @@ -3612,48 +4152,58 @@ } }, "ImageStitch": { - "description": "\n将 image2 按指定方向拼接到 image1 上。\n如果未提供 image2,则返回未更改的 image1。\n可以在图像之间添加可选间距。\n", "display_name": "图像拼接", + "description": "\n将 image2 按指定方向拼接到 image1 上。\n如果未提供 image2,则返回未更改的 image1。\n可以在图像之间添加可选间距。\n", "inputs": { - "direction": { - "name": "方向" - }, "image1": { "name": "图像1" }, - "image2": { - "name": "图像2" + "direction": { + "name": "方向" }, "match_image_size": { "name": "匹配图像尺寸" }, + "spacing_width": { + "name": "间距宽度" + }, "spacing_color": { "name": "间距颜色" }, - "spacing_width": { - "name": "间距宽度" + "image2": { + "name": "图像2" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "ImageToMask": { "display_name": "图像转换为遮罩", "inputs": { - "channel": { - "name": "通道" - }, "image": { "name": "图像" + }, + "channel": { + "name": "通道" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "ImageUpscaleWithModel": { "display_name": "使用模型放大图像", "inputs": { - "image": { - "name": "图像" - }, "upscale_model": { "name": "放大模型" + }, + "image": { + "name": "图像" } }, "outputs": { @@ -3665,14 +4215,14 @@ "ImageYUVToRGB": { "display_name": "图像YUV到RGB", "inputs": { + "Y": { + "name": "Y" + }, "U": { "name": "U" }, "V": { "name": "V" - }, - "Y": { - "name": "Y" } }, "outputs": { @@ -3684,24 +4234,24 @@ "InpaintModelConditioning": { "display_name": "内补模型条件", "inputs": { - "mask": { - "name": "遮罩" + "positive": { + "name": "正面条件" }, "negative": { "name": "负面条件" }, - "noise_mask": { - "name": "噪波遮罩", - "tooltip": "向Latent图像添加遮罩,采样仅在遮罩内进行。根据模型的不同,可能会改善结果或完全破坏效果。" + "vae": { + "name": "vae" }, "pixels": { "name": "像素" }, - "positive": { - "name": "正面条件" + "mask": { + "name": "遮罩" }, - "vae": { - "name": "vae" + "noise_mask": { + "name": "噪波遮罩", + "tooltip": "向Latent图像添加遮罩,采样仅在遮罩内进行。根据模型的不同,可能会改善结果或完全破坏效果。" } }, "outputs": { @@ -3719,17 +4269,17 @@ "InstructPixToPixConditioning": { "display_name": "InstructPixToPix条件", "inputs": { - "negative": { - "name": "负面条件" - }, - "pixels": { - "name": "像素" - }, "positive": { "name": "正面条件" }, + "negative": { + "name": "负面条件" + }, "vae": { "name": "vae" + }, + "pixels": { + "name": "像素" } }, "outputs": { @@ -3753,16 +4303,21 @@ "mask": { "name": "遮罩" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "JoinImageWithAlpha": { "display_name": "合并图像Alpha", "inputs": { - "alpha": { - "name": "阿尔法" - }, "image": { "name": "图像" + }, + "alpha": { + "name": "阿尔法" } }, "outputs": { @@ -3771,120 +4326,58 @@ } } }, - "KSampler": { - "description": "使用提供的模型、正面条件和负面条件条件降噪Latent图像。", - "display_name": "K采样器", + "Kandinsky5ImageToVideo": { + "display_name": "图像到视频(Kandinsky5)", "inputs": { - "cfg": { - "name": "cfg", - "tooltip": "用于平衡随机性和提示词服从性。提高该值会使结果更加符合提示词,但过高会导致图像质量下降。" - }, - "control_after_generate": { - "name": "生成后的控制" - }, - "denoise": { - "name": "降噪", - "tooltip": "降噪的强度,降低该值会保留原图的大部分内容从而实现图生图。" - }, - "latent_image": { - "name": "Latent图像", - "tooltip": "要降噪的 Latent 图像。" - }, - "model": { - "name": "模型", - "tooltip": "用于降噪输入 Latent 图像的模型。" - }, - "negative": { - "name": "负面条件", - "tooltip": "描述不包含在图像中的内容的条件。" - }, "positive": { - "name": "正面条件", - "tooltip": "描述包含在图像中的内容的条件。" - }, - "sampler_name": { - "name": "采样器名称", - "tooltip": "采样算法,会影响结果质量、生成速度、风格样式。" - }, - "scheduler": { - "name": "调度器", - "tooltip": "控制逐渐移除噪波的方法。" - }, - "seed": { - "name": "种子", - "tooltip": "生成噪波的随机种。" - }, - "steps": { - "name": "步数", - "tooltip": "降噪的步数。" - } - }, - "outputs": { - "0": { - "tooltip": "降噪后的 Latent。" - } - } - }, - "KSamplerAdvanced": { - "display_name": "K采样器(高级)", - "inputs": { - "add_noise": { - "name": "添加噪波" - }, - "cfg": { - "name": "cfg" - }, - "control_after_generate": { - "name": "生成后的控制" - }, - "end_at_step": { - "name": "结束步数" - }, - "latent_image": { - "name": "Latent图像" - }, - "model": { - "name": "模型" + "name": "正面条件" }, "negative": { "name": "负面条件" }, - "noise_seed": { - "name": "随机种" + "vae": { + "name": "vae" }, - "positive": { - "name": "正面条件" + "width": { + "name": "宽度" }, - "return_with_leftover_noise": { - "name": "返回剩余噪波" + "height": { + "name": "高度 " }, - "sampler_name": { - "name": "采样器名称" + "length": { + "name": "时长" }, - "scheduler": { - "name": "调度器" + "batch_size": { + "name": "批次大小" }, - "start_at_step": { - "name": "开始步数" - }, - "steps": { - "name": "步数" + "start_image": { + "name": "初始图象" } - } - }, - "KSamplerSelect": { - "display_name": "K采样器选择", - "inputs": { - "sampler_name": { - "name": "采样器名称" + }, + "outputs": { + "0": { + "name": "正面条件", + "tooltip": null + }, + "1": { + "name": "负面条件", + "tooltip": null + }, + "2": { + "name": "Latent", + "tooltip": "空视频Latent" + }, + "3": { + "name": "条件Latent", + "tooltip": "纯净编码的 Latent,用于替代纯噪波 Latent 输出。" } } }, "KarrasScheduler": { "display_name": "Karras调度器", "inputs": { - "rho": { - "name": "rho" + "steps": { + "name": "步数" }, "sigma_max": { "name": "最大Sigma" @@ -3892,73 +4385,41 @@ "sigma_min": { "name": "最小Sigma" }, - "steps": { - "name": "步数" + "rho": { + "name": "rho" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "KlingCameraControlI2VNode": { - "description": "将静态图像转化为具有专业摄像机运动的电影级视频,模拟真实世界的电影摄影。可控制虚拟摄像机的缩放、旋转、平移、俯仰和第一人称视角,同时保持对原始图像的聚焦。", "display_name": "Kling 图像转视频(摄像机控制)", + "description": "将静态图像转化为具有专业摄像机运动的电影级视频,模拟真实世界的电影摄影。可控制虚拟摄像机的缩放、旋转、平移、俯仰和第一人称视角,同时保持对原始图像的聚焦。", "inputs": { + "start_frame": { + "name": "起始帧", + "tooltip": "参考图像 - URL 或 Base64 编码字符串,不能超过 10MB,分辨率不低于 300*300 像素,宽高比在 1:2.5 ~ 2.5:1 之间。Base64 不应包含 data:image 前缀。" + }, + "prompt": { + "name": "提示词", + "tooltip": "正向文本提示" + }, + "negative_prompt": { + "name": "负面提示词", + "tooltip": "反向文本提示" + }, + "cfg_scale": { + "name": "CFG" + }, "aspect_ratio": { "name": "宽高比" }, "camera_control": { "name": "镜头控制", "tooltip": "可通过 Kling Camera Controls 节点创建。控制视频生成过程中的摄像机运动和动作。" - }, - "cfg_scale": { - "name": "CFG" - }, - "negative_prompt": { - "name": "负面提示词", - "tooltip": "反向文本提示" - }, - "prompt": { - "name": "提示词", - "tooltip": "正向文本提示" - }, - "start_frame": { - "name": "起始帧", - "tooltip": "参考图像 - URL 或 Base64 编码字符串,不能超过 10MB,分辨率不低于 300*300 像素,宽高比在 1:2.5 ~ 2.5:1 之间。Base64 不应包含 data:image 前缀。" - } - }, - "outputs": { - "0": { - "tooltip": null - }, - "1": { - "name": "视频ID", - "tooltip": null - }, - "2": { - "name": "时长", - "tooltip": null - } - } - }, - "KlingCameraControlT2VNode": { - "description": "将文本转化为具有专业摄像机运动的电影级视频,模拟真实世界的电影摄影。可控制虚拟摄像机的动作,包括缩放、旋转、平移、俯仰和第一人称视角,同时保持对原始文本的聚焦。", - "display_name": "Kling 文本转视频(摄像机控制)", - "inputs": { - "aspect_ratio": { - "name": "宽高比" - }, - "camera_control": { - "name": "镜头控制", - "tooltip": "可通过 Kling Camera Controls 节点创建。控制视频生成过程中的摄像机运动和移动。" - }, - "cfg_scale": { - "name": "CFG" - }, - "negative_prompt": { - "name": "负面提示词", - "tooltip": "反向文本提示" - }, - "prompt": { - "name": "提示词", - "tooltip": "正向文本提示" } }, "outputs": { @@ -3976,8 +4437,8 @@ } }, "KlingCameraControls": { - "description": "允许指定 Kling 相机控制和运动控制效果的配置选项。", "display_name": "Kling 相机控制", + "description": "允许指定 Kling 相机控制和运动控制效果的配置选项。", "inputs": { "camera_control_type": { "name": "镜头类型" @@ -3986,21 +4447,21 @@ "name": "水平移动", "tooltip": "控制相机在水平轴(x 轴)上的移动。负值表示向左,正值表示向右。" }, + "vertical_movement": { + "name": "垂直移动", + "tooltip": "控制相机在垂直轴(y 轴)上的移动。负值表示向下,正值表示向上。" + }, "pan": { "name": "垂直旋转", "tooltip": "控制相机在垂直平面(x 轴)上的旋转。负值表示向下旋转,正值表示向上旋转。" }, - "roll": { - "name": "滚转", - "tooltip": "控制相机的滚转量(z 轴)。负值表示逆时针,正值表示顺时针。" - }, "tilt": { "name": "水平旋转", "tooltip": "控制相机在水平平面(y 轴)上的旋转。负值表示向左旋转,正值表示向右旋转。" }, - "vertical_movement": { - "name": "垂直移动", - "tooltip": "控制相机在垂直轴(y 轴)上的移动。负值表示向下,正值表示向上。" + "roll": { + "name": "滚转", + "tooltip": "控制相机的滚转量(z 轴)。负值表示逆时针,正值表示顺时针。" }, "zoom": { "name": "变焦", @@ -4014,16 +4475,47 @@ } } }, + "KlingCameraControlT2VNode": { + "display_name": "Kling 文本转视频(摄像机控制)", + "description": "将文本转化为具有专业摄像机运动的电影级视频,模拟真实世界的电影摄影。可控制虚拟摄像机的动作,包括缩放、旋转、平移、俯仰和第一人称视角,同时保持对原始文本的聚焦。", + "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "正向文本提示" + }, + "negative_prompt": { + "name": "负面提示词", + "tooltip": "反向文本提示" + }, + "cfg_scale": { + "name": "CFG" + }, + "aspect_ratio": { + "name": "宽高比" + }, + "camera_control": { + "name": "镜头控制", + "tooltip": "可通过 Kling Camera Controls 节点创建。控制视频生成过程中的摄像机运动和移动。" + } + }, + "outputs": { + "0": { + "tooltip": null + }, + "1": { + "name": "视频ID", + "tooltip": null + }, + "2": { + "name": "时长", + "tooltip": null + } + } + }, "KlingDualCharacterVideoEffectNode": { "display_name": "Kling 双角色视频特效", "description": "根据 效果 在生成视频时实现不同的特效。第一张图片将被放置在合成画面的左侧,第二张图片在右侧。", "inputs": { - "duration": { - "name": "时长" - }, - "effect_scene": { - "name": "效果" - }, "image_left": { "name": "左侧图像", "tooltip": "左侧图片" @@ -4032,11 +4524,17 @@ "name": "右侧图像", "tooltip": "右侧图片" }, - "mode": { - "name": "模式" + "effect_scene": { + "name": "效果" }, "model_name": { "name": "模型" + }, + "mode": { + "name": "模式" + }, + "duration": { + "name": "时长" } }, "outputs": { @@ -4052,32 +4550,32 @@ "KlingImage2VideoNode": { "display_name": "Kling 图像转视频", "inputs": { - "aspect_ratio": { - "name": "宽高比" - }, - "cfg_scale": { - "name": "CFG" - }, - "duration": { - "name": "时长" - }, - "mode": { - "name": "模式" - }, - "model_name": { - "name": "模型" - }, - "negative_prompt": { - "name": "负面提示词", - "tooltip": "反向文本提示" + "start_frame": { + "name": "起始帧", + "tooltip": "参考图像 - URL 或 Base64 编码字符串,不能超过 10MB,分辨率不少于 300*300 像素,宽高比在 1:2.5 ~ 2.5:1 之间。Base64 不应包含 data:image 前缀。" }, "prompt": { "name": "提示词", "tooltip": "正向文本提示" }, - "start_frame": { - "name": "起始帧", - "tooltip": "参考图像 - URL 或 Base64 编码字符串,不能超过 10MB,分辨率不少于 300*300 像素,宽高比在 1:2.5 ~ 2.5:1 之间。Base64 不应包含 data:image 前缀。" + "negative_prompt": { + "name": "负面提示词", + "tooltip": "反向文本提示" + }, + "model_name": { + "name": "模型" + }, + "cfg_scale": { + "name": "CFG" + }, + "mode": { + "name": "模式" + }, + "aspect_ratio": { + "name": "宽高比" + }, + "duration": { + "name": "时长" } }, "outputs": { @@ -4095,40 +4593,69 @@ } }, "KlingImageGenerationNode": { - "description": "Kling 图像生成节点。通过文本提示生成图像,可选参考图像。", "display_name": "Kling 图像生成", + "description": "Kling 图像生成节点。通过文本提示生成图像,可选参考图像。", "inputs": { - "aspect_ratio": { - "name": "宽高比" - }, - "human_fidelity": { - "name": "主体参考强度", - "tooltip": "主体参考相似度" - }, - "image": { - "name": "图像" - }, - "image_fidelity": { - "name": "图像参考强度", - "tooltip": "用户上传图像的参考强度" - }, - "image_type": { - "name": "图像类型" - }, - "model_name": { - "name": "模型" - }, - "n": { - "name": "图像数量", - "tooltip": "生成图像数量" + "prompt": { + "name": "提示词", + "tooltip": "正向文本提示" }, "negative_prompt": { "name": "负面提示词", "tooltip": "反向文本提示" }, + "image_type": { + "name": "图像类型" + }, + "image_fidelity": { + "name": "图像参考强度", + "tooltip": "用户上传图像的参考强度" + }, + "human_fidelity": { + "name": "主体参考强度", + "tooltip": "主体参考相似度" + }, + "model_name": { + "name": "模型" + }, + "aspect_ratio": { + "name": "宽高比" + }, + "n": { + "name": "图像数量", + "tooltip": "生成图像数量" + }, + "image": { + "name": "图像" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "KlingImageToVideoWithAudio": { + "display_name": "Kling 图像到视频音频", + "inputs": { + "model_name": { + "name": "模型" + }, + "start_frame": { + "name": "起始帧" + }, "prompt": { "name": "提示词", - "tooltip": "正向文本提示" + "tooltip": "正面文本提示词。" + }, + "mode": { + "name": "模式" + }, + "duration": { + "name": "时长(秒)" + }, + "generate_audio": { + "name": "生成音频" } }, "outputs": { @@ -4138,15 +4665,15 @@ } }, "KlingLipSyncAudioToVideoNode": { - "description": "Kling 音频驱动视频口型同步节点。将视频文件中的嘴部动作与音频文件的音频内容进行同步。", "display_name": "Kling 音频驱动视频口型同步", + "description": "Kling 音频驱动视频口型同步节点。将视频文件中的嘴部动作与音频文件的音频内容进行同步。", "inputs": { - "audio": { - "name": "音频" - }, "video": { "name": "视频" }, + "audio": { + "name": "音频" + }, "voice_language": { "name": "语音语言" } @@ -4166,16 +4693,16 @@ } }, "KlingLipSyncTextToVideoNode": { - "description": "Kling 文字驱动口型同步节点。将视频文件中的嘴部动作与文本提示同步。", "display_name": "Kling 文字驱动口型同步视频", + "description": "Kling 文字驱动口型同步节点。将视频文件中的嘴部动作与文本提示同步。", "inputs": { + "video": { + "name": "视频" + }, "text": { "name": "文本", "tooltip": "用于口型同步视频生成的文本内容。当模式为 text2video 时必填。最大长度为 120 个字符。" }, - "video": { - "name": "视频" - }, "voice": { "name": "语音" }, @@ -4198,22 +4725,228 @@ } } }, - "KlingSingleImageVideoEffectNode": { - "description": "根据 效果 在生成视频时实现不同的特效。", - "display_name": "Kling 视频特效", + "KlingMotionControl": { + "display_name": "Kling 动作控制", "inputs": { + "prompt": { + "name": "提示词" + }, + "reference_image": { + "name": "参考图像" + }, + "reference_video": { + "name": "参考视频", + "tooltip": "动作或表情的参考视频。\n持续时间取决于参考类型:\n图像:3-10 秒\n视频:3-30 秒" + }, + "keep_original_sound": { + "name": "保留原音频" + }, + "character_orientation": { + "name": "参考方向", + "tooltip": "控制角色的朝向/方向。\nv视频:动作,表情,相机移动和方向遵循运动参考视频(其他细节通过提示)。\n图像:运动和表情仍然遵循运动参考视频,但角色方向匹配参考图像(通过提示相机/其他细节)" + }, + "mode": { + "name": "模式" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "KlingOmniProEditVideoNode": { + "display_name": "Kling Omni 编辑视频 (Pro)", + "description": "使用 Kling 最新模型编辑视频。", + "inputs": { + "model_name": { + "name": "模型" + }, + "prompt": { + "name": "提示词", + "tooltip": "描述视频内容的文本提示词。可以同时包括正面负面描述。" + }, + "video": { + "name": "视频", + "tooltip": "需要编辑的视频,输出视频的时长和输入视频相同。" + }, + "keep_original_sound": { + "name": "保留原音频" + }, + "reference_images": { + "name": "参考图像", + "tooltip": "最多 4 个参考图像" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "KlingOmniProFirstLastFrameNode": { + "display_name": "Kling Omni 首尾帧到视频 (Pro)", + "description": "使用 Kling 最新模型和起始帧、可选的结束帧或参考图像。", + "inputs": { + "model_name": { + "name": "模型" + }, + "prompt": { + "name": "提示词", + "tooltip": "描述视频内容的文本提示词。可以同时包括正面负面描述。" + }, "duration": { "name": "时长" }, - "effect_scene": { - "name": "效果" + "first_frame": { + "name": "起始帧" }, + "end_frame": { + "name": "结束帧", + "tooltip": "可选的视频结束帧。不能和“参考图像”同时使用。" + }, + "reference_images": { + "name": "参考图像", + "tooltip": "最多 6 个参考图像" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "KlingOmniProImageNode": { + "display_name": "Kling Omni 图像 (Pro)", + "description": "使用 Kling 最新模型生成或编辑图像。", + "inputs": { + "model_name": { + "name": "模型" + }, + "prompt": { + "name": "提示词", + "tooltip": "描述图像内容的文本提示词。可以同时包括正面负面描述。" + }, + "resolution": { + "name": "分辨率" + }, + "aspect_ratio": { + "name": "宽高比" + }, + "reference_images": { + "name": "参考图像", + "tooltip": "最多 10 个参考图像" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "KlingOmniProImageToVideoNode": { + "display_name": "Kling Omni 图像到视频 (Pro)", + "description": "使用 Kling 最新模型基于最多 7 个参考图生成视频。", + "inputs": { + "model_name": { + "name": "模型" + }, + "prompt": { + "name": "提示词", + "tooltip": "描述图像内容的文本提示词。可以同时包括正面负面描述。" + }, + "aspect_ratio": { + "name": "宽高比" + }, + "duration": { + "name": "时长" + }, + "reference_images": { + "name": "参考图像", + "tooltip": "最多 7 个参考图像" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "KlingOmniProTextToVideoNode": { + "display_name": "Kling Omni 文本到视频 (Pro)", + "description": "使用 Kling 最新模型和提示词生成视频。", + "inputs": { + "model_name": { + "name": "模型" + }, + "prompt": { + "name": "提示词", + "tooltip": "描述图像内容的文本提示词。可以同时包括正面负面描述。" + }, + "aspect_ratio": { + "name": "宽高比" + }, + "duration": { + "name": "时长" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "KlingOmniProVideoToVideoNode": { + "display_name": "Kling Omni 视频到视频 (Pro)", + "description": "使用 Kling 最新模型基于最多 4 个参考图编辑视频。", + "inputs": { + "model_name": { + "name": "模型" + }, + "prompt": { + "name": "提示词", + "tooltip": "描述图像内容的文本提示词。可以同时包括正面负面描述。" + }, + "aspect_ratio": { + "name": "宽高比" + }, + "duration": { + "name": "时长" + }, + "reference_video": { + "name": "参考视频", + "tooltip": "用于参考的视频。" + }, + "keep_original_sound": { + "name": "保留原音频" + }, + "reference_images": { + "name": "参考图像", + "tooltip": "最多 4 个参考图像" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "KlingSingleImageVideoEffectNode": { + "display_name": "Kling 视频特效", + "description": "根据 效果 在生成视频时实现不同的特效。", + "inputs": { "image": { "name": "图像3", "tooltip": "参考图片。URL 或 Base64 编码字符串(不含 data:image 前缀)。文件大小不得超过 10MB,分辨率不低于 300*300 像素,宽高比在 1:2.5 ~ 2.5:1 之间。" }, + "effect_scene": { + "name": "效果" + }, "model_name": { "name": "模型" + }, + "duration": { + "name": "时长" } }, "outputs": { @@ -4231,34 +4964,34 @@ } }, "KlingStartEndFrameNode": { - "description": "生成一个在起始图像和结束图像之间过渡的视频序列。该节点会创建所有中间帧,实现从第一帧到最后一帧的平滑变换。", "display_name": "Kling 起止帧生成视频", + "description": "生成一个在起始图像和结束图像之间过渡的视频序列。该节点会创建所有中间帧,实现从第一帧到最后一帧的平滑变换。", "inputs": { - "aspect_ratio": { - "name": "宽高比" - }, - "cfg_scale": { - "name": "CFG" + "start_frame": { + "name": "起始帧", + "tooltip": "参考图像 - URL 或 Base64 编码字符串,不能超过 10MB,分辨率不低于 300*300 像素,宽高比在 1:2.5 ~ 2.5:1 之间。Base64 不应包含 data:image 前缀。" }, "end_frame": { "name": "end_frame", "tooltip": "参考图像 - 结束帧控制。URL 或 Base64 编码字符串,不能超过 10MB,分辨率不低于 300*300 像素。Base64 不应包含 data:image 前缀。" }, - "mode": { - "name": "模式", - "tooltip": "用于视频生成的配置,格式为:mode / duration / model_name。" + "prompt": { + "name": "提示词", + "tooltip": "正向文本提示" }, "negative_prompt": { "name": "负面提示词", "tooltip": "反向文本提示" }, - "prompt": { - "name": "提示词", - "tooltip": "正向文本提示" + "cfg_scale": { + "name": "CFG" }, - "start_frame": { - "name": "起始帧", - "tooltip": "参考图像 - URL 或 Base64 编码字符串,不能超过 10MB,分辨率不低于 300*300 像素,宽高比在 1:2.5 ~ 2.5:1 之间。Base64 不应包含 data:image 前缀。" + "aspect_ratio": { + "name": "宽高比" + }, + "mode": { + "name": "模式", + "tooltip": "用于视频生成的配置,格式为:mode / duration / model_name。" } }, "outputs": { @@ -4276,26 +5009,26 @@ } }, "KlingTextToVideoNode": { - "description": "Kling 文本转视频节点", "display_name": "Kling 文本转视频", + "description": "Kling 文本转视频节点", "inputs": { - "aspect_ratio": { - "name": "宽高比" - }, - "cfg_scale": { - "name": "CFG" - }, - "mode": { - "name": "模式", - "tooltip": "用于视频生成的配置,格式为:mode / duration / model_name。" + "prompt": { + "name": "提示词", + "tooltip": "正向文本提示" }, "negative_prompt": { "name": "负面提示词", "tooltip": "反向文本提示" }, - "prompt": { - "name": "提示词", - "tooltip": "正向文本提示" + "cfg_scale": { + "name": "CFG" + }, + "aspect_ratio": { + "name": "宽高比" + }, + "mode": { + "name": "模式", + "tooltip": "用于视频生成的配置,格式为:mode / duration / model_name。" } }, "outputs": { @@ -4312,20 +5045,49 @@ } } }, - "KlingVideoExtendNode": { - "description": "Kling 视频扩展节点。扩展由其他 Kling 节点生成的视频。video_id 由其他 Kling 节点生成。", - "display_name": "Kling 视频扩展", + "KlingTextToVideoWithAudio": { + "display_name": "Kling 文本到视频音频", "inputs": { - "cfg_scale": { - "name": "CFG" + "model_name": { + "name": "模型" + }, + "prompt": { + "name": "提示词", + "tooltip": "正面文本提示词。" + }, + "mode": { + "name": "模式" + }, + "aspect_ratio": { + "name": "宽高比" + }, + "duration": { + "name": "时长" + }, + "generate_audio": { + "name": "生成音频" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "KlingVideoExtendNode": { + "display_name": "Kling 视频扩展", + "description": "Kling 视频扩展节点。扩展由其他 Kling 节点生成的视频。video_id 由其他 Kling 节点生成。", + "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "用于引导视频扩展的正向文本提示" }, "negative_prompt": { "name": "负面提示词", "tooltip": "用于在扩展视频中避免出现的元素的负向文本提示" }, - "prompt": { - "name": "提示词", - "tooltip": "用于引导视频扩展的正向文本提示" + "cfg_scale": { + "name": "CFG" }, "video_id": { "name": "视频ID", @@ -4347,15 +5109,15 @@ } }, "KlingVirtualTryOnNode": { - "description": "Kling 虚拟试穿节点。输入一张人物图片和一张服装图片,将服装试穿到人物身上。", "display_name": "Kling 虚拟试穿", + "description": "Kling 虚拟试穿节点。输入一张人物图片和一张服装图片,将服装试穿到人物身上。", "inputs": { - "cloth_image": { - "name": "服装" - }, "human_image": { "name": "主体" }, + "cloth_image": { + "name": "服装" + }, "model_name": { "name": "模型" } @@ -4366,186 +5128,112 @@ } } }, - "LTXVAddGuide": { - "display_name": "LTXV添加指导", + "KSampler": { + "display_name": "K采样器", + "description": "使用提供的模型、正面条件和负面条件条件降噪Latent图像。", "inputs": { - "frame_idx": { - "name": "帧索引", - "tooltip": "开始调节的帧索引。对于单帧图像或1-8帧的视频,任何帧索引值都可以接受。对于9+帧的视频,帧索引必须能被8整除,否则它将被向下取整到最接近的8的倍数。负值从视频的末尾开始计算。" + "model": { + "name": "模型", + "tooltip": "用于降噪输入 Latent 图像的模型。" }, - "image": { - "name": "图像", - "tooltip": "用于调节潜在视频的图像或视频。必须是8*n + 1帧。如果视频不是8*n + 1帧,它将被裁剪到最接近的8*n + 1帧。" + "seed": { + "name": "种子", + "tooltip": "生成噪波的随机种。" }, - "latent": { - "name": "潜在空间" + "steps": { + "name": "步数", + "tooltip": "降噪的步数。" }, - "negative": { - "name": "负向" + "cfg": { + "name": "cfg", + "tooltip": "用于平衡随机性和提示词服从性。提高该值会使结果更加符合提示词,但过高会导致图像质量下降。" + }, + "sampler_name": { + "name": "采样器名称", + "tooltip": "采样算法,会影响结果质量、生成速度、风格样式。" + }, + "scheduler": { + "name": "调度器", + "tooltip": "控制逐渐移除噪波的方法。" }, "positive": { - "name": "正向" - }, - "strength": { - "name": "强度" - }, - "vae": { - "name": "vae" - } - }, - "outputs": { - "0": { - "name": "正向", - "tooltip": null - }, - "1": { - "name": "负向", - "tooltip": null - }, - "2": { - "name": "潜在空间", - "tooltip": null - } - } - }, - "LTXVConditioning": { - "display_name": "LTXV条件", - "inputs": { - "frame_rate": { - "name": "帧率" - }, - "negative": { - "name": "负面条件" - }, - "positive": { - "name": "正面条件" - } - }, - "outputs": { - "0": { "name": "正面条件", - "tooltip": null - }, - "1": { - "name": "负面条件", - "tooltip": null - } - } - }, - "LTXVCropGuides": { - "display_name": "LTXV裁剪指导", - "inputs": { - "latent": { - "name": "潜在空间" + "tooltip": "描述包含在图像中的内容的条件。" }, "negative": { - "name": "负向" - }, - "positive": { - "name": "正向" - } - }, - "outputs": { - "0": { - "name": "正向", - "tooltip": null - }, - "1": { - "name": "负向", - "tooltip": null - }, - "2": { - "name": "潜在空间", - "tooltip": null - } - } - }, - "LTXVImgToVideo": { - "display_name": "LTXV图像到视频", - "inputs": { - "batch_size": { - "name": "批量大小" - }, - "height": { - "name": "高度" - }, - "image": { - "name": "图像" - }, - "length": { - "name": "长度" - }, - "negative": { - "name": "负面条件" - }, - "positive": { - "name": "正面条件" - }, - "strength": { - "name": "强度" - }, - "vae": { - "name": "vae" - }, - "width": { - "name": "宽度" - } - }, - "outputs": { - "0": { - "name": "正面条件", - "tooltip": null - }, - "1": { "name": "负面条件", - "tooltip": null + "tooltip": "描述不包含在图像中的内容的条件。" }, - "2": { - "name": "Latent", - "tooltip": null - } - } - }, - "LTXVPreprocess": { - "display_name": "LTXV预处理", - "inputs": { - "image": { - "name": "图像" + "latent_image": { + "name": "Latent图像", + "tooltip": "要降噪的 Latent 图像。" }, - "img_compression": { - "name": "图像压缩", - "tooltip": "应用于图像的压缩量。" + "denoise": { + "name": "降噪", + "tooltip": "降噪的强度,降低该值会保留原图的大部分内容从而实现图生图。" + }, + "control_after_generate": { + "name": "生成后的控制" } }, "outputs": { "0": { - "name": "输出图像", - "tooltip": null + "tooltip": "降噪后的 Latent。" } } }, - "LTXVScheduler": { - "display_name": "LTXV调度器", + "KSamplerAdvanced": { + "display_name": "K采样器(高级)", "inputs": { - "base_shift": { - "name": "基础移位" + "model": { + "name": "模型" }, - "latent": { - "name": "Latent" + "add_noise": { + "name": "添加噪波" }, - "max_shift": { - "name": "最大移位" + "noise_seed": { + "name": "随机种" }, "steps": { "name": "步数" }, - "stretch": { - "name": "拉伸", - "tooltip": "将 sigma 拉伸到范围 [终值, 1]。" + "cfg": { + "name": "cfg" }, - "terminal": { - "name": "终值", - "tooltip": "拉伸后 sigma 的终值。" + "sampler_name": { + "name": "采样器名称" + }, + "scheduler": { + "name": "调度器" + }, + "positive": { + "name": "正面条件" + }, + "negative": { + "name": "负面条件" + }, + "latent_image": { + "name": "Latent图像" + }, + "start_at_step": { + "name": "开始步数" + }, + "end_at_step": { + "name": "结束步数" + }, + "return_with_leftover_noise": { + "name": "返回剩余噪波" + }, + "control_after_generate": { + "name": "生成后的控制" + } + } + }, + "KSamplerSelect": { + "display_name": "K采样器选择", + "inputs": { + "sampler_name": { + "name": "采样器名称" } }, "outputs": { @@ -4557,11 +5245,8 @@ "LaplaceScheduler": { "display_name": "Laplace调度器", "inputs": { - "beta": { - "name": "beta" - }, - "mu": { - "name": "mu" + "steps": { + "name": "步数" }, "sigma_max": { "name": "sigma_max" @@ -4569,8 +5254,16 @@ "sigma_min": { "name": "sigma_min" }, - "steps": { - "name": "步数" + "mu": { + "name": "mu" + }, + "beta": { + "name": "beta" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, @@ -4593,11 +5286,11 @@ "LatentApplyOperation": { "display_name": "Latent应用操作", "inputs": { - "operation": { - "name": "操作" - }, "samples": { "name": "Latent" + }, + "operation": { + "name": "操作" } }, "outputs": { @@ -4657,34 +5350,34 @@ "LatentBlend": { "display_name": "混合Latent", "inputs": { - "blend_factor": { - "name": "系数" - }, "samples1": { "name": "Latent1" }, "samples2": { "name": "Latent2" + }, + "blend_factor": { + "name": "系数" } } }, "LatentComposite": { "display_name": "合成Latent", "inputs": { - "feather": { - "name": "羽化" + "samples_to": { + "name": "Latent到" }, "samples_from": { "name": "Latent从" }, - "samples_to": { - "name": "Latent到" - }, "x": { "name": "x" }, "y": { "name": "y" + }, + "feather": { + "name": "羽化" } } }, @@ -4694,12 +5387,6 @@ "destination": { "name": "目标Latent" }, - "mask": { - "name": "遮罩" - }, - "resize_source": { - "name": "调整来源大小" - }, "source": { "name": "来源Latent" }, @@ -4708,20 +5395,31 @@ }, "y": { "name": "y" + }, + "resize_source": { + "name": "调整来源大小" + }, + "mask": { + "name": "遮罩" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "LatentConcat": { "display_name": "潜在空间拼接", "inputs": { - "dim": { - "name": "维度" - }, "samples1": { "name": "样本1" }, "samples2": { "name": "样本2" + }, + "dim": { + "name": "维度" } }, "outputs": { @@ -4733,15 +5431,15 @@ "LatentCrop": { "display_name": "裁剪Latent", "inputs": { - "height": { - "name": "高度" - }, "samples": { "name": "Latent" }, "width": { "name": "宽度" }, + "height": { + "name": "高度" + }, "x": { "name": "x" }, @@ -4753,8 +5451,8 @@ "LatentCut": { "display_name": "潜在空间切割", "inputs": { - "amount": { - "name": "数量" + "samples": { + "name": "样本" }, "dim": { "name": "维度" @@ -4762,8 +5460,27 @@ "index": { "name": "索引" }, + "amount": { + "name": "数量" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "LatentCutToBatch": { + "display_name": "Latent切割", + "inputs": { "samples": { - "name": "样本" + "name": "Latent" + }, + "dim": { + "name": "维度" + }, + "slice_size": { + "name": "碎片大小" } }, "outputs": { @@ -4775,39 +5492,39 @@ "LatentFlip": { "display_name": "翻转Latent", "inputs": { - "flip_method": { - "name": "翻转方法" - }, "samples": { "name": "Latent" + }, + "flip_method": { + "name": "翻转方法" } } }, "LatentFromBatch": { "display_name": "从批次获取Latent", "inputs": { + "samples": { + "name": "Latent" + }, "batch_index": { "name": "批次索引" }, "length": { "name": "长度" - }, - "samples": { - "name": "Latent" } } }, "LatentInterpolate": { "display_name": "Latent插值", "inputs": { - "ratio": { - "name": "比率" - }, "samples1": { "name": "Latent1" }, "samples2": { "name": "Latent2" + }, + "ratio": { + "name": "比率" } }, "outputs": { @@ -4819,11 +5536,11 @@ "LatentMultiply": { "display_name": "Latent相乘", "inputs": { - "multiplier": { - "name": "乘数" - }, "samples": { "name": "Latent" + }, + "multiplier": { + "name": "乘数" } }, "outputs": { @@ -4835,14 +5552,14 @@ "LatentOperationSharpen": { "display_name": "Latent操作锐化", "inputs": { - "alpha": { - "name": "阿尔法" - }, "sharpen_radius": { "name": "锐化半径" }, "sigma": { "name": "西格玛" + }, + "alpha": { + "name": "阿尔法" } }, "outputs": { @@ -4867,11 +5584,11 @@ "LatentRotate": { "display_name": "旋转Latent", "inputs": { - "rotation": { - "name": "旋转" - }, "samples": { "name": "Latent" + }, + "rotation": { + "name": "旋转" } } }, @@ -4894,12 +5611,6 @@ "LatentUpscale": { "display_name": "缩放Latent", "inputs": { - "crop": { - "name": "裁剪" - }, - "height": { - "name": "高度" - }, "samples": { "name": "Latent" }, @@ -4908,6 +5619,12 @@ }, "width": { "name": "宽度" + }, + "height": { + "name": "高度" + }, + "crop": { + "name": "裁剪" } } }, @@ -4917,11 +5634,11 @@ "samples": { "name": "Latent" }, - "scale_by": { - "name": "缩放比例" - }, "upscale_method": { "name": "缩放算法" + }, + "scale_by": { + "name": "缩放比例" } } }, @@ -4939,13 +5656,9 @@ } }, "LazyCache": { - "description": "EasyCache 的自制版本 - 更'简单'的 EasyCache 实现。总体效果不如 EasyCache,但在某些罕见情况下表现更好,并且与 ComfyUI 中的所有内容具有通用兼容性。", "display_name": "惰性缓存", + "description": "EasyCache 的自制版本 - 更'简单'的 EasyCache 实现。总体效果不如 EasyCache,但在某些罕见情况下表现更好,并且与 ComfyUI 中的所有内容具有通用兼容性。", "inputs": { - "end_percent": { - "name": "结束百分比", - "tooltip": "结束使用惰性缓存的相对采样步骤。" - }, "model": { "name": "模型", "tooltip": "要添加惰性缓存的模型。" @@ -4958,6 +5671,10 @@ "name": "起始百分比", "tooltip": "开始使用惰性缓存的相对采样步骤。" }, + "end_percent": { + "name": "结束百分比", + "tooltip": "结束使用惰性缓存的相对采样步骤。" + }, "verbose": { "name": "详细模式", "tooltip": "是否记录详细信息。" @@ -4972,81 +5689,46 @@ "Load3D": { "display_name": "加载3D", "inputs": { - "clear": { - }, - "height": { - "name": "高度" + "model_file": { + "name": "模型文件" }, "image": { "name": "图像" }, - "model_file": { - "name": "模型文件" - }, - "upload 3d model": { - }, "width": { "name": "宽度" - } - }, - "outputs": { - "0": { - "name": "图像" }, - "1": { - "name": "遮罩" - }, - "2": { - "name": "网格路径" - }, - "3": { - "name": "法向" - }, - "4": { - "name": "线条" - }, - "5": { - "name": "相机信息" - }, - "6": { - "name": "录制视频" - } - } - }, - "Load3DAnimation": { - "display_name": "加载3D动画", - "inputs": { "height": { "name": "高度" }, - "image": { - "name": "图像" - }, - "model_file": { - "name": "模型文件" - }, - "width": { - "name": "宽度" - } + "clear": {}, + "upload 3d model": {}, + "upload extra resources": {} }, "outputs": { "0": { - "name": "图像" + "name": "图像", + "tooltip": null }, "1": { - "name": "遮罩" + "name": "遮罩", + "tooltip": null }, "2": { - "name": "网格路径" + "name": "网格路径", + "tooltip": null }, "3": { - "name": "法线" + "name": "法向", + "tooltip": null }, "4": { - "name": "相机信息" + "name": "线条", + "tooltip": null }, "5": { - "name": "录制视频" + "name": "相机信息", + "tooltip": null } } }, @@ -5062,6 +5744,11 @@ "upload": { "name": "选择文件上传" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "LoadImage": { @@ -5075,34 +5762,68 @@ } } }, + "LoadImageDataSetFromFolder": { + "display_name": "加载图像数据集", + "inputs": { + "folder": { + "name": "文件夹", + "tooltip": "图像数据集的文件夹" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "已加载的图像序列" + } + } + }, "LoadImageMask": { "display_name": "加载图像(作为遮罩)", "inputs": { - "channel": { - "name": "通道" - }, "image": { "name": "图像" }, + "channel": { + "name": "通道" + }, "upload": { "name": "选择文件上传" } } }, "LoadImageOutput": { - "description": "从输出文件夹加载图像。当点击刷新按钮时,节点将更新图像列表并自动选择第一张图像,便于轻松迭代。", "display_name": "加载图像(来自输出)", + "description": "从输出文件夹加载图像。当点击刷新按钮时,节点将更新图像列表并自动选择第一张图像,便于轻松迭代。", "inputs": { "image": { "name": "图像" }, - "refresh": { - }, + "Auto-refresh after generation": {}, + "refresh": {}, "upload": { "name": "选择文件上传" } } }, + "LoadImageTextDataSetFromFolder": { + "display_name": "加载图像和文本数据集", + "inputs": { + "folder": { + "name": "文件夹", + "tooltip": "图像数据集的文件夹" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "已加载的图像序列" + }, + "1": { + "name": "文本", + "tooltip": "已加载的标注文本" + } + } + }, "LoadLatent": { "display_name": "加载Latent", "inputs": { @@ -5111,6 +5832,25 @@ } } }, + "LoadTrainingDataset": { + "display_name": "加载训练数据集", + "inputs": { + "folder_name": { + "name": "文件夹名", + "tooltip": "包含训练数据集的文件夹名(在 输出 文件夹内)。" + } + }, + "outputs": { + "0": { + "name": "Latent", + "tooltip": "Latent 列表" + }, + "1": { + "name": "条件", + "tooltip": "条件列表" + } + } + }, "LoadVideo": { "display_name": "加载视频", "inputs": { @@ -5128,9 +5868,13 @@ } }, "LoraLoader": { - "description": "LoRA用于修改扩散和CLIP模型,改变Latent图像的降噪方式,例如应用风格。多个LoRA节点可以链接在一起。", "display_name": "加载LoRA", + "description": "LoRA用于修改扩散和CLIP模型,改变Latent图像的降噪方式,例如应用风格。多个LoRA节点可以链接在一起。", "inputs": { + "model": { + "name": "模型", + "tooltip": "LoRA 将应用于的扩散模型。" + }, "clip": { "name": "CLIP", "tooltip": "LoRA 将应用于的 CLIP 模型。" @@ -5139,17 +5883,13 @@ "name": "LoRA名称", "tooltip": "LoRA 的名称。" }, - "model": { - "name": "模型", - "tooltip": "LoRA 将应用于的扩散模型。" + "strength_model": { + "name": "模型强度", + "tooltip": "修改扩散模型的强度。此值可以为负。" }, "strength_clip": { "name": "CLIP强度", "tooltip": "修改 CLIP 模型的强度。此值可以为负。" - }, - "strength_model": { - "name": "模型强度", - "tooltip": "修改扩散模型的强度。此值可以为负。" } }, "outputs": { @@ -5162,15 +5902,15 @@ } }, "LoraLoaderModelOnly": { - "description": "LoRA用于修改扩散和CLIP模型,改变Latent图像的降噪方式,例如应用风格。多个LoRA节点可以链接在一起。", "display_name": "LoRA加载器(仅模型)", + "description": "LoRA用于修改扩散和CLIP模型,改变Latent图像的降噪方式,例如应用风格。多个LoRA节点可以链接在一起。", "inputs": { - "lora_name": { - "name": "LoRA名称" - }, "model": { "name": "模型" }, + "lora_name": { + "name": "LoRA名称" + }, "strength_model": { "name": "模型强度" } @@ -5184,14 +5924,14 @@ "LoraModelLoader": { "display_name": "加载 LoRA 模型", "inputs": { - "lora": { - "name": "lora", - "tooltip": "要应用于扩散模型的 LoRA 模型。" - }, "model": { "name": "模型", "tooltip": "LoRA 将应用于的扩散模型。" }, + "lora": { + "name": "lora", + "tooltip": "要应用于扩散模型的 LoRA 模型。" + }, "strength_model": { "name": "模型强度", "tooltip": "修改扩散模型的强度。此值可以为负数。" @@ -5199,6 +5939,7 @@ }, "outputs": { "0": { + "name": "模型", "tooltip": "修改后的扩散模型。" } } @@ -5206,22 +5947,22 @@ "LoraSave": { "display_name": "保存LoRA", "inputs": { - "bias_diff": { - "name": "偏差差异" - }, "filename_prefix": { "name": "文件名前缀" }, + "rank": { + "name": "排名" + }, "lora_type": { "name": "lora类型" }, + "bias_diff": { + "name": "偏差差异" + }, "model_diff": { "name": "模型差异", "tooltip": "要转换为 LoRA 的模型差异输出。" }, - "rank": { - "name": "排名" - }, "text_encoder_diff": { "name": "文本编码器差异", "tooltip": "要转换为 LoRA 的CLIP差异输出。" @@ -5231,11 +5972,13 @@ "LossGraphNode": { "display_name": "绘制损失图", "inputs": { - "filename_prefix": { - "name": "文件名前缀" - }, "loss": { - "name": "损失" + "name": "损失", + "tooltip": "训练节点的损失图" + }, + "filename_prefix": { + "name": "文件名前缀", + "tooltip": "保存损失图的文件名前缀" } } }, @@ -5248,20 +5991,52 @@ } } }, - "LtxvApiImageToVideo": { - "description": "基于起始图像生成专业品质视频,可自定义时长和分辨率。", - "display_name": "LTXV 图像转视频", + "LTXVAddGuide": { + "display_name": "LTXV添加指导", "inputs": { - "duration": { - "name": "时长" + "positive": { + "name": "正向" }, - "fps": { - "name": "帧率" + "negative": { + "name": "负向" }, - "generate_audio": { - "name": "生成音频", - "tooltip": "为 true 时,生成的视频将包含与场景匹配的 AI 生成音频。" + "vae": { + "name": "vae" }, + "latent": { + "name": "潜在空间" + }, + "image": { + "name": "图像", + "tooltip": "用于调节潜在视频的图像或视频。必须是8*n + 1帧。如果视频不是8*n + 1帧,它将被裁剪到最接近的8*n + 1帧。" + }, + "frame_idx": { + "name": "帧索引", + "tooltip": "开始调节的帧索引。对于单帧图像或1-8帧的视频,任何帧索引值都可以接受。对于9+帧的视频,帧索引必须能被8整除,否则它将被向下取整到最接近的8的倍数。负值从视频的末尾开始计算。" + }, + "strength": { + "name": "强度" + } + }, + "outputs": { + "0": { + "name": "正向", + "tooltip": null + }, + "1": { + "name": "负向", + "tooltip": null + }, + "2": { + "name": "潜在空间", + "tooltip": null + } + } + }, + "LtxvApiImageToVideo": { + "display_name": "LTXV 图像到视频", + "description": "基于起始图像生成专业品质视频,可自定义时长和分辨率。", + "inputs": { "image": { "name": "图像", "tooltip": "用于视频的第一帧图像。" @@ -5272,8 +6047,18 @@ "prompt": { "name": "提示词" }, + "duration": { + "name": "时长" + }, "resolution": { "name": "分辨率" + }, + "fps": { + "name": "帧率" + }, + "generate_audio": { + "name": "生成音频", + "tooltip": "为 true 时,生成的视频将包含与场景匹配的 AI 生成音频。" } }, "outputs": { @@ -5283,27 +6068,173 @@ } }, "LtxvApiTextToVideo": { + "display_name": "LTXV 文本到视频", "description": "可自定义时长和分辨率的专业品质视频。", - "display_name": "LTXV 文本转视频", "inputs": { - "duration": { - "name": "时长" - }, - "fps": { - "name": "帧率" - }, - "generate_audio": { - "name": "生成音频", - "tooltip": "为 true 时,生成的视频将包含与场景匹配的 AI 生成音频。" - }, "model": { "name": "模型" }, "prompt": { "name": "提示词" }, + "duration": { + "name": "时长" + }, "resolution": { "name": "分辨率" + }, + "fps": { + "name": "帧率" + }, + "generate_audio": { + "name": "生成音频", + "tooltip": "生成的视频将包含与场景匹配的 AI 生成音频。" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "LTXVConditioning": { + "display_name": "LTXV条件", + "inputs": { + "positive": { + "name": "正面条件" + }, + "negative": { + "name": "负面条件" + }, + "frame_rate": { + "name": "帧率" + } + }, + "outputs": { + "0": { + "name": "正面条件", + "tooltip": null + }, + "1": { + "name": "负面条件", + "tooltip": null + } + } + }, + "LTXVCropGuides": { + "display_name": "LTXV裁剪指导", + "inputs": { + "positive": { + "name": "正向" + }, + "negative": { + "name": "负向" + }, + "latent": { + "name": "潜在空间" + } + }, + "outputs": { + "0": { + "name": "正向", + "tooltip": null + }, + "1": { + "name": "负向", + "tooltip": null + }, + "2": { + "name": "潜在空间", + "tooltip": null + } + } + }, + "LTXVImgToVideo": { + "display_name": "图像到视频(LTXV)", + "inputs": { + "positive": { + "name": "正面条件" + }, + "negative": { + "name": "负面条件" + }, + "vae": { + "name": "vae" + }, + "image": { + "name": "图像" + }, + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" + }, + "length": { + "name": "长度" + }, + "batch_size": { + "name": "批量大小" + }, + "strength": { + "name": "强度" + } + }, + "outputs": { + "0": { + "name": "正面条件", + "tooltip": null + }, + "1": { + "name": "负面条件", + "tooltip": null + }, + "2": { + "name": "Latent", + "tooltip": null + } + } + }, + "LTXVPreprocess": { + "display_name": "LTXV预处理", + "inputs": { + "image": { + "name": "图像" + }, + "img_compression": { + "name": "图像压缩", + "tooltip": "应用于图像的压缩量。" + } + }, + "outputs": { + "0": { + "name": "输出图像", + "tooltip": null + } + } + }, + "LTXVScheduler": { + "display_name": "LTXV调度器", + "inputs": { + "steps": { + "name": "步数" + }, + "max_shift": { + "name": "最大移位" + }, + "base_shift": { + "name": "基础移位" + }, + "stretch": { + "name": "拉伸", + "tooltip": "将 sigma 拉伸到范围 [终值, 1]。" + }, + "terminal": { + "name": "终值", + "tooltip": "拉伸后 sigma 的终值。" + }, + "latent": { + "name": "Latent" } }, "outputs": { @@ -5313,8 +6244,8 @@ } }, "LumaConceptsNode": { - "description": "包含一个或多个相机概念,可用于 Luma 文本转视频和 Luma 图像转视频节点。", "display_name": "Luma 概念", + "description": "包含一个或多个相机概念,可用于 Luma 文本转视频和 Luma 图像转视频节点。", "inputs": { "concept1": { "name": "概念1" @@ -5341,15 +6272,16 @@ } }, "LumaImageModifyNode": { - "description": "根据提示词和宽高比同步修改图像。", "display_name": "Luma 图像到图像", + "description": "根据提示词和宽高比同步修改图像。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, "image": { "name": "图像" }, + "prompt": { + "name": "提示词", + "tooltip": "用于图像生成的提示词" + }, "image_weight": { "name": "图像权重", "tooltip": "图像权重;越接近 1.0,图像被修改的程度越小。" @@ -5357,13 +6289,12 @@ "model": { "name": "模型" }, - "prompt": { - "name": "提示词", - "tooltip": "用于图像生成的提示词" - }, "seed": { "name": "随机种", "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -5373,41 +6304,41 @@ } }, "LumaImageNode": { - "description": "根据提示词和宽高比同步生成图像。", "display_name": "Luma 文生图", + "description": "根据提示词和宽高比同步生成图像。", "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "用于图像生成的提示词" + }, + "model": { + "name": "模型" + }, "aspect_ratio": { "name": "宽高比" }, + "seed": { + "name": "种子", + "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" + }, + "style_image_weight": { + "name": "风格图权重", + "tooltip": "风格图像的权重。如果未提供风格图像则忽略。" + }, + "image_luma_ref": { + "name": "Luma 参考图", + "tooltip": "Luma 参考节点连接,可用输入图像影响生成;最多可考虑 4 张图像。" + }, + "style_image": { + "name": "风格参考图", + "tooltip": "风格参考图像;仅使用 1 张图像。" + }, "character_image": { "name": "角色参考图", "tooltip": "角色参考图像;可为多张批量输入,最多可考虑 4 张图像。" }, "control_after_generate": { "name": "生成后控制" - }, - "image_luma_ref": { - "name": "Luma 参考图", - "tooltip": "Luma 参考节点连接,可用输入图像影响生成;最多可考虑 4 张图像。" - }, - "model": { - "name": "模型" - }, - "prompt": { - "name": "提示词", - "tooltip": "用于图像生成的提示词" - }, - "seed": { - "name": "种子", - "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" - }, - "style_image": { - "name": "风格参考图", - "tooltip": "风格参考图像;仅使用 1 张图像。" - }, - "style_image_weight": { - "name": "风格图权重", - "tooltip": "风格图像的权重。如果未提供风格图像则忽略。" } }, "outputs": { @@ -5417,15 +6348,29 @@ } }, "LumaImageToVideoNode": { - "description": "根据提示词、输入图像和输出尺寸同步生成视频。", "display_name": "Luma 图像转视频", + "description": "根据提示词、输入图像和输出尺寸同步生成视频。", "inputs": { - "control_after_generate": { - "name": "生成后控制" + "prompt": { + "name": "提示词", + "tooltip": "用于视频生成的提示词" + }, + "model": { + "name": "模型" + }, + "resolution": { + "name": "分辨率" }, "duration": { "name": "时长" }, + "loop": { + "name": "循环" + }, + "seed": { + "name": "种子", + "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" + }, "first_image": { "name": "首帧图像", "tooltip": "生成视频的第一帧。" @@ -5434,26 +6379,12 @@ "name": "末帧图像", "tooltip": "生成视频的最后一帧。" }, - "loop": { - "name": "循环" - }, "luma_concepts": { "name": "Luma概念", "tooltip": "可选的 Camera Concepts,通过 Luma Concepts 节点控制相机运动。" }, - "model": { - "name": "模型" - }, - "prompt": { - "name": "提示词", - "tooltip": "用于视频生成的提示词" - }, - "resolution": { - "name": "分辨率" - }, - "seed": { - "name": "种子", - "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -5463,19 +6394,19 @@ } }, "LumaReferenceNode": { - "description": "用于 Luma 生成图像节点,包含一张图片和权重。", "display_name": "Luma 参考", + "description": "用于 Luma 生成图像节点,包含一张图片和权重。", "inputs": { "image": { "name": "图片", "tooltip": "用作参考的图片。" }, - "luma_ref": { - "name": "Luma参考" - }, "weight": { "name": "权重", "tooltip": "图片参考的权重。" + }, + "luma_ref": { + "name": "Luma参考" } }, "outputs": { @@ -5486,14 +6417,21 @@ } }, "LumaVideoNode": { - "description": "根据提示词和输出尺寸同步生成视频。", "display_name": "Luma 文本转视频", + "description": "根据提示词和输出尺寸同步生成视频。", "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "用于视频生成的提示词" + }, + "model": { + "name": "模型" + }, "aspect_ratio": { "name": "宽高比" }, - "control_after_generate": { - "name": "生成后控制" + "resolution": { + "name": "分辨率" }, "duration": { "name": "时长" @@ -5501,23 +6439,16 @@ "loop": { "name": "循环" }, + "seed": { + "name": "种子", + "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" + }, "luma_concepts": { "name": "Luma概念", "tooltip": "可选的相机概念,通过 Luma Concepts 节点控制相机运动。" }, - "model": { - "name": "模型" - }, - "prompt": { - "name": "提示词", - "tooltip": "用于视频生成的提示词" - }, - "resolution": { - "name": "分辨率" - }, - "seed": { - "name": "种子", - "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -5527,8 +6458,8 @@ } }, "Mahiro": { - "description": "修改引导以更多地侧重于正面条件提示的'方向',而不是负面条件提示之间的差异。", "display_name": "真寻太可爱了,她应该有个更好的引导功能!!(。・ω・。)", + "description": "修改引导以更多地侧重于正面条件提示的'方向',而不是负面条件提示之间的差异。", "inputs": { "model": { "name": "模型" @@ -5541,15 +6472,56 @@ } } }, + "MakeTrainingDataset": { + "display_name": "制作训练数据集", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要编码的图像序列。" + }, + "vae": { + "name": "VAE", + "tooltip": "用于编码图像的 VAE 模型" + }, + "clip": { + "name": "CLIP", + "tooltip": "用于编码文本的 CLIP 模型" + }, + "texts": { + "name": "文本", + "tooltip": "标注文本序列。数量可以是n(匹配图像),1(重复使用),或者省略(使用空字符串)。" + } + }, + "outputs": { + "0": { + "name": "Latent", + "tooltip": "Latent 字典序列" + }, + "1": { + "name": "条件", + "tooltip": "条件字典序列" + } + } + }, + "ManualSigmas": { + "display_name": "自定义Sigmas", + "inputs": { + "sigmas": { + "name": "sigmas" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, "MaskComposite": { "display_name": "合成遮罩", "inputs": { "destination": { "name": "目标" }, - "operation": { - "name": "操作" - }, "source": { "name": "源" }, @@ -5558,12 +6530,20 @@ }, "y": { "name": "y" + }, + "operation": { + "name": "操作" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "MaskPreview": { - "description": "将输入图像保存到您的 ComfyUI 输出目录。", "display_name": "预览遮罩", + "description": "将输入图像保存到您的 ComfyUI 输出目录。", "inputs": { "mask": { "name": "遮罩" @@ -5576,18 +6556,54 @@ "mask": { "name": "遮罩" } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "MergeImageLists": { + "display_name": "融合图像序列", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要处理的图像序列。" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "已处理的图像" + } + } + }, + "MergeTextLists": { + "display_name": "融合文本序列", + "inputs": { + "texts": { + "name": "文本", + "tooltip": "需要处理的文本序列" + } + }, + "outputs": { + "0": { + "name": "文本", + "tooltip": "已处理的文本" + } } }, "MinimaxHailuoVideoNode": { - "description": "使用新的 MiniMax Hailuo-02 模型从提示词生成视频,可选择起始帧。", "display_name": "MiniMax 海螺视频", + "description": "使用新的 MiniMax Hailuo-02 模型从提示词生成视频,可选择起始帧。", "inputs": { - "control_after_generate": { - "name": "生成后控制" + "prompt_text": { + "name": "提示文本", + "tooltip": "指导视频生成的文本提示。" }, - "duration": { - "name": "时长", - "tooltip": "输出视频的长度(秒)。" + "seed": { + "name": "种子", + "tooltip": "用于创建噪声的随机种子。" }, "first_frame_image": { "name": "第一帧图像", @@ -5597,17 +6613,16 @@ "name": "提示优化器", "tooltip": "需要时优化提示词以提高生成质量。" }, - "prompt_text": { - "name": "提示文本", - "tooltip": "指导视频生成的文本提示。" + "duration": { + "name": "时长", + "tooltip": "输出视频的长度(秒)。" }, "resolution": { "name": "分辨率", "tooltip": "视频显示的尺寸。1080p为1920x1080,768p为1366x768。" }, - "seed": { - "name": "种子", - "tooltip": "用于创建噪声的随机种子。" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -5617,27 +6632,27 @@ } }, "MinimaxImageToVideoNode": { - "description": "使用 MiniMax 的 API 根据图像和提示生成视频", "display_name": "MiniMax 图像转视频", + "description": "使用 MiniMax 的 API 根据图像和提示生成视频", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, "image": { "name": "图像", "tooltip": "用于视频生成首帧的图像" }, - "model": { - "name": "模型", - "tooltip": "用于视频生成的模型" - }, "prompt_text": { "name": "提示词", "tooltip": "用于引导视频生成的文本提示" }, + "model": { + "name": "模型", + "tooltip": "用于视频生成的模型" + }, "seed": { "name": "随机种", "tooltip": "用于生成噪声的随机种子。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -5647,23 +6662,23 @@ } }, "MinimaxTextToVideoNode": { - "description": "使用 MiniMax 的 API 根据提示生成视频", "display_name": "MiniMax 文本转视频", + "description": "使用 MiniMax 的 API 根据提示生成视频", "inputs": { - "control_after_generate": { - "name": "生成后控制" + "prompt_text": { + "name": "提示词", + "tooltip": "用于引导视频生成的文本提示" }, "model": { "name": "模型", "tooltip": "用于视频生成的模型" }, - "prompt_text": { - "name": "提示词", - "tooltip": "用于引导视频生成的文本提示" - }, "seed": { "name": "随机种", "tooltip": "用于生成噪声的随机种子。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -5675,11 +6690,11 @@ "ModelComputeDtype": { "display_name": "模型计算Dtype", "inputs": { - "dtype": { - "name": "dtype" - }, "model": { "name": "模型" + }, + "dtype": { + "name": "dtype" } } }, @@ -5697,9 +6712,27 @@ "ModelMergeAuraflow": { "display_name": "模型融合(Auraflow )", "inputs": { + "model1": { + "name": "模型1" + }, + "model2": { + "name": "模型2" + }, + "init_x_linear_": { + "name": "初始x线性." + }, + "positional_encoding": { + "name": "位置编码" + }, "cond_seq_linear_": { "name": "条件序列线性." }, + "register_tokens": { + "name": "注册令牌" + }, + "t_embedder_": { + "name": "t嵌入器." + }, "double_layers_0_": { "name": "双层.0." }, @@ -5712,30 +6745,36 @@ "double_layers_3_": { "name": "双层.3." }, - "final_linear_": { - "name": "最终线性." - }, - "init_x_linear_": { - "name": "初始x线性." - }, - "modF_": { - "name": "modF." - }, - "model1": { - "name": "模型1" - }, - "model2": { - "name": "模型2" - }, - "positional_encoding": { - "name": "位置编码" - }, - "register_tokens": { - "name": "注册令牌" - }, "single_layers_0_": { "name": "单层.0." }, + "single_layers_1_": { + "name": "单层.1." + }, + "single_layers_2_": { + "name": "单层.2." + }, + "single_layers_3_": { + "name": "单层.3." + }, + "single_layers_4_": { + "name": "单层.4." + }, + "single_layers_5_": { + "name": "单层.5." + }, + "single_layers_6_": { + "name": "单层.6." + }, + "single_layers_7_": { + "name": "单层.7." + }, + "single_layers_8_": { + "name": "单层.8." + }, + "single_layers_9_": { + "name": "单层.9." + }, "single_layers_10_": { "name": "单层.10." }, @@ -5766,9 +6805,6 @@ "single_layers_19_": { "name": "单层.19." }, - "single_layers_1_": { - "name": "单层.1." - }, "single_layers_20_": { "name": "单层.20." }, @@ -5799,56 +6835,35 @@ "single_layers_29_": { "name": "单层.29." }, - "single_layers_2_": { - "name": "单层.2." - }, "single_layers_30_": { "name": "单层.30." }, "single_layers_31_": { "name": "单层.31." }, - "single_layers_3_": { - "name": "单层.3." + "modF_": { + "name": "modF." }, - "single_layers_4_": { - "name": "单层.4." - }, - "single_layers_5_": { - "name": "单层.5." - }, - "single_layers_6_": { - "name": "单层.6." - }, - "single_layers_7_": { - "name": "单层.7." - }, - "single_layers_8_": { - "name": "单层.8." - }, - "single_layers_9_": { - "name": "单层.9." - }, - "t_embedder_": { - "name": "t嵌入器." + "final_linear_": { + "name": "最终线性." } } }, "ModelMergeBlocks": { "display_name": "模型融合(分块)", "inputs": { - "input": { - "name": "输入" - }, - "middle": { - "name": "中间" - }, "model1": { "name": "模型1" }, "model2": { "name": "模型2" }, + "input": { + "name": "输入" + }, + "middle": { + "name": "中间" + }, "out": { "name": "输出" } @@ -5857,12 +6872,57 @@ "ModelMergeCosmos14B": { "display_name": "模型融合(Cosmos14B)", "inputs": { + "model1": { + "name": "模型1" + }, + "model2": { + "name": "模型2" + }, + "pos_embedder_": { + "name": "位置嵌入器." + }, + "extra_pos_embedder_": { + "name": "额外位置嵌入器." + }, + "x_embedder_": { + "name": "x嵌入器." + }, + "t_embedder_": { + "name": "t嵌入器." + }, "affline_norm_": { "name": "仿射规范化." }, "blocks_block0_": { "name": "blocks.block0." }, + "blocks_block1_": { + "name": "blocks.block1." + }, + "blocks_block2_": { + "name": "blocks.block2." + }, + "blocks_block3_": { + "name": "blocks.block3." + }, + "blocks_block4_": { + "name": "blocks.block4." + }, + "blocks_block5_": { + "name": "blocks.block5." + }, + "blocks_block6_": { + "name": "blocks.block6." + }, + "blocks_block7_": { + "name": "blocks.block7." + }, + "blocks_block8_": { + "name": "blocks.block8." + }, + "blocks_block9_": { + "name": "blocks.block9." + }, "blocks_block10_": { "name": "blocks.block10." }, @@ -5893,9 +6953,6 @@ "blocks_block19_": { "name": "blocks.block19." }, - "blocks_block1_": { - "name": "blocks.block1." - }, "blocks_block20_": { "name": "blocks.block20." }, @@ -5926,9 +6983,6 @@ "blocks_block29_": { "name": "blocks.block29." }, - "blocks_block2_": { - "name": "blocks.block2." - }, "blocks_block30_": { "name": "blocks.block30." }, @@ -5947,6 +7001,44 @@ "blocks_block35_": { "name": "blocks.block35." }, + "final_layer_": { + "name": "最终层." + } + } + }, + "ModelMergeCosmos7B": { + "display_name": "模型融合(COsmos7B)", + "inputs": { + "model1": { + "name": "模型1" + }, + "model2": { + "name": "模型2" + }, + "pos_embedder_": { + "name": "位置嵌入器." + }, + "extra_pos_embedder_": { + "name": "额外位置嵌入器." + }, + "x_embedder_": { + "name": "x嵌入器." + }, + "t_embedder_": { + "name": "t嵌入器." + }, + "affline_norm_": { + "name": "仿射规范化." + }, + "blocks_block0_": { + "name": "blocks.block0." + }, + "blocks_block1_": { + "name": "blocks.block1." + }, + "blocks_block2_": { + "name": "blocks.block2." + }, "blocks_block3_": { "name": "blocks.block3." }, @@ -5968,38 +7060,6 @@ "blocks_block9_": { "name": "blocks.block9." }, - "extra_pos_embedder_": { - "name": "额外位置嵌入器." - }, - "final_layer_": { - "name": "最终层." - }, - "model1": { - "name": "模型1" - }, - "model2": { - "name": "模型2" - }, - "pos_embedder_": { - "name": "位置嵌入器." - }, - "t_embedder_": { - "name": "t嵌入器." - }, - "x_embedder_": { - "name": "x嵌入器." - } - } - }, - "ModelMergeCosmos7B": { - "display_name": "模型融合(COsmos7B)", - "inputs": { - "affline_norm_": { - "name": "仿射规范化." - }, - "blocks_block0_": { - "name": "blocks.block0." - }, "blocks_block10_": { "name": "blocks.block10." }, @@ -6030,9 +7090,6 @@ "blocks_block19_": { "name": "blocks.block19." }, - "blocks_block1_": { - "name": "blocks.block1." - }, "blocks_block20_": { "name": "blocks.block20." }, @@ -6057,36 +7114,14 @@ "blocks_block27_": { "name": "blocks.block27." }, - "blocks_block2_": { - "name": "blocks.block2." - }, - "blocks_block3_": { - "name": "blocks.block3." - }, - "blocks_block4_": { - "name": "blocks.block4." - }, - "blocks_block5_": { - "name": "blocks.block5." - }, - "blocks_block6_": { - "name": "blocks.block6." - }, - "blocks_block7_": { - "name": "blocks.block7." - }, - "blocks_block8_": { - "name": "blocks.block8." - }, - "blocks_block9_": { - "name": "blocks.block9." - }, - "extra_pos_embedder_": { - "name": "额外位置嵌入器." - }, "final_layer_": { "name": "最终层." - }, + } + } + }, + "ModelMergeCosmosPredict2_14B": { + "display_name": "模型融合(CosmosPredict2_14B)", + "inputs": { "model1": { "name": "模型1" }, @@ -6094,22 +7129,47 @@ "name": "模型2" }, "pos_embedder_": { - "name": "位置嵌入器." - }, - "t_embedder_": { - "name": "t嵌入器." + "name": "位置嵌入器。" }, "x_embedder_": { - "name": "x嵌入器." - } - } - }, - "ModelMergeCosmosPredict2_14B": { - "display_name": "模型融合(CosmosPredict2_14B)", - "inputs": { + "name": "x嵌入器。" + }, + "t_embedder_": { + "name": "t嵌入器。" + }, + "t_embedding_norm_": { + "name": "t嵌入归一化。" + }, "blocks_0_": { "name": "块0。" }, + "blocks_1_": { + "name": "块1。" + }, + "blocks_2_": { + "name": "块2。" + }, + "blocks_3_": { + "name": "块3。" + }, + "blocks_4_": { + "name": "块4。" + }, + "blocks_5_": { + "name": "块5。" + }, + "blocks_6_": { + "name": "块6。" + }, + "blocks_7_": { + "name": "块7。" + }, + "blocks_8_": { + "name": "块8。" + }, + "blocks_9_": { + "name": "块9。" + }, "blocks_10_": { "name": "块10。" }, @@ -6140,9 +7200,6 @@ "blocks_19_": { "name": "块19。" }, - "blocks_1_": { - "name": "块1。" - }, "blocks_20_": { "name": "块20。" }, @@ -6173,9 +7230,6 @@ "blocks_29_": { "name": "块29。" }, - "blocks_2_": { - "name": "块2。" - }, "blocks_30_": { "name": "块30。" }, @@ -6194,30 +7248,14 @@ "blocks_35_": { "name": "块35。" }, - "blocks_3_": { - "name": "块3。" - }, - "blocks_4_": { - "name": "块4。" - }, - "blocks_5_": { - "name": "块5。" - }, - "blocks_6_": { - "name": "块6。" - }, - "blocks_7_": { - "name": "块7。" - }, - "blocks_8_": { - "name": "块8。" - }, - "blocks_9_": { - "name": "块9。" - }, "final_layer_": { "name": "最终层。" - }, + } + } + }, + "ModelMergeCosmosPredict2_2B": { + "display_name": "模型融合(CosmosPredict2_2B)", + "inputs": { "model1": { "name": "模型1" }, @@ -6227,23 +7265,45 @@ "pos_embedder_": { "name": "位置嵌入器。" }, + "x_embedder_": { + "name": "x_嵌入器。" + }, "t_embedder_": { - "name": "t嵌入器。" + "name": "t_嵌入器。" }, "t_embedding_norm_": { - "name": "t嵌入归一化。" + "name": "t_嵌入归一化。" }, - "x_embedder_": { - "name": "x嵌入器。" - } - } - }, - "ModelMergeCosmosPredict2_2B": { - "display_name": "模型融合(CosmosPredict2_2B)", - "inputs": { "blocks_0_": { "name": "块.0." }, + "blocks_1_": { + "name": "块.1." + }, + "blocks_2_": { + "name": "块.2." + }, + "blocks_3_": { + "name": "块.3." + }, + "blocks_4_": { + "name": "块.4." + }, + "blocks_5_": { + "name": "块.5." + }, + "blocks_6_": { + "name": "块.6." + }, + "blocks_7_": { + "name": "块.7." + }, + "blocks_8_": { + "name": "块.8." + }, + "blocks_9_": { + "name": "块.9." + }, "blocks_10_": { "name": "块.10." }, @@ -6274,9 +7334,6 @@ "blocks_19_": { "name": "块.19." }, - "blocks_1_": { - "name": "块.1." - }, "blocks_20_": { "name": "块.20." }, @@ -6301,86 +7358,38 @@ "blocks_27_": { "name": "块.27." }, - "blocks_2_": { - "name": "块.2." - }, - "blocks_3_": { - "name": "块.3." - }, - "blocks_4_": { - "name": "块.4." - }, - "blocks_5_": { - "name": "块.5." - }, - "blocks_6_": { - "name": "块.6." - }, - "blocks_7_": { - "name": "块.7." - }, - "blocks_8_": { - "name": "块.8." - }, - "blocks_9_": { - "name": "块.9." - }, "final_layer_": { "name": "最终层。" - }, - "model1": { - "name": "模型1" - }, - "model2": { - "name": "模型2" - }, - "pos_embedder_": { - "name": "位置嵌入器。" - }, - "t_embedder_": { - "name": "t_嵌入器。" - }, - "t_embedding_norm_": { - "name": "t_嵌入归一化。" - }, - "x_embedder_": { - "name": "x_嵌入器。" } } }, "ModelMergeFlux1": { "display_name": "模型融合(Flux1)", "inputs": { + "model1": { + "name": "模型1" + }, + "model2": { + "name": "模型2" + }, + "img_in_": { + "name": "输入图像." + }, + "time_in_": { + "name": "输入时间." + }, + "guidance_in": { + "name": "输入引导" + }, + "vector_in_": { + "name": "输入向量." + }, + "txt_in_": { + "name": "输入文本." + }, "double_blocks_0_": { "name": "双块.0." }, - "double_blocks_10_": { - "name": "双块.10." - }, - "double_blocks_11_": { - "name": "双块.11." - }, - "double_blocks_12_": { - "name": "双块.12." - }, - "double_blocks_13_": { - "name": "双块.13." - }, - "double_blocks_14_": { - "name": "双块.14." - }, - "double_blocks_15_": { - "name": "双块.15." - }, - "double_blocks_16_": { - "name": "双块.16." - }, - "double_blocks_17_": { - "name": "双块.17." - }, - "double_blocks_18_": { - "name": "双块.18." - }, "double_blocks_1_": { "name": "双块.1." }, @@ -6408,24 +7417,63 @@ "double_blocks_9_": { "name": "双块.9." }, - "final_layer_": { - "name": "最终层." + "double_blocks_10_": { + "name": "双块.10." }, - "guidance_in": { - "name": "输入引导" + "double_blocks_11_": { + "name": "双块.11." }, - "img_in_": { - "name": "输入图像." + "double_blocks_12_": { + "name": "双块.12." }, - "model1": { - "name": "模型1" + "double_blocks_13_": { + "name": "双块.13." }, - "model2": { - "name": "模型2" + "double_blocks_14_": { + "name": "双块.14." + }, + "double_blocks_15_": { + "name": "双块.15." + }, + "double_blocks_16_": { + "name": "双块.16." + }, + "double_blocks_17_": { + "name": "双块.17." + }, + "double_blocks_18_": { + "name": "双块.18." }, "single_blocks_0_": { "name": "单块.0." }, + "single_blocks_1_": { + "name": "单块.1." + }, + "single_blocks_2_": { + "name": "单块.2." + }, + "single_blocks_3_": { + "name": "单块.3." + }, + "single_blocks_4_": { + "name": "单块.4." + }, + "single_blocks_5_": { + "name": "单块.5." + }, + "single_blocks_6_": { + "name": "单块.6." + }, + "single_blocks_7_": { + "name": "单块.7." + }, + "single_blocks_8_": { + "name": "单块.8." + }, + "single_blocks_9_": { + "name": "单块.9." + }, "single_blocks_10_": { "name": "单块.10." }, @@ -6456,9 +7504,6 @@ "single_blocks_19_": { "name": "单块.19." }, - "single_blocks_1_": { - "name": "单块.1." - }, "single_blocks_20_": { "name": "单块.20." }, @@ -6489,9 +7534,6 @@ "single_blocks_29_": { "name": "单块.29." }, - "single_blocks_2_": { - "name": "单块.2." - }, "single_blocks_30_": { "name": "单块.30." }, @@ -6516,47 +7558,14 @@ "single_blocks_37_": { "name": "单块.37." }, - "single_blocks_3_": { - "name": "单块.3." - }, - "single_blocks_4_": { - "name": "单块.4." - }, - "single_blocks_5_": { - "name": "单块.5." - }, - "single_blocks_6_": { - "name": "单块.6." - }, - "single_blocks_7_": { - "name": "单块.7." - }, - "single_blocks_8_": { - "name": "单块.8." - }, - "single_blocks_9_": { - "name": "单块.9." - }, - "time_in_": { - "name": "输入时间." - }, - "txt_in_": { - "name": "输入文本." - }, - "vector_in_": { - "name": "输入向量." + "final_layer_": { + "name": "最终层." } } }, "ModelMergeLTXV": { "display_name": "模型融合(LTXV)", "inputs": { - "adaln_single_": { - "name": "adaln_single." - }, - "caption_projection_": { - "name": "caption_projection." - }, "model1": { "name": "模型1" }, @@ -6566,15 +7575,42 @@ "patchify_proj_": { "name": "patchify_proj." }, - "proj_out_": { - "name": "proj_out." + "adaln_single_": { + "name": "adaln_single." }, - "scale_shift_table": { - "name": "scale_shift_table" + "caption_projection_": { + "name": "caption_projection." }, "transformer_blocks_0_": { "name": "transformer_blocks.0." }, + "transformer_blocks_1_": { + "name": "transformer_blocks.1." + }, + "transformer_blocks_2_": { + "name": "transformer_blocks.2." + }, + "transformer_blocks_3_": { + "name": "transformer_blocks.3." + }, + "transformer_blocks_4_": { + "name": "transformer_blocks.4." + }, + "transformer_blocks_5_": { + "name": "transformer_blocks.5." + }, + "transformer_blocks_6_": { + "name": "transformer_blocks.6." + }, + "transformer_blocks_7_": { + "name": "transformer_blocks.7." + }, + "transformer_blocks_8_": { + "name": "transformer_blocks.8." + }, + "transformer_blocks_9_": { + "name": "transformer_blocks.9." + }, "transformer_blocks_10_": { "name": "transformer_blocks.10." }, @@ -6605,9 +7641,6 @@ "transformer_blocks_19_": { "name": "transformer_blocks.19." }, - "transformer_blocks_1_": { - "name": "transformer_blocks.1." - }, "transformer_blocks_20_": { "name": "transformer_blocks.20." }, @@ -6632,38 +7665,65 @@ "transformer_blocks_27_": { "name": "transformer_blocks.27." }, - "transformer_blocks_2_": { - "name": "transformer_blocks.2." + "scale_shift_table": { + "name": "scale_shift_table" }, - "transformer_blocks_3_": { - "name": "transformer_blocks.3." - }, - "transformer_blocks_4_": { - "name": "transformer_blocks.4." - }, - "transformer_blocks_5_": { - "name": "transformer_blocks.5." - }, - "transformer_blocks_6_": { - "name": "transformer_blocks.6." - }, - "transformer_blocks_7_": { - "name": "transformer_blocks.7." - }, - "transformer_blocks_8_": { - "name": "transformer_blocks.8." - }, - "transformer_blocks_9_": { - "name": "transformer_blocks.9." + "proj_out_": { + "name": "proj_out." } } }, "ModelMergeMochiPreview": { "display_name": "模型融合(Mochi预览)", "inputs": { + "model1": { + "name": "模型1" + }, + "model2": { + "name": "模型2" + }, + "pos_frequencies_": { + "name": "pos_frequencies." + }, + "t_embedder_": { + "name": "t_embedder." + }, + "t5_y_embedder_": { + "name": "t5_y_embedder." + }, + "t5_yproj_": { + "name": "t5_yproj." + }, "blocks_0_": { "name": "blocks.0." }, + "blocks_1_": { + "name": "blocks.1." + }, + "blocks_2_": { + "name": "blocks.2." + }, + "blocks_3_": { + "name": "blocks.3." + }, + "blocks_4_": { + "name": "blocks.4." + }, + "blocks_5_": { + "name": "blocks.5." + }, + "blocks_6_": { + "name": "blocks.6." + }, + "blocks_7_": { + "name": "blocks.7." + }, + "blocks_8_": { + "name": "blocks.8." + }, + "blocks_9_": { + "name": "blocks.9." + }, "blocks_10_": { "name": "blocks.10." }, @@ -6694,9 +7754,6 @@ "blocks_19_": { "name": "blocks.19." }, - "blocks_1_": { - "name": "blocks.1." - }, "blocks_20_": { "name": "blocks.20." }, @@ -6727,9 +7784,6 @@ "blocks_29_": { "name": "blocks.29." }, - "blocks_2_": { - "name": "blocks.2." - }, "blocks_30_": { "name": "blocks.30." }, @@ -6760,9 +7814,6 @@ "blocks_39_": { "name": "blocks.39." }, - "blocks_3_": { - "name": "blocks.3." - }, "blocks_40_": { "name": "blocks.40." }, @@ -6787,53 +7838,14 @@ "blocks_47_": { "name": "blocks.47." }, - "blocks_4_": { - "name": "blocks.4." - }, - "blocks_5_": { - "name": "blocks.5." - }, - "blocks_6_": { - "name": "blocks.6." - }, - "blocks_7_": { - "name": "blocks.7." - }, - "blocks_8_": { - "name": "blocks.8." - }, - "blocks_9_": { - "name": "blocks.9." - }, "final_layer_": { "name": "final_layer." - }, - "model1": { - "name": "模型1" - }, - "model2": { - "name": "模型2" - }, - "pos_frequencies_": { - "name": "pos_frequencies." - }, - "t5_y_embedder_": { - "name": "t5_y_embedder." - }, - "t5_yproj_": { - "name": "t5_yproj." - }, - "t_embedder_": { - "name": "t_embedder." } } }, "ModelMergeQwenImage": { "display_name": "模型融合Qwen图像", "inputs": { - "img_in_": { - "name": "图像输入。" - }, "model1": { "name": "模型1" }, @@ -6843,8 +7855,14 @@ "pos_embeds_": { "name": "位置嵌入。" }, - "proj_out_": { - "name": "proj_out." + "img_in_": { + "name": "图像输入。" + }, + "txt_norm_": { + "name": "文本归一化。" + }, + "txt_in_": { + "name": "文本输入。" }, "time_text_embed_": { "name": "时间文本嵌入。" @@ -6852,6 +7870,33 @@ "transformer_blocks_0_": { "name": "变换器块.0." }, + "transformer_blocks_1_": { + "name": "变换器块.1." + }, + "transformer_blocks_2_": { + "name": "变换器块.2." + }, + "transformer_blocks_3_": { + "name": "变换器块.3." + }, + "transformer_blocks_4_": { + "name": "变换器块.4." + }, + "transformer_blocks_5_": { + "name": "变换器块.5." + }, + "transformer_blocks_6_": { + "name": "变换器块.6." + }, + "transformer_blocks_7_": { + "name": "变换器块.7." + }, + "transformer_blocks_8_": { + "name": "变换器块.8." + }, + "transformer_blocks_9_": { + "name": "变换器块.9." + }, "transformer_blocks_10_": { "name": "transformer_blocks.10." }, @@ -6882,9 +7927,6 @@ "transformer_blocks_19_": { "name": "transformer_blocks.19." }, - "transformer_blocks_1_": { - "name": "变换器块.1." - }, "transformer_blocks_20_": { "name": "transformer_blocks.20." }, @@ -6915,9 +7957,6 @@ "transformer_blocks_29_": { "name": "transformer_blocks.29." }, - "transformer_blocks_2_": { - "name": "变换器块.2." - }, "transformer_blocks_30_": { "name": "transformer_blocks.30." }, @@ -6948,9 +7987,6 @@ "transformer_blocks_39_": { "name": "transformer_blocks.39." }, - "transformer_blocks_3_": { - "name": "变换器块.3." - }, "transformer_blocks_40_": { "name": "transformer_blocks.40." }, @@ -6981,9 +8017,6 @@ "transformer_blocks_49_": { "name": "transformer_blocks.49." }, - "transformer_blocks_4_": { - "name": "变换器块.4." - }, "transformer_blocks_50_": { "name": "transformer_blocks.50." }, @@ -7014,41 +8047,29 @@ "transformer_blocks_59_": { "name": "transformer_blocks.59." }, - "transformer_blocks_5_": { - "name": "变换器块.5." - }, - "transformer_blocks_6_": { - "name": "变换器块.6." - }, - "transformer_blocks_7_": { - "name": "变换器块.7." - }, - "transformer_blocks_8_": { - "name": "变换器块.8." - }, - "transformer_blocks_9_": { - "name": "变换器块.9." - }, - "txt_in_": { - "name": "文本输入。" - }, - "txt_norm_": { - "name": "文本归一化。" + "proj_out_": { + "name": "proj_out." } } }, "ModelMergeSD1": { "display_name": "模型融合(SD1)", "inputs": { + "model1": { + "name": "模型1" + }, + "model2": { + "name": "模型2" + }, + "time_embed_": { + "name": "时间嵌入." + }, + "label_emb_": { + "name": "标签嵌入." + }, "input_blocks_0_": { "name": "输入块.0." }, - "input_blocks_10_": { - "name": "输入块.10." - }, - "input_blocks_11_": { - "name": "输入块.11." - }, "input_blocks_1_": { "name": "输入块.1." }, @@ -7076,8 +8097,11 @@ "input_blocks_9_": { "name": "输入块.9." }, - "label_emb_": { - "name": "标签嵌入." + "input_blocks_10_": { + "name": "输入块.10." + }, + "input_blocks_11_": { + "name": "输入块.11." }, "middle_block_0_": { "name": "中间块.0." @@ -7088,24 +8112,9 @@ "middle_block_2_": { "name": "中间块.2." }, - "model1": { - "name": "模型1" - }, - "model2": { - "name": "模型2" - }, - "out_": { - "name": "出." - }, "output_blocks_0_": { "name": "输出块.0." }, - "output_blocks_10_": { - "name": "输出块.10." - }, - "output_blocks_11_": { - "name": "输出块.11." - }, "output_blocks_1_": { "name": "输出块.1." }, @@ -7133,23 +8142,35 @@ "output_blocks_9_": { "name": "输出块.9." }, - "time_embed_": { - "name": "时间嵌入." + "output_blocks_10_": { + "name": "输出块.10." + }, + "output_blocks_11_": { + "name": "输出块.11." + }, + "out_": { + "name": "出." } } }, "ModelMergeSD2": { "display_name": "模型融合(SD2)", "inputs": { + "model1": { + "name": "模型1" + }, + "model2": { + "name": "模型2" + }, + "time_embed_": { + "name": "时间嵌入." + }, + "label_emb_": { + "name": "标签嵌入." + }, "input_blocks_0_": { "name": "输入块.0." }, - "input_blocks_10_": { - "name": "输入块.10." - }, - "input_blocks_11_": { - "name": "输入块.11." - }, "input_blocks_1_": { "name": "输入块.1." }, @@ -7177,8 +8198,11 @@ "input_blocks_9_": { "name": "输入块.9." }, - "label_emb_": { - "name": "标签嵌入." + "input_blocks_10_": { + "name": "输入块.10." + }, + "input_blocks_11_": { + "name": "输入块.11." }, "middle_block_0_": { "name": "中间块.0." @@ -7189,24 +8213,9 @@ "middle_block_2_": { "name": "中间块.2." }, - "model1": { - "name": "模型1" - }, - "model2": { - "name": "模型2" - }, - "out_": { - "name": "出." - }, "output_blocks_0_": { "name": "输出块.0." }, - "output_blocks_10_": { - "name": "输出块.10." - }, - "output_blocks_11_": { - "name": "输出块.11." - }, "output_blocks_1_": { "name": "输出块.1." }, @@ -7234,23 +8243,71 @@ "output_blocks_9_": { "name": "输出块.9." }, - "time_embed_": { - "name": "时间嵌入." + "output_blocks_10_": { + "name": "输出块.10." + }, + "output_blocks_11_": { + "name": "输出块.11." + }, + "out_": { + "name": "出." } } }, - "ModelMergeSD35_Large": { - "display_name": "模型融合(SD35_大)", + "ModelMergeSD3_2B": { + "display_name": "模型融合(SD3_2B)", "inputs": { + "model1": { + "name": "模型1" + }, + "model2": { + "name": "模型2" + }, + "pos_embed_": { + "name": "位置嵌入." + }, + "x_embedder_": { + "name": "x嵌入器." + }, "context_embedder_": { "name": "上下文嵌入器." }, - "final_layer_": { - "name": "最终层." + "y_embedder_": { + "name": "y嵌入器." + }, + "t_embedder_": { + "name": "t嵌入器." }, "joint_blocks_0_": { "name": "联合块.0." }, + "joint_blocks_1_": { + "name": "联合块.1." + }, + "joint_blocks_2_": { + "name": "联合块.2." + }, + "joint_blocks_3_": { + "name": "联合块.3." + }, + "joint_blocks_4_": { + "name": "联合块.4." + }, + "joint_blocks_5_": { + "name": "联合块.5." + }, + "joint_blocks_6_": { + "name": "联合块.6." + }, + "joint_blocks_7_": { + "name": "联合块.7." + }, + "joint_blocks_8_": { + "name": "联合块.8." + }, + "joint_blocks_9_": { + "name": "联合块.9." + }, "joint_blocks_10_": { "name": "联合块.10." }, @@ -7281,9 +8338,107 @@ "joint_blocks_19_": { "name": "联合块.19." }, + "joint_blocks_20_": { + "name": "联合块.20." + }, + "joint_blocks_21_": { + "name": "联合块.21." + }, + "joint_blocks_22_": { + "name": "联合块.22." + }, + "joint_blocks_23_": { + "name": "联合块.23." + }, + "final_layer_": { + "name": "最终层." + } + } + }, + "ModelMergeSD35_Large": { + "display_name": "模型融合(SD35_大)", + "inputs": { + "model1": { + "name": "模型1" + }, + "model2": { + "name": "模型2" + }, + "pos_embed_": { + "name": "位置嵌入." + }, + "x_embedder_": { + "name": "x嵌入器." + }, + "context_embedder_": { + "name": "上下文嵌入器." + }, + "y_embedder_": { + "name": "y嵌入器." + }, + "t_embedder_": { + "name": "t嵌入器." + }, + "joint_blocks_0_": { + "name": "联合块.0." + }, "joint_blocks_1_": { "name": "联合块.1." }, + "joint_blocks_2_": { + "name": "联合块.2." + }, + "joint_blocks_3_": { + "name": "联合块.3." + }, + "joint_blocks_4_": { + "name": "联合块.4." + }, + "joint_blocks_5_": { + "name": "联合块.5." + }, + "joint_blocks_6_": { + "name": "联合块.6." + }, + "joint_blocks_7_": { + "name": "联合块.7." + }, + "joint_blocks_8_": { + "name": "联合块.8." + }, + "joint_blocks_9_": { + "name": "联合块.9." + }, + "joint_blocks_10_": { + "name": "联合块.10." + }, + "joint_blocks_11_": { + "name": "联合块.11." + }, + "joint_blocks_12_": { + "name": "联合块.12." + }, + "joint_blocks_13_": { + "name": "联合块.13." + }, + "joint_blocks_14_": { + "name": "联合块.14." + }, + "joint_blocks_15_": { + "name": "联合块.15." + }, + "joint_blocks_16_": { + "name": "联合块.16." + }, + "joint_blocks_17_": { + "name": "联合块.17." + }, + "joint_blocks_18_": { + "name": "联合块.18." + }, + "joint_blocks_19_": { + "name": "联合块.19." + }, "joint_blocks_20_": { "name": "联合块.20." }, @@ -7314,9 +8469,6 @@ "joint_blocks_29_": { "name": "联合块.29." }, - "joint_blocks_2_": { - "name": "联合块.2." - }, "joint_blocks_30_": { "name": "联合块.30." }, @@ -7341,151 +8493,26 @@ "joint_blocks_37_": { "name": "联合块.37." }, - "joint_blocks_3_": { - "name": "联合块.3." - }, - "joint_blocks_4_": { - "name": "联合块.4." - }, - "joint_blocks_5_": { - "name": "联合块.5." - }, - "joint_blocks_6_": { - "name": "联合块.6." - }, - "joint_blocks_7_": { - "name": "联合块.7." - }, - "joint_blocks_8_": { - "name": "联合块.8." - }, - "joint_blocks_9_": { - "name": "联合块.9." - }, - "model1": { - "name": "模型1" - }, - "model2": { - "name": "模型2" - }, - "pos_embed_": { - "name": "位置嵌入." - }, - "t_embedder_": { - "name": "t嵌入器." - }, - "x_embedder_": { - "name": "x嵌入器." - }, - "y_embedder_": { - "name": "y嵌入器." - } - } - }, - "ModelMergeSD3_2B": { - "display_name": "模型融合(SD3_2B)", - "inputs": { - "context_embedder_": { - "name": "上下文嵌入器." - }, "final_layer_": { "name": "最终层." - }, - "joint_blocks_0_": { - "name": "联合块.0." - }, - "joint_blocks_10_": { - "name": "联合块.10." - }, - "joint_blocks_11_": { - "name": "联合块.11." - }, - "joint_blocks_12_": { - "name": "联合块.12." - }, - "joint_blocks_13_": { - "name": "联合块.13." - }, - "joint_blocks_14_": { - "name": "联合块.14." - }, - "joint_blocks_15_": { - "name": "联合块.15." - }, - "joint_blocks_16_": { - "name": "联合块.16." - }, - "joint_blocks_17_": { - "name": "联合块.17." - }, - "joint_blocks_18_": { - "name": "联合块.18." - }, - "joint_blocks_19_": { - "name": "联合块.19." - }, - "joint_blocks_1_": { - "name": "联合块.1." - }, - "joint_blocks_20_": { - "name": "联合块.20." - }, - "joint_blocks_21_": { - "name": "联合块.21." - }, - "joint_blocks_22_": { - "name": "联合块.22." - }, - "joint_blocks_23_": { - "name": "联合块.23." - }, - "joint_blocks_2_": { - "name": "联合块.2." - }, - "joint_blocks_3_": { - "name": "联合块.3." - }, - "joint_blocks_4_": { - "name": "联合块.4." - }, - "joint_blocks_5_": { - "name": "联合块.5." - }, - "joint_blocks_6_": { - "name": "联合块.6." - }, - "joint_blocks_7_": { - "name": "联合块.7." - }, - "joint_blocks_8_": { - "name": "联合块.8." - }, - "joint_blocks_9_": { - "name": "联合块.9." - }, - "model1": { - "name": "模型1" - }, - "model2": { - "name": "模型2" - }, - "pos_embed_": { - "name": "位置嵌入." - }, - "t_embedder_": { - "name": "t嵌入器." - }, - "x_embedder_": { - "name": "x嵌入器." - }, - "y_embedder_": { - "name": "y嵌入器." } } }, "ModelMergeSDXL": { "display_name": "模型融合(SDXL)", "inputs": { + "model1": { + "name": "模型1" + }, + "model2": { + "name": "模型2" + }, + "time_embed_": { + "name": "时间嵌入." + }, + "label_emb_": { + "name": "标签嵌入." + }, "input_blocks_0": { "name": "输入块.0" }, @@ -7513,9 +8540,6 @@ "input_blocks_8": { "name": "输入块.8" }, - "label_emb_": { - "name": "标签嵌入." - }, "middle_block_0": { "name": "中间块.0" }, @@ -7525,15 +8549,6 @@ "middle_block_2": { "name": "中间块.2" }, - "model1": { - "name": "模型1" - }, - "model2": { - "name": "模型2" - }, - "out_": { - "name": "输出." - }, "output_blocks_0": { "name": "输出块.0" }, @@ -7561,8 +8576,8 @@ "output_blocks_8": { "name": "输出块.8" }, - "time_embed_": { - "name": "时间嵌入." + "out_": { + "name": "输出." } } }, @@ -7595,12 +8610,60 @@ } }, "ModelMergeWAN2_1": { - "description": "1.3B模型有30个模块,14B模型有40个模块。图像转视频模型有额外的img_emb。", "display_name": "模型融合(WAN2.1)", + "description": "1.3B模型有30个模块,14B模型有40个模块。图像转视频模型有额外的img_emb。", "inputs": { + "model1": { + "name": "模型1" + }, + "model2": { + "name": "模型2" + }, + "patch_embedding_": { + "name": "patch_embedding." + }, + "time_embedding_": { + "name": "time_embedding." + }, + "time_projection_": { + "name": "time_projection." + }, + "text_embedding_": { + "name": "text_embedding." + }, + "img_emb_": { + "name": "img_emb." + }, "blocks_0_": { "name": "blocks.0." }, + "blocks_1_": { + "name": "blocks.1." + }, + "blocks_2_": { + "name": "blocks.2." + }, + "blocks_3_": { + "name": "blocks.3." + }, + "blocks_4_": { + "name": "blocks.4." + }, + "blocks_5_": { + "name": "blocks.5." + }, + "blocks_6_": { + "name": "blocks.6." + }, + "blocks_7_": { + "name": "blocks.7." + }, + "blocks_8_": { + "name": "blocks.8." + }, + "blocks_9_": { + "name": "blocks.9." + }, "blocks_10_": { "name": "blocks.10." }, @@ -7631,9 +8694,6 @@ "blocks_19_": { "name": "blocks.19." }, - "blocks_1_": { - "name": "blocks.1." - }, "blocks_20_": { "name": "blocks.20." }, @@ -7664,9 +8724,6 @@ "blocks_29_": { "name": "blocks.29." }, - "blocks_2_": { - "name": "blocks.2." - }, "blocks_30_": { "name": "blocks.30." }, @@ -7697,50 +8754,8 @@ "blocks_39_": { "name": "blocks.39." }, - "blocks_3_": { - "name": "blocks.3." - }, - "blocks_4_": { - "name": "blocks.4." - }, - "blocks_5_": { - "name": "blocks.5." - }, - "blocks_6_": { - "name": "blocks.6." - }, - "blocks_7_": { - "name": "blocks.7." - }, - "blocks_8_": { - "name": "blocks.8." - }, - "blocks_9_": { - "name": "blocks.9." - }, "head_": { "name": "head." - }, - "img_emb_": { - "name": "img_emb." - }, - "model1": { - "name": "模型1" - }, - "model2": { - "name": "模型2" - }, - "patch_embedding_": { - "name": "patch_embedding." - }, - "text_embedding_": { - "name": "text_embedding." - }, - "time_embedding_": { - "name": "time_embedding." - }, - "time_projection_": { - "name": "time_projection." } } }, @@ -7814,37 +8829,37 @@ "ModelSamplingFlux": { "display_name": "采样算法(Flux)", "inputs": { - "base_shift": { - "name": "基础移位" - }, - "height": { - "name": "高度" + "model": { + "name": "模型" }, "max_shift": { "name": "最大移位" }, - "model": { - "name": "模型" + "base_shift": { + "name": "基础移位" }, "width": { "name": "宽度" + }, + "height": { + "name": "高度" } } }, "ModelSamplingLTXV": { "display_name": "采样算法(LTXV)", "inputs": { + "model": { + "name": "模型" + }, + "max_shift": { + "name": "最大移位" + }, "base_shift": { "name": "基础移位" }, "latent": { "name": "Latent" - }, - "max_shift": { - "name": "最大移位" - }, - "model": { - "name": "模型" } }, "outputs": { @@ -7878,40 +8893,37 @@ "ModelSave": { "display_name": "保存模型", "inputs": { - "filename_prefix": { - "name": "文件名前缀" - }, "model": { "name": "模型" + }, + "filename_prefix": { + "name": "文件名前缀" } } }, "MoonvalleyImg2VideoNode": { - "description": "Moonvalry Marey 图像转视频节点", - "display_name": "Moonvalry Marey 图像转视频", + "display_name": "Moonvalley Marey 图像转视频", + "description": "Moonvalley Marey 图像转视频节点", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, "image": { "name": "图像", "tooltip": "用于生成视频的参考图像" }, + "prompt": { + "name": "提示词" + }, "negative_prompt": { "name": "负面提示词", "tooltip": "负面提示词文本" }, - "prompt": { - "name": "提示词" + "resolution": { + "name": "分辨率", + "tooltip": "输出视频的分辨率" }, "prompt_adherence": { "name": "提示词遵循度", "tooltip": "用于生成控制的引导尺度" }, - "resolution": { - "name": "分辨率", - "tooltip": "输出视频的分辨率" - }, "seed": { "name": "种子", "tooltip": "随机种子值" @@ -7919,6 +8931,9 @@ "steps": { "name": "步数", "tooltip": "去噪步数" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -7928,26 +8943,23 @@ } }, "MoonvalleyTxt2VideoNode": { - "display_name": "Moonvalry Marey 文本转视频", + "display_name": "Moonvalley Marey 文本转视频", "inputs": { - "control_after_generate": { - "name": "生成后控制" + "prompt": { + "name": "提示词" }, "negative_prompt": { "name": "负面提示词", "tooltip": "负面提示词文本" }, - "prompt": { - "name": "提示词" + "resolution": { + "name": "分辨率", + "tooltip": "输出视频的分辨率" }, "prompt_adherence": { "name": "提示词遵循度", "tooltip": "用于生成控制的引导尺度" }, - "resolution": { - "name": "分辨率", - "tooltip": "输出视频的分辨率" - }, "seed": { "name": "种子", "tooltip": "随机种子值" @@ -7955,6 +8967,9 @@ "steps": { "name": "步数", "tooltip": "推理步数" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -7964,34 +8979,34 @@ } }, "MoonvalleyVideo2VideoNode": { - "display_name": "Moonvalry Marey 视频转视频", + "display_name": "Moonvalley Marey 视频转视频", "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "描述要生成的视频" + }, + "negative_prompt": { + "name": "负面提示词", + "tooltip": "负面提示词文本" + }, + "seed": { + "name": "种子", + "tooltip": "随机种子值" + }, + "video": { + "name": "视频", + "tooltip": "用于生成输出视频的参考视频。必须至少5秒长。超过5秒的视频将被自动裁剪。仅支持MP4格式。" + }, + "steps": { + "name": "步数", + "tooltip": "推理步数" + }, "control_type": { "name": "控制类型" }, "motion_intensity": { "name": "运动强度", "tooltip": "仅在控制类型为'运动转移'时使用" - }, - "negative_prompt": { - "name": "负面提示词", - "tooltip": "负面提示词文本" - }, - "prompt": { - "name": "提示词", - "tooltip": "描述要生成的视频" - }, - "seed": { - "name": "种子", - "tooltip": "随机种子值" - }, - "steps": { - "name": "步数", - "tooltip": "推理步数" - }, - "video": { - "name": "视频", - "tooltip": "用于生成输出视频的参考视频。必须至少5秒长。超过5秒的视频将被自动裁剪。仅支持MP4格式。" } }, "outputs": { @@ -8006,11 +9021,11 @@ "image": { "name": "图像" }, - "kernel_size": { - "name": "核心大小" - }, "operation": { "name": "操作" + }, + "kernel_size": { + "name": "核心大小" } }, "outputs": { @@ -8019,21 +9034,67 @@ } } }, - "OpenAIChatConfig": { - "description": "允许为OpenAI聊天节点指定高级配置选项。", - "display_name": "OpenAI ChatGPT 高级选项", + "NormalizeImages": { + "display_name": "规格化图像", "inputs": { - "instructions": { - "name": "指令", - "tooltip": "指导模型如何生成响应的指令" + "images": { + "name": "图像", + "tooltip": "需要处理的图像序列。" + }, + "mean": { + "name": "平均", + "tooltip": "规格化的平均值。" + }, + "std": { + "name": "标准差", + "tooltip": "规格化的标准差。" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "已处理的图像" + } + } + }, + "NormalizeVideoLatentStart": { + "display_name": "规格化视频Latent", + "description": "将视频初始帧的 Latent 规格化,使其符合后续参考帧的平均值与标准差。有助于减少起始帧与视频其余部分之间的差异。", + "inputs": { + "latent": { + "name": "Latent" + }, + "start_frame_count": { + "name": "规格化数量", + "tooltip": "从起始帧开始,需要规格化的 Latent 数量" + }, + "reference_frame_count": { + "name": "参考数量", + "tooltip": "从起始帧开始,用于参考的 Latent 数量" + } + }, + "outputs": { + "0": { + "name": "latent", + "tooltip": null + } + } + }, + "OpenAIChatConfig": { + "display_name": "OpenAI ChatGPT 高级选项", + "description": "允许为OpenAI聊天节点指定高级配置选项。", + "inputs": { + "truncation": { + "name": "截断", + "tooltip": "用于模型响应的截断策略。auto:如果此响应和先前响应的上下文超过模型的上下文窗口大小,模型将通过丢弃对话中间部分的输入项来截断响应以适应上下文窗口。disabled:如果模型响应将超过模型的上下文窗口大小,请求将失败并返回400错误。" }, "max_output_tokens": { "name": "Token输出上限", "tooltip": "生成响应时可生成token数量的上限,包括可见输出token" }, - "truncation": { - "name": "截断", - "tooltip": "用于模型响应的截断策略。auto:如果此响应和先前响应的上下文超过模型的上下文窗口大小,模型将通过丢弃对话中间部分的输入项来截断响应以适应上下文窗口。disabled:如果模型响应将超过模型的上下文窗口大小,请求将失败并返回400错误。" + "instructions": { + "name": "指令", + "tooltip": "指导模型如何生成响应的指令" } }, "outputs": { @@ -8043,32 +9104,32 @@ } }, "OpenAIChatNode": { - "description": "从OpenAI模型生成文本响应。", "display_name": "OpenAI ChatGPT", + "description": "从OpenAI模型生成文本响应。", "inputs": { - "advanced_options": { - "name": "高级设置", - "tooltip": "模型的可选配置。接受来自OpenAI聊天高级选项节点的输入。" - }, - "files": { - "name": "文件", - "tooltip": "可选文件,用作模型的上下文。接受来自OpenAI聊天输入文件节点的输入。" - }, - "images": { - "name": "图像", - "tooltip": "可选图像,用作模型的上下文。要包含多张图像,可使用批处理图像节点。" - }, - "model": { - "name": "模型", - "tooltip": "用于生成响应的模型" + "prompt": { + "name": "提示词", + "tooltip": "模型的文本输入,用于生成响应。" }, "persist_context": { "name": "保持上下文", "tooltip": "此参数已弃用,无任何效果。" }, - "prompt": { - "name": "提示词", - "tooltip": "模型的文本输入,用于生成响应。" + "model": { + "name": "模型", + "tooltip": "用于生成响应的模型" + }, + "images": { + "name": "图像", + "tooltip": "可选图像,用作模型的上下文。要包含多张图像,可使用批处理图像节点。" + }, + "files": { + "name": "文件", + "tooltip": "可选文件,用作模型的上下文。接受来自OpenAI聊天输入文件节点的输入。" + }, + "advanced_options": { + "name": "高级设置", + "tooltip": "模型的可选配置。接受来自OpenAI聊天高级选项节点的输入。" } }, "outputs": { @@ -8078,24 +9139,9 @@ } }, "OpenAIDalle2": { - "description": "通过 OpenAI 的 DALL·E 2 接口同步生成图像。", "display_name": "OpenAI DALL·E 2", + "description": "通过 OpenAI 的 DALL·E 2 接口同步生成图像。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "image": { - "name": "参考图像", - "tooltip": "用于图像编辑的可选参考图像。" - }, - "mask": { - "name": "掩码", - "tooltip": "用于修复的可选掩码(白色区域将被替换)" - }, - "n": { - "name": "数量", - "tooltip": "生成的图像数量" - }, "prompt": { "name": "提示词", "tooltip": "用于 DALL·E 的文本提示" @@ -8107,6 +9153,21 @@ "size": { "name": "尺寸", "tooltip": "图像尺寸" + }, + "n": { + "name": "数量", + "tooltip": "生成的图像数量" + }, + "image": { + "name": "参考图像", + "tooltip": "用于图像编辑的可选参考图像。" + }, + "mask": { + "name": "掩码", + "tooltip": "用于修复的可选掩码(白色区域将被替换)" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -8116,31 +9177,31 @@ } }, "OpenAIDalle3": { - "description": "通过 OpenAI 的 DALL·E 3 接口同步生成图像。", "display_name": "OpenAI DALL·E 3", + "description": "通过 OpenAI 的 DALL·E 3 接口同步生成图像。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, "prompt": { "name": "提示词", "tooltip": "DALL·E 的文本提示" }, - "quality": { - "name": "质量", - "tooltip": "图像质量" - }, "seed": { "name": "种子", "tooltip": "后端尚未实现" }, - "size": { - "name": "尺寸", - "tooltip": "图像尺寸" + "quality": { + "name": "质量", + "tooltip": "图像质量" }, "style": { "name": "风格", "tooltip": "“生动”会让模型倾向于生成超现实和戏剧性的图像。“自然”会让模型生成更自然、较少超现实感的图像。" + }, + "size": { + "name": "尺寸", + "tooltip": "图像尺寸" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -8150,15 +9211,32 @@ } }, "OpenAIGPTImage1": { - "description": "通过 OpenAI 的 GPT Image 1 端点同步生成图像。", "display_name": "OpenAI GPT Image 1", + "description": "通过 OpenAI 的 GPT Image 1 端点同步生成图像。", "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "用于 GPT Image 1 的文本提示" + }, + "seed": { + "name": "种子", + "tooltip": "后端尚未实现" + }, + "quality": { + "name": "质量", + "tooltip": "图像质量,影响成本和生成时间。" + }, "background": { "name": "背景", "tooltip": "返回带有或不带背景的图像" }, - "control_after_generate": { - "name": "生成后控制" + "size": { + "name": "尺寸", + "tooltip": "图像尺寸" + }, + "n": { + "name": "数量", + "tooltip": "生成多少张图像" }, "image": { "name": "参考图像", @@ -8168,25 +9246,11 @@ "name": "遮罩", "tooltip": "用于修复的可选 mask(白色区域将被替换)" }, - "n": { - "name": "数量", - "tooltip": "生成多少张图像" + "model": { + "name": "模型" }, - "prompt": { - "name": "提示词", - "tooltip": "用于 GPT Image 1 的文本提示" - }, - "quality": { - "name": "质量", - "tooltip": "图像质量,影响成本和生成时间。" - }, - "seed": { - "name": "种子", - "tooltip": "后端尚未实现" - }, - "size": { - "name": "尺寸", - "tooltip": "图像尺寸" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -8196,16 +9260,16 @@ } }, "OpenAIInputFiles": { - "description": "加载并准备输入文件(文本、PDF等)作为OpenAI聊天节点的输入。生成响应时,OpenAI模型将读取这些文件。🛈 提示:可与其他OpenAI输入文件节点链式连接。", "display_name": "OpenAI ChatGPT Input Files", + "description": "加载并准备输入文件(文本、PDF等)作为OpenAI聊天节点的输入。生成响应时,OpenAI模型将读取这些文件。🛈 提示:可与其他OpenAI输入文件节点链式连接。", "inputs": { - "OPENAI_INPUT_FILES": { - "name": "OpenAI输入文件", - "tooltip": "可选的附加文件,与此节点加载的文件一起批处理。允许链式连接输入文件,以便单个消息可包含多个输入文件。" - }, "file": { "name": "文件", "tooltip": "作为模型上下文的输入文件。目前仅接受文本(.txt)和PDF(.pdf)文件。" + }, + "OPENAI_INPUT_FILES": { + "name": "OpenAI输入文件", + "tooltip": "可选的附加文件,与此节点加载的文件一起批处理。允许链式连接输入文件,以便单个消息可包含多个输入文件。" } }, "outputs": { @@ -8215,18 +9279,9 @@ } }, "OpenAIVideoSora2": { - "description": "OpenAI视频和音频生成。", "display_name": "OpenAI Sora - Video", + "description": "OpenAI视频和音频生成。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长" - }, - "image": { - "name": "图像" - }, "model": { "name": "模型" }, @@ -8234,12 +9289,21 @@ "name": "提示词", "tooltip": "引导文本;如果存在输入图像,可为空。" }, + "size": { + "name": "尺寸" + }, + "duration": { + "name": "时长" + }, + "image": { + "name": "图像" + }, "seed": { "name": "随机种", "tooltip": "确定节点是否应重新运行的种子;无论种子如何,实际结果都是非确定性的。" }, - "size": { - "name": "尺寸" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -8251,14 +9315,14 @@ "OptimalStepsScheduler": { "display_name": "OptimalSteps调度器", "inputs": { - "denoise": { - "name": "去噪" - }, "model_type": { "name": "模型" }, "steps": { "name": "步数" + }, + "denoise": { + "name": "去噪" } }, "outputs": { @@ -8270,17 +9334,17 @@ "PairConditioningCombine": { "display_name": "条件对合并", "inputs": { - "negative_A": { - "name": "负面条件_A" - }, - "negative_B": { - "name": "负面条件_B" - }, "positive_A": { "name": "正面条件_A" }, + "negative_A": { + "name": "负面条件_A" + }, "positive_B": { "name": "正面条件_B" + }, + "negative_B": { + "name": "负面条件_B" } }, "outputs": { @@ -8295,20 +9359,20 @@ "PairConditioningSetDefaultCombine": { "display_name": "条件对设置默认合并", "inputs": { - "hooks": { - "name": "约束" + "positive": { + "name": "正面条件" }, "negative": { "name": "负面条件" }, + "positive_DEFAULT": { + "name": "默认正面条件" + }, "negative_DEFAULT": { "name": "默认负面条件" }, - "positive": { - "name": "正面条件" - }, - "positive_DEFAULT": { - "name": "默认正面条件" + "hooks": { + "name": "约束" } }, "outputs": { @@ -8323,23 +9387,23 @@ "PairConditioningSetProperties": { "display_name": "条件对设置属性", "inputs": { - "hooks": { - "name": "约束" - }, - "mask": { - "name": "遮罩" + "positive_NEW": { + "name": "新正面条件" }, "negative_NEW": { "name": "新负面条件" }, - "positive_NEW": { - "name": "新正面条件" + "strength": { + "name": "强度" }, "set_cond_area": { "name": "设置条件区域" }, - "strength": { - "name": "强度" + "mask": { + "name": "遮罩" + }, + "hooks": { + "name": "约束" }, "timesteps": { "name": "间隔" @@ -8357,29 +9421,29 @@ "PairConditioningSetPropertiesAndCombine": { "display_name": "条件对设置属性合并", "inputs": { - "hooks": { - "name": "约束" - }, - "mask": { - "name": "遮罩" + "positive": { + "name": "正面条件" }, "negative": { "name": "负面条件" }, + "positive_NEW": { + "name": "新正面条件" + }, "negative_NEW": { "name": "新负面条件" }, - "positive": { - "name": "正面条件" - }, - "positive_NEW": { - "name": "新正面条件" + "strength": { + "name": "强度" }, "set_cond_area": { "name": "设置条件区域" }, - "strength": { - "name": "强度" + "mask": { + "name": "遮罩" + }, + "hooks": { + "name": "约束" }, "timesteps": { "name": "间隔" @@ -8397,26 +9461,26 @@ "PatchModelAddDownscale": { "display_name": "收缩模型UNET(Kohya Deep Shrink)", "inputs": { + "model": { + "name": "模型" + }, "block_number": { "name": "层编号" }, - "downscale_after_skip": { - "name": "跳过后收缩" - }, "downscale_factor": { "name": "收缩系数" }, - "downscale_method": { - "name": "收缩算法" + "start_percent": { + "name": "开始百分比" }, "end_percent": { "name": "结束百分比" }, - "model": { - "name": "模型" + "downscale_after_skip": { + "name": "跳过后收缩" }, - "start_percent": { - "name": "开始百分比" + "downscale_method": { + "name": "收缩算法" }, "upscale_method": { "name": "放大方法" @@ -8431,12 +9495,12 @@ "PerpNeg": { "display_name": "Perp-Neg(已弃用,使用PerpNegGuider)", "inputs": { - "empty_conditioning": { - "name": "空条件" - }, "model": { "name": "模型" }, + "empty_conditioning": { + "name": "空条件" + }, "neg_scale": { "name": "负面缩放" } @@ -8450,23 +9514,23 @@ "PerpNegGuider": { "display_name": "PerpNeg引导器", "inputs": { - "cfg": { - "name": "cfg" - }, - "empty_conditioning": { - "name": "空条件" - }, "model": { "name": "模型" }, - "neg_scale": { - "name": "负面缩放" + "positive": { + "name": "正面条件" }, "negative": { "name": "负面条件" }, - "positive": { - "name": "正面条件" + "empty_conditioning": { + "name": "空条件" + }, + "cfg": { + "name": "cfg" + }, + "neg_scale": { + "name": "负面缩放" } }, "outputs": { @@ -8494,14 +9558,14 @@ "PhotoMakerEncode": { "display_name": "PhotoMaker编码", "inputs": { - "clip": { - "name": "clip" + "photomaker": { + "name": "photomaker" }, "image": { "name": "图像" }, - "photomaker": { - "name": "photomaker" + "clip": { + "name": "clip" }, "text": { "name": "文本" @@ -8526,281 +9590,30 @@ } } }, - "PikaImageToVideoNode2_2": { - "description": "将图像和提示词发送到 Pika API v2.2 以生成视频。", - "display_name": "Pika 图像转视频", - "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长" - }, - "image": { - "name": "图像", - "tooltip": "要转换为视频的图像" - }, - "negative_prompt": { - "name": "反向提示词" - }, - "prompt_text": { - "name": "提示词" - }, - "resolution": { - "name": "分辨率" - }, - "seed": { - "name": "种子" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, - "PikaScenesV2_2": { - "description": "将你的图像组合在一起,生成包含所有物体的高质量视频。上传多张图片作为素材,生成融合所有内容的视频。", - "display_name": "Pika 场景(视频图像合成)", - "inputs": { - "aspect_ratio": { - "name": "宽高比", - "tooltip": "宽高比(宽 / 高)" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长" - }, - "image_ingredient_1": { - "name": "图片素材 1", - "tooltip": "用于生成视频的图片素材。" - }, - "image_ingredient_2": { - "name": "图片素材 2", - "tooltip": "用于生成视频的图片素材。" - }, - "image_ingredient_3": { - "name": "图片素材 3", - "tooltip": "用于生成视频的图片素材。" - }, - "image_ingredient_4": { - "name": "图片素材 4", - "tooltip": "用于生成视频的图片素材。" - }, - "image_ingredient_5": { - "name": "图片素材 5", - "tooltip": "用于生成视频的图片素材。" - }, - "ingredients_mode": { - "name": "素材模式" - }, - "negative_prompt": { - "name": "反向提示词" - }, - "prompt_text": { - "name": "提示词" - }, - "resolution": { - "name": "分辨率" - }, - "seed": { - "name": "随机种子" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, - "PikaStartEndFrameNode2_2": { - "description": "通过合成首帧和尾帧生成视频。上传两张图片以定义起点和终点,让 AI 在它们之间创建平滑过渡。", - "display_name": "Pika 首尾帧合成视频", - "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长" - }, - "image_end": { - "name": "结束图像", - "tooltip": "要合成的最后一张图片。" - }, - "image_start": { - "name": "起始图像", - "tooltip": "要合成的第一张图片。" - }, - "negative_prompt": { - "name": "负面提示词" - }, - "prompt_text": { - "name": "提示词" - }, - "resolution": { - "name": "分辨率" - }, - "seed": { - "name": "随机种" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, - "PikaTextToVideoNode2_2": { - "description": "将文本提示发送到 Pika API v2.2 以生成视频。", - "display_name": "Pika 文本转视频", - "inputs": { - "aspect_ratio": { - "name": "宽高比", - "tooltip": "宽高比(宽 / 高)" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长" - }, - "negative_prompt": { - "name": "反向提示" - }, - "prompt_text": { - "name": "提示文本" - }, - "resolution": { - "name": "分辨率" - }, - "seed": { - "name": "种子" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, - "Pikadditions": { - "description": "将任意对象或图像添加到你的视频中。上传一个视频并指定你想要添加的内容,实现无缝集成的效果。", - "display_name": "Pikadditions(视频对象插入)", - "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "image": { - "name": "图像", - "tooltip": "要添加到视频中的图像。" - }, - "negative_prompt": { - "name": "反向提示词" - }, - "prompt_text": { - "name": "提示词" - }, - "seed": { - "name": "种子" - }, - "video": { - "name": "视频", - "tooltip": "要添加图像的视频。" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, - "Pikaffects": { - "description": "生成带有特定Pikaffect的视频。支持的Pikaffect有:Cake-ify、Crumble、Crush、Decapitate、Deflate、Dissolve、Explode、Eye-pop、Inflate、Levitate、Melt、Peel、Poke、Squish、Ta-da、Tear", - "display_name": "Pikaffects(视频特效)", - "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "image": { - "name": "图像", - "tooltip": "要应用Pikaffect的参考图像。" - }, - "negative_prompt": { - "name": "负面提示词" - }, - "pikaffect": { - "name": "pikaffect" - }, - "prompt_text": { - "name": "提示词" - }, - "seed": { - "name": "随机种" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, - "Pikaswaps": { - "description": "用新图像或对象替换视频中的任意对象或区域。可通过 mask 或坐标定义需要替换的区域。", - "display_name": "Pika Swaps(视频对象替换)", - "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "image": { - "name": "图像", - "tooltip": "用于替换视频中被 mask 的对象的图像。" - }, - "mask": { - "name": "遮罩", - "tooltip": "使用 mask 定义视频中需要替换的区域" - }, - "negative_prompt": { - "name": "反向提示词" - }, - "prompt_text": { - "name": "提示词" - }, - "region_to_modify": { - "name": "修改区域", - "tooltip": "要修改的对象/区域的纯文本描述。" - }, - "seed": { - "name": "种子" - }, - "video": { - "name": "视频", - "tooltip": "要在其中替换对象的视频。" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, "PixverseImageToVideoNode": { - "description": "根据提示词和输出尺寸同步生成视频。", "display_name": "PixVerse 图像转视频", + "description": "根据提示词和输出尺寸同步生成视频。", "inputs": { - "control_after_generate": { - "name": "生成后控制" + "image": { + "name": "图像" + }, + "prompt": { + "name": "提示词", + "tooltip": "用于视频生成的提示词" + }, + "quality": { + "name": "质量" }, "duration_seconds": { "name": "时长(秒)" }, - "image": { - "name": "图像" - }, "motion_mode": { "name": "运动模式" }, + "seed": { + "name": "种子", + "tooltip": "用于视频生成的种子。" + }, "negative_prompt": { "name": "反向提示词", "tooltip": "可选的文本描述,用于指定图像中不希望出现的元素。" @@ -8809,16 +9622,8 @@ "name": "PixVerse 模板", "tooltip": "可选模板,由 PixVerse Template 节点创建,用于影响生成风格。" }, - "prompt": { - "name": "提示词", - "tooltip": "用于视频生成的提示词" - }, - "quality": { - "name": "质量" - }, - "seed": { - "name": "种子", - "tooltip": "用于视频生成的种子。" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -8842,14 +9647,18 @@ } }, "PixverseTextToVideoNode": { - "description": "根据提示词和输出尺寸同步生成视频。", "display_name": "PixVerse 文本转视频", + "description": "根据提示词和输出尺寸同步生成视频。", "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "用于视频生成的提示词" + }, "aspect_ratio": { "name": "宽高比" }, - "control_after_generate": { - "name": "生成后控制" + "quality": { + "name": "质量" }, "duration_seconds": { "name": "时长(秒)" @@ -8857,6 +9666,10 @@ "motion_mode": { "name": "运动模式" }, + "seed": { + "name": "种子", + "tooltip": "用于视频生成的种子。" + }, "negative_prompt": { "name": "反向提示词", "tooltip": "用于描述图像中不希望出现元素的可选文本。" @@ -8865,16 +9678,8 @@ "name": "PixVerse 模板", "tooltip": "可选模板,用于影响生成风格,由 PixVerse Template 节点创建。" }, - "prompt": { - "name": "提示词", - "tooltip": "用于视频生成的提示词" - }, - "quality": { - "name": "质量" - }, - "seed": { - "name": "种子", - "tooltip": "用于视频生成的种子。" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -8884,28 +9689,15 @@ } }, "PixverseTransitionVideoNode": { - "description": "根据提示词和输出尺寸同步生成视频。", "display_name": "PixVerse 转场视频", + "description": "根据提示词和输出尺寸同步生成视频。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "duration_seconds": { - "name": "时长(秒)" - }, "first_frame": { "name": "首帧" }, "last_frame": { "name": "末帧" }, - "motion_mode": { - "name": "运动模式" - }, - "negative_prompt": { - "name": "反向提示词", - "tooltip": "用于描述图像中不希望出现元素的可选文本。" - }, "prompt": { "name": "提示词", "tooltip": "用于视频生成的提示词" @@ -8913,9 +9705,22 @@ "quality": { "name": "质量" }, + "duration_seconds": { + "name": "时长(秒)" + }, + "motion_mode": { + "name": "运动模式" + }, "seed": { "name": "种子", "tooltip": "用于视频生成的种子。" + }, + "negative_prompt": { + "name": "反向提示词", + "tooltip": "用于描述图像中不希望出现元素的可选文本。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -8927,8 +9732,8 @@ "PolyexponentialScheduler": { "display_name": "Polyexponential调度器", "inputs": { - "rho": { - "name": "rho" + "steps": { + "name": "步数" }, "sigma_max": { "name": "sigma最大值" @@ -8936,14 +9741,25 @@ "sigma_min": { "name": "sigma最小值" }, - "steps": { - "name": "步数" + "rho": { + "name": "rho" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "PorterDuffImageComposite": { "display_name": "Porter-Duff图像合成", "inputs": { + "source": { + "name": "来源图像" + }, + "source_alpha": { + "name": "来源图像alpha" + }, "destination": { "name": "目标图像" }, @@ -8952,12 +9768,6 @@ }, "mode": { "name": "模式" - }, - "source": { - "name": "来源图像" - }, - "source_alpha": { - "name": "来源图像alpha" } }, "outputs": { @@ -8972,25 +9782,28 @@ "Preview3D": { "display_name": "预览3D", "inputs": { + "model_file": { + "name": "模型文件" + }, "camera_info": { "name": "相机信息" }, + "bg_image": { + "name": "背景图像" + }, "image": { "name": "图像" - }, - "model_file": { - "name": "模型文件" } } }, "PreviewAny": { "display_name": "预览任意", "inputs": { - "preview": { - }, "source": { "name": "源" - } + }, + "preview": {}, + "previewMode": {} } }, "PreviewAudio": { @@ -9005,8 +9818,8 @@ } }, "PreviewImage": { - "description": "将输入图像保存到您的ComfyUI临时目录。", "display_name": "预览图像", + "description": "将输入图像保存到您的ComfyUI临时目录。", "inputs": { "images": { "name": "图像" @@ -9042,11 +9855,11 @@ "PrimitiveInt": { "display_name": "整数", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, "value": { "name": "数值" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -9082,8 +9895,8 @@ } }, "QuadrupleCLIPLoader": { - "description": "[配方]\n\nhidream: long clip-l, long clip-g, t5xxl, llama_8b_3.1_instruct", "display_name": "四重CLIP加载器", + "description": "[配方]\n\nhidream: long clip-l, long clip-g, t5xxl, llama_8b_3.1_instruct", "inputs": { "clip_name1": { "name": "clip_name1" @@ -9107,45 +9920,80 @@ "QwenImageDiffsynthControlnet": { "display_name": "QwenImageDiffsynthControlnet", "inputs": { - "image": { - "name": "图像" - }, - "mask": { - "name": "遮罩" - }, "model": { "name": "模型" }, "model_patch": { "name": "模型补丁" }, + "vae": { + "name": "vae" + }, + "image": { + "name": "图像" + }, "strength": { "name": "强度" }, - "vae": { - "name": "vae" + "mask": { + "name": "遮罩" + } + } + }, + "RandomCropImages": { + "display_name": "裁剪图像(随机)", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要处理的图像序列。" + }, + "width": { + "name": "宽度", + "tooltip": "裁剪框宽度" + }, + "height": { + "name": "高度", + "tooltip": "裁剪框高度" + }, + "seed": { + "name": "随机种", + "tooltip": "随机种" + }, + "control_after_generate": { + "name": "生成后控制" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "已处理的图像" } } }, "RandomNoise": { "display_name": "随机噪波", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, "noise_seed": { "name": "噪波随机种" + }, + "control_after_generate": { + "name": "生成后控制" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "RebatchImages": { "display_name": "重设图像批次", "inputs": { - "batch_size": { - "name": "批量大小" - }, "images": { "name": "图像" + }, + "batch_size": { + "name": "批量大小" } }, "outputs": { @@ -9157,11 +10005,11 @@ "RebatchLatents": { "display_name": "重设Latent批次", "inputs": { - "batch_size": { - "name": "批量大小" - }, "latents": { "name": "Latent因素" + }, + "batch_size": { + "name": "批量大小" } }, "outputs": { @@ -9176,23 +10024,28 @@ "audio": { "name": "音频" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "RecraftColorRGB": { - "description": "通过选择特定的 RGB 值来创建 Recraft 颜色。", "display_name": "Recraft 颜色 RGB", + "description": "通过选择特定的 RGB 值来创建 Recraft 颜色。", "inputs": { - "b": { - "name": "b", - "tooltip": "颜色的蓝色值。" + "r": { + "name": "r", + "tooltip": "颜色的红色值。" }, "g": { "name": "g", "tooltip": "颜色的绿色值。" }, - "r": { - "name": "r", - "tooltip": "颜色的红色值。" + "b": { + "name": "b", + "tooltip": "颜色的蓝色值。" }, "recraft_color": { "name": "Recraft色彩" @@ -9206,14 +10059,14 @@ } }, "RecraftControls": { - "description": "创建 Recraft 控件以自定义 Recraft 生成。", "display_name": "Recraft 控件", + "description": "创建 Recraft 控件以自定义 Recraft 生成。", "inputs": { - "background_color": { - "name": "背景色" - }, "colors": { "name": "色彩" + }, + "background_color": { + "name": "背景色" } }, "outputs": { @@ -9224,8 +10077,8 @@ } }, "RecraftCreativeUpscaleNode": { - "description": "同步放大图像。\n使用“创意放大”工具增强给定的光栅图像,提升分辨率,重点优化细节和人脸。", "display_name": "Recraft 创意放大图像", + "description": "同步放大图像。\n使用“创意放大”工具增强给定的光栅图像,提升分辨率,重点优化细节和人脸。", "inputs": { "image": { "name": "图像" @@ -9238,8 +10091,8 @@ } }, "RecraftCrispUpscaleNode": { - "description": "同步放大图像。\n使用“清晰放大”工具增强给定的光栅图像,提高图像分辨率,使图像更加锐利和干净。", "display_name": "Recraft 清晰放大图像", + "description": "同步放大图像。\n使用“清晰放大”工具增强给定的光栅图像,提高图像分辨率,使图像更加锐利和干净。", "inputs": { "image": { "name": "图像" @@ -9252,36 +10105,36 @@ } }, "RecraftImageInpaintingNode": { - "description": "根据提示词和 mask 修改图像。", "display_name": "Recraft 图像修复", + "description": "根据提示词和 mask 修改图像。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, "image": { "name": "图像" }, "mask": { "name": "遮罩" }, + "prompt": { + "name": "提示词", + "tooltip": "用于图像生成的提示词。" + }, "n": { "name": "数量", "tooltip": "要生成的图像数量。" }, + "seed": { + "name": "种子", + "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" + }, + "recraft_style": { + "name": "Recraft风格" + }, "negative_prompt": { "name": "反向提示词", "tooltip": "对图像中不希望出现元素的可选文本描述。" }, - "prompt": { - "name": "提示词", - "tooltip": "用于图像生成的提示词。" - }, - "recraft_style": { - "name": "Recraft风格" - }, - "seed": { - "name": "种子", - "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -9291,41 +10144,41 @@ } }, "RecraftImageToImageNode": { - "description": "根据提示词和强度修改图像。", "display_name": "Recraft 图像到图像", + "description": "根据提示词和强度修改图像。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, "image": { "name": "图像" }, - "n": { - "name": "数量", - "tooltip": "要生成的图像数量。" - }, - "negative_prompt": { - "name": "反向提示词", - "tooltip": "可选的文本描述,用于指定图像中不希望出现的元素。" - }, "prompt": { "name": "提示词", "tooltip": "用于生成图像的提示词。" }, - "recraft_controls": { - "name": "Recraft控制", - "tooltip": "通过 Recraft Controls 节点对生成过程进行可选的附加控制。" + "n": { + "name": "数量", + "tooltip": "要生成的图像数量。" }, - "recraft_style": { - "name": "Recraft风格" + "strength": { + "name": "强度", + "tooltip": "定义与原始图像的差异,范围为[0, 1],0表示几乎相同,1表示极大不同。" }, "seed": { "name": "种子", "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" }, - "strength": { - "name": "强度", - "tooltip": "定义与原始图像的差异,范围为[0, 1],0表示几乎相同,1表示极大不同。" + "recraft_style": { + "name": "Recraft风格" + }, + "negative_prompt": { + "name": "反向提示词", + "tooltip": "可选的文本描述,用于指定图像中不希望出现的元素。" + }, + "recraft_controls": { + "name": "Recraft控制", + "tooltip": "通过 Recraft Controls 节点对生成过程进行可选的附加控制。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -9335,8 +10188,8 @@ } }, "RecraftRemoveBackgroundNode": { - "description": "从图像中移除背景,返回处理后的图像和 mask。", "display_name": "Recraft 移除背景", + "description": "从图像中移除背景,返回处理后的图像和 mask。", "inputs": { "image": { "name": "图像" @@ -9352,33 +10205,33 @@ } }, "RecraftReplaceBackgroundNode": { - "description": "根据提供的提示词替换图像背景。", "display_name": "Recraft 更换背景", + "description": "根据提供的提示词替换图像背景。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, "image": { "name": "图像" }, - "n": { - "name": "数量", - "tooltip": "要生成的图像数量。" - }, - "negative_prompt": { - "name": "反向提示词", - "tooltip": "对图像中不希望出现元素的可选文本描述。" - }, "prompt": { "name": "提示词", "tooltip": "用于图像生成的提示词。" }, - "recraft_style": { - "name": "recraft 风格" + "n": { + "name": "数量", + "tooltip": "要生成的图像数量。" }, "seed": { "name": "种子", "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" + }, + "recraft_style": { + "name": "recraft 风格" + }, + "negative_prompt": { + "name": "反向提示词", + "tooltip": "对图像中不希望出现元素的可选文本描述。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -9388,8 +10241,8 @@ } }, "RecraftStyleV3DigitalIllustration": { - "description": "选择 realistic_image 风格和可选的子风格。", "display_name": "Recraft 风格 - 数字插画", + "description": "选择 realistic_image 风格和可选的子风格。", "inputs": { "substyle": { "name": "子风格" @@ -9403,8 +10256,8 @@ } }, "RecraftStyleV3InfiniteStyleLibrary": { - "description": "根据 Recraft 的无限风格库中已有的 UUID 选择风格。", "display_name": "Recraft 风格 - 无限风格库", + "description": "根据 Recraft 的无限风格库中已有的 UUID 选择风格。", "inputs": { "style_id": { "name": "风格ID", @@ -9419,8 +10272,8 @@ } }, "RecraftStyleV3LogoRaster": { - "description": "选择 realistic_image 风格和可选的子风格。", "display_name": "Recraft 风格 - 标志光栅图", + "description": "选择 realistic_image 风格和可选的子风格。", "inputs": { "substyle": { "name": "子风格" @@ -9434,8 +10287,8 @@ } }, "RecraftStyleV3RealisticImage": { - "description": "选择 realistic_image 风格和可选的子风格。", "display_name": "Recraft 风格 - 真实图像", + "description": "选择 realistic_image 风格和可选的子风格。", "inputs": { "substyle": { "name": "子风格" @@ -9449,38 +10302,38 @@ } }, "RecraftTextToImageNode": { - "description": "根据提示词和分辨率同步生成图像。", "display_name": "Recraft 文本转图像", + "description": "根据提示词和分辨率同步生成图像。", "inputs": { - "control_after_generate": { - "name": "生成后控制" + "prompt": { + "name": "提示词", + "tooltip": "用于图像生成的提示词。" + }, + "size": { + "name": "尺寸", + "tooltip": "生成图像的尺寸。" }, "n": { "name": "n", "tooltip": "要生成的图像数量。" }, + "seed": { + "name": "随机种", + "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" + }, + "recraft_style": { + "name": "Recraft风格" + }, "negative_prompt": { "name": "负面提示词", "tooltip": "对图像中不希望出现元素的可选文本描述。" }, - "prompt": { - "name": "提示词", - "tooltip": "用于图像生成的提示词。" - }, "recraft_controls": { "name": "Recraft控制", "tooltip": "通过 Recraft Controls 节点对生成过程的可选附加控制。" }, - "recraft_style": { - "name": "Recraft风格" - }, - "seed": { - "name": "随机种", - "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" - }, - "size": { - "name": "尺寸", - "tooltip": "生成图像的尺寸。" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -9490,38 +10343,38 @@ } }, "RecraftTextToVectorNode": { - "description": "根据提示词和分辨率同步生成 SVG。", "display_name": "Recraft 文本转矢量", + "description": "根据提示词和分辨率同步生成 SVG。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "n": { - "name": "数量", - "tooltip": "要生成的图像数量。" - }, - "negative_prompt": { - "name": "反向提示词", - "tooltip": "对图像中不希望出现元素的可选文本描述。" - }, "prompt": { "name": "提示词", "tooltip": "用于生成图像的提示词。" }, - "recraft_controls": { - "name": "Recraft 控制", - "tooltip": "通过 Recraft Controls 节点对生成过程的可选附加控制。" - }, - "seed": { - "name": "种子", - "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" + "substyle": { + "name": "子风格" }, "size": { "name": "尺寸", "tooltip": "生成图像的尺寸。" }, - "substyle": { - "name": "子风格" + "n": { + "name": "数量", + "tooltip": "要生成的图像数量。" + }, + "seed": { + "name": "种子", + "tooltip": "用于决定节点是否重新运行的种子;无论种子如何,实际结果都是非确定性的。" + }, + "negative_prompt": { + "name": "反向提示词", + "tooltip": "对图像中不希望出现元素的可选文本描述。" + }, + "recraft_controls": { + "name": "Recraft 控制", + "tooltip": "通过 Recraft Controls 节点对生成过程的可选附加控制。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -9531,8 +10384,8 @@ } }, "RecraftVectorizeImageNode": { - "description": "从输入图像同步生成 SVG。", "display_name": "Recraft 矢量化图像", + "description": "从输入图像同步生成 SVG。", "inputs": { "image": { "name": "图像" @@ -9545,8 +10398,8 @@ } }, "ReferenceLatent": { - "description": "此节点为编辑模型设置引导潜在空间。如果模型支持,您可以链式连接多个以设置多个参考图像。", "display_name": "参考Latent", + "description": "此节点为编辑模型设置引导潜在空间。如果模型支持,您可以链式连接多个以设置多个参考图像。", "inputs": { "conditioning": { "name": "条件" @@ -9564,26 +10417,26 @@ "RegexExtract": { "display_name": "正则表达式提取", "inputs": { + "string": { + "name": "字符串" + }, + "regex_pattern": { + "name": "正则表达式模式" + }, + "mode": { + "name": "模式" + }, "case_insensitive": { "name": "忽略大小写" }, + "multiline": { + "name": "多行模式" + }, "dotall": { "name": "点号匹配所有" }, "group_index": { "name": "分组索引" - }, - "mode": { - "name": "模式" - }, - "multiline": { - "name": "多行模式" - }, - "regex_pattern": { - "name": "正则表达式模式" - }, - "string": { - "name": "字符串" } }, "outputs": { @@ -9595,20 +10448,20 @@ "RegexMatch": { "display_name": "正则表达式匹配", "inputs": { - "case_insensitive": { - "name": "忽略大小写" - }, - "dotall": { - "name": "点号匹配所有" - }, - "multiline": { - "name": "多行模式" + "string": { + "name": "字符串" }, "regex_pattern": { "name": "正则表达式模式" }, - "string": { - "name": "字符串" + "case_insensitive": { + "name": "忽略大小写" + }, + "multiline": { + "name": "多行模式" + }, + "dotall": { + "name": "点号匹配所有" } }, "outputs": { @@ -9619,22 +10472,11 @@ } }, "RegexReplace": { - "description": "使用正则表达式模式查找和替换文本。", "display_name": "正则表达式替换", + "description": "使用正则表达式模式查找和替换文本。", "inputs": { - "case_insensitive": { - "name": "忽略大小写" - }, - "count": { - "name": "计数", - "tooltip": "最大替换次数。设置为0可替换所有匹配项(默认)。设置为1仅替换第一个匹配项,2替换前两个匹配项,依此类推。" - }, - "dotall": { - "name": "点号匹配所有", - "tooltip": "启用时,点号(.)字符将匹配包括换行符在内的任何字符。禁用时,点号不会匹配换行符。" - }, - "multiline": { - "name": "多行模式" + "string": { + "name": "字符串" }, "regex_pattern": { "name": "正则表达式模式" @@ -9642,8 +10484,19 @@ "replace": { "name": "替换内容" }, - "string": { - "name": "字符串" + "case_insensitive": { + "name": "忽略大小写" + }, + "multiline": { + "name": "多行模式" + }, + "dotall": { + "name": "点号匹配所有", + "tooltip": "启用时,点号(.)字符将匹配包括换行符在内的任何字符。禁用时,点号不会匹配换行符。" + }, + "count": { + "name": "计数", + "tooltip": "最大替换次数。设置为0可替换所有匹配项(默认)。设置为1仅替换第一个匹配项,2替换前两个匹配项,依此类推。" } }, "outputs": { @@ -9655,12 +10508,12 @@ "RenormCFG": { "display_name": "RenormCFG", "inputs": { - "cfg_trunc": { - "name": "cfg_trunc" - }, "model": { "name": "模型" }, + "cfg_trunc": { + "name": "cfg_trunc" + }, "renorm_cfg": { "name": "renorm_cfg" } @@ -9674,22 +10527,72 @@ "RepeatImageBatch": { "display_name": "复制图像批次", "inputs": { - "amount": { - "name": "数量" - }, "image": { "name": "图像" + }, + "amount": { + "name": "数量" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "RepeatLatentBatch": { "display_name": "复制Latent批次", "inputs": { - "amount": { - "name": "数量" - }, "samples": { "name": "Latent" + }, + "amount": { + "name": "数量" + } + } + }, + "ReplaceText": { + "display_name": "替换文本", + "inputs": { + "texts": { + "name": "文本", + "tooltip": "需要处理的文本" + }, + "find": { + "name": "搜索", + "tooltip": "需要被替换的文本" + }, + "replace": { + "name": "替换", + "tooltip": "用于替换的文本" + } + }, + "outputs": { + "0": { + "name": "文本", + "tooltip": "已处理的文本" + } + } + }, + "ReplaceVideoLatentFrames": { + "display_name": "替换视频Latent", + "inputs": { + "destination": { + "name": "目标Latent", + "tooltip": "需要被替换的 Latent" + }, + "index": { + "name": "序号", + "tooltip": "选择需要被替换的 Latent 的序号,负值表示从后往前数。" + }, + "source": { + "name": "来源Latent", + "tooltip": "用于替换的 Latent,如果没有则不会替换。" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, @@ -9710,35 +10613,101 @@ "image": { "name": "图像" }, - "interpolation": { - "name": "插值方法" - }, - "padding_color": { - "name": "填充颜色" + "target_width": { + "name": "目标宽度" }, "target_height": { "name": "目标高度" }, - "target_width": { - "name": "目标宽度" + "padding_color": { + "name": "填充颜色" + }, + "interpolation": { + "name": "插值方法" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "ResizeImagesByLongerEdge": { + "display_name": "缩放图像(长边)", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要处理的图像序列。" + }, + "longer_edge": { + "name": "长边", + "tooltip": "长边目标长度。" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "已处理的图像" + } + } + }, + "ResizeImagesByShorterEdge": { + "display_name": "Resize Images by Shorter Edge", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要处理的图像序列。" + }, + "shorter_edge": { + "name": "短边", + "tooltip": "短边目标长度。" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "已处理的图像" + } + } + }, + "ResolutionBucket": { + "display_name": "分辨率 Bucket", + "inputs": { + "latents": { + "name": "Latent", + "tooltip": "需要 bucket 的 Latent 字典序列" + }, + "conditioning": { + "name": "条件", + "tooltip": "条件序列(必须和 Latent 序列数量相同)" + } + }, + "outputs": { + "0": { + "name": "Latent", + "tooltip": "Latent 字典,按分辨率分批。" + }, + "1": { + "name": "条件", + "tooltip": "条件字典,按分辨率分批。" } } }, "Rodin3D_Detail": { - "description": "使用Rodin API生成3D资源", "display_name": "Rodin 3D生成 - 细节生成", + "description": "使用Rodin API生成3D资源", "inputs": { "Images": { "name": "图像" }, + "Seed": { + "name": "种子" + }, "Material_Type": { "name": "材质类型" }, "Polygon_count": { "name": "多边形数量" - }, - "Seed": { - "name": "种子" } }, "outputs": { @@ -9749,23 +10718,23 @@ } }, "Rodin3D_Gen2": { - "description": "使用Rodin API生成3D资源", "display_name": "Rodin 3D生成 - Gen-2生成", + "description": "使用Rodin API生成3D资源", "inputs": { "Images": { "name": "图像" }, + "TAPose": { + "name": "TAPose" + }, + "Seed": { + "name": "种子" + }, "Material_Type": { "name": "材质类型" }, "Polygon_count": { "name": "多边形数量" - }, - "Seed": { - "name": "种子" - }, - "TAPose": { - "name": "TAPose" } }, "outputs": { @@ -9776,20 +10745,20 @@ } }, "Rodin3D_Regular": { - "description": "使用Rodin API生成3D资源", "display_name": "Rodin 3D生成 - 常规生成", + "description": "使用Rodin API生成3D资源", "inputs": { "Images": { "name": "图像" }, + "Seed": { + "name": "种子" + }, "Material_Type": { "name": "材质类型" }, "Polygon_count": { "name": "多边形数量" - }, - "Seed": { - "name": "种子" } }, "outputs": { @@ -9800,8 +10769,8 @@ } }, "Rodin3D_Sketch": { - "description": "使用Rodin API生成3D资源", "display_name": "Rodin 3D生成 - 草图生成", + "description": "使用Rodin API生成3D资源", "inputs": { "Images": { "name": "图像" @@ -9818,20 +10787,20 @@ } }, "Rodin3D_Smooth": { - "description": "使用Rodin API生成3D资源", "display_name": "Rodin 3D生成 - 平滑生成", + "description": "使用Rodin API生成3D资源", "inputs": { "Images": { "name": "图像" }, + "Seed": { + "name": "种子" + }, "Material_Type": { "name": "材质类型" }, "Polygon_count": { "name": "多边形数量" - }, - "Seed": { - "name": "种子" } }, "outputs": { @@ -9842,22 +10811,23 @@ } }, "RunwayFirstLastFrameNode": { - "description": "上传首尾关键帧,草拟提示词,生成视频。对于更复杂的过渡(例如尾帧与首帧完全不同的情况),较长的10秒时长可能更有利,这能为生成过程提供更多时间在两个输入之间平滑过渡。开始前,请查看这些最佳实践以确保您的输入选择能为生成成功奠定基础:https://help.runwayml.com/hc/en-us/articles/34170748696595-Creating-with-Keyframes-on-Gen-3。", "display_name": "Runway首尾帧转视频", + "description": "上传首尾关键帧,草拟提示词,生成视频。对于更复杂的过渡(例如尾帧与首帧完全不同的情况),较长的10秒时长可能更有利,这能为生成过程提供更多时间在两个输入之间平滑过渡。开始前,请查看这些最佳实践以确保您的输入选择能为生成成功奠定基础:https://help.runwayml.com/hc/en-us/articles/34170748696595-Creating-with-Keyframes-on-Gen-3。", "inputs": { - "control_after_generate": { - "name": "生成后控制" + "prompt": { + "name": "提示词", + "tooltip": "生成的文本提示词" }, - "duration": { - "name": "时长" + "start_frame": { + "name": "起始帧", + "tooltip": "用于视频的起始帧" }, "end_frame": { "name": "结束帧", "tooltip": "用于视频的结束帧。仅支持gen3a_turbo。" }, - "prompt": { - "name": "提示词", - "tooltip": "生成的文本提示词" + "duration": { + "name": "时长" }, "ratio": { "name": "比例" @@ -9866,9 +10836,8 @@ "name": "种子", "tooltip": "生成的随机种子" }, - "start_frame": { - "name": "起始帧", - "tooltip": "用于视频的起始帧" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -9878,19 +10847,20 @@ } }, "RunwayImageToVideoNodeGen3a": { - "description": "使用Gen3a Turbo模型从单个起始帧生成视频。开始前,请查看这些最佳实践以确保您的输入选择能为生成成功奠定基础:https://help.runwayml.com/hc/en-us/articles/33927968552339-Creating-with-Act-One-on-Gen-3-Alpha-and-Turbo。", "display_name": "Runway图像转视频(Gen3a Turbo)", + "description": "使用Gen3a Turbo模型从单个起始帧生成视频。开始前,请查看这些最佳实践以确保您的输入选择能为生成成功奠定基础:https://help.runwayml.com/hc/en-us/articles/33927968552339-Creating-with-Act-One-on-Gen-3-Alpha-and-Turbo。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长" - }, "prompt": { "name": "提示词", "tooltip": "生成的文本提示词" }, + "start_frame": { + "name": "起始帧", + "tooltip": "用于视频的起始帧" + }, + "duration": { + "name": "时长" + }, "ratio": { "name": "比例" }, @@ -9898,9 +10868,8 @@ "name": "种子", "tooltip": "生成的随机种子" }, - "start_frame": { - "name": "起始帧", - "tooltip": "用于视频的起始帧" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -9910,19 +10879,20 @@ } }, "RunwayImageToVideoNodeGen4": { - "description": "使用Gen4 Turbo模型从单个起始帧生成视频。开始前,请查看这些最佳实践以确保您的输入选择能为生成成功奠定基础:https://help.runwayml.com/hc/en-us/articles/37327109429011-Creating-with-Gen-4-Video。", "display_name": "Runway图像转视频(Gen4 Turbo)", + "description": "使用Gen4 Turbo模型从单个起始帧生成视频。开始前,请查看这些最佳实践以确保您的输入选择能为生成成功奠定基础:https://help.runwayml.com/hc/en-us/articles/37327109429011-Creating-with-Gen-4-Video。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长" - }, "prompt": { "name": "提示词", "tooltip": "生成的文本提示词" }, + "start_frame": { + "name": "起始帧", + "tooltip": "用于视频的起始帧" + }, + "duration": { + "name": "时长" + }, "ratio": { "name": "比例" }, @@ -9930,9 +10900,8 @@ "name": "种子", "tooltip": "生成的随机种子" }, - "start_frame": { - "name": "起始帧", - "tooltip": "用于视频的起始帧" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -9942,8 +10911,8 @@ } }, "RunwayTextToImageNode": { - "description": "使用 Runway 的 Gen 4 模型从文本提示生成图像。您还可以包含参考图像来引导生成过程。", "display_name": "Runway 文生图", + "description": "使用 Runway 的 Gen 4 模型从文本提示生成图像。您还可以包含参考图像来引导生成过程。", "inputs": { "prompt": { "name": "提示词", @@ -9963,257 +10932,140 @@ } } }, - "SDTurboScheduler": { - "display_name": "SDTurbo调度器", - "inputs": { - "denoise": { - "name": "降噪" - }, - "model": { - "name": "模型" - }, - "steps": { - "name": "步数" - } - } - }, - "SD_4XUpscale_Conditioning": { - "display_name": "SD_4X放大条件", - "inputs": { - "images": { - "name": "图片" - }, - "negative": { - "name": "负面条件" - }, - "noise_augmentation": { - "name": "噪波增强" - }, - "positive": { - "name": "正面条件" - }, - "scale_ratio": { - "name": "缩放比例" - } - }, - "outputs": { - "0": { - "name": "正面条件", - "tooltip": null - }, - "1": { - "name": "负面条件", - "tooltip": null - }, - "2": { - "name": "Latent", - "tooltip": null - } - } - }, - "SV3D_Conditioning": { - "display_name": "SV3D条件", - "inputs": { - "clip_vision": { - "name": "clip视觉" - }, - "elevation": { - "name": "俯仰角" - }, - "height": { - "name": "高度" - }, - "init_image": { - "name": "初始图像" - }, - "vae": { - "name": "vae" - }, - "video_frames": { - "name": "帧数" - }, - "width": { - "name": "宽度" - } - }, - "outputs": { - "0": { - "name": "正面条件", - "tooltip": null - }, - "1": { - "name": "负面条件", - "tooltip": null - }, - "2": { - "name": "Latent", - "tooltip": null - } - } - }, - "SVD_img2vid_Conditioning": { - "display_name": "SVD_img2vid条件", - "inputs": { - "augmentation_level": { - "name": "增强" - }, - "clip_vision": { - "name": "clip视觉" - }, - "fps": { - "name": "帧率" - }, - "height": { - "name": "高度" - }, - "init_image": { - "name": "初始图像" - }, - "motion_bucket_id": { - "name": "动态bucketID" - }, - "vae": { - "name": "vae" - }, - "video_frames": { - "name": "帧数" - }, - "width": { - "name": "宽度" - } - }, - "outputs": { - "0": { - "name": "正面条件" - }, - "1": { - "name": "负面条件" - }, - "2": { - "name": "Latent" - } - } - }, "SamplerCustom": { "display_name": "自定义采样器", "inputs": { - "add_noise": { - "name": "添加噪波" - }, - "cfg": { - "name": "cfg" - }, - "control_after_generate": { - "name": "生成后的控制" - }, - "latent_image": { - "name": "Latent" - }, "model": { "name": "模型" }, - "negative": { - "name": "负面条件" + "add_noise": { + "name": "添加噪波" }, "noise_seed": { "name": "噪波种子" }, + "cfg": { + "name": "cfg" + }, "positive": { "name": "正面条件" }, + "negative": { + "name": "负面条件" + }, "sampler": { "name": "采样器" }, "sigmas": { "name": "Sigmas" + }, + "latent_image": { + "name": "Latent" + }, + "control_after_generate": { + "name": "生成后的控制" } }, "outputs": { "0": { - "name": "Latent" + "name": "Latent", + "tooltip": null }, "1": { - "name": "降噪Latent" + "name": "降噪Latent", + "tooltip": null } } }, "SamplerCustomAdvanced": { "display_name": "自定义采样器(高级)", "inputs": { - "guider": { - "name": "引导器" - }, - "latent_image": { - "name": "Latent图像" - }, "noise": { "name": "噪波" }, + "guider": { + "name": "引导器" + }, "sampler": { "name": "采样器" }, "sigmas": { "name": "西格玛" + }, + "latent_image": { + "name": "Latent图像" } }, "outputs": { "0": { - "name": "Latent" + "name": "Latent", + "tooltip": null }, "1": { - "name": "降噪Latent" + "name": "降噪Latent", + "tooltip": null } } }, "SamplerDPMAdaptative": { "display_name": "DPMAdaptative采样器", "inputs": { - "accept_safety": { - "name": "accept_safety" - }, - "atol": { - "name": "atol" - }, - "dcoeff": { - "name": "dcoeff" - }, - "eta": { - "name": "eta" - }, - "h_init": { - "name": "h_init" - }, - "icoeff": { - "name": "icoeff" - }, "order": { "name": "order" }, - "pcoeff": { - "name": "pcoeff" - }, "rtol": { "name": "rtol" }, + "atol": { + "name": "atol" + }, + "h_init": { + "name": "h_init" + }, + "pcoeff": { + "name": "pcoeff" + }, + "icoeff": { + "name": "icoeff" + }, + "dcoeff": { + "name": "dcoeff" + }, + "accept_safety": { + "name": "accept_safety" + }, + "eta": { + "name": "eta" + }, "s_noise": { "name": "s_noise" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "SamplerDPMPP_2M_SDE": { "display_name": "DPMPP_2M_SDE采样器", "inputs": { + "solver_type": { + "name": "求解器类型" + }, "eta": { "name": "eta" }, - "noise_device": { - "name": "设备" - }, "s_noise": { "name": "s_noise" }, - "solver_type": { - "name": "求解器类型" + "noise_device": { + "name": "设备" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, @@ -10226,6 +11078,11 @@ "s_noise": { "name": "s_noise" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "SamplerDPMPP_3M_SDE": { @@ -10234,11 +11091,16 @@ "eta": { "name": "eta" }, - "noise_device": { - "name": "设备" - }, "s_noise": { "name": "s_noise" + }, + "noise_device": { + "name": "设备" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, @@ -10248,32 +11110,42 @@ "eta": { "name": "eta" }, - "noise_device": { - "name": "设备" + "s_noise": { + "name": "s_noise" }, "r": { "name": "r" }, - "s_noise": { - "name": "s_noise" + "noise_device": { + "name": "设备" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "SamplerER_SDE": { - "display_name": "SamplerER_SDE", + "display_name": "ER_SDE采样器", "inputs": { - "eta": { - "name": "eta", - "tooltip": "反向时间 SDE 的随机强度。\n当 eta=0 时,简化为确定性 ODE。此设置不适用于 ER-SDE 求解器类型。" + "solver_type": { + "name": "求解器" }, "max_stage": { "name": "最大阶段" }, + "eta": { + "name": "eta", + "tooltip": "反向时间 SDE 的随机强度。\n当 eta=0 时,简化为确定性 ODE。此设置不适用于 ER-SDE 求解器类型。" + }, "s_noise": { "name": "s_noise" - }, - "solver_type": { - "name": "求解器类型" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, @@ -10286,6 +11158,11 @@ "s_noise": { "name": "s噪波" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "SamplerEulerAncestralCFGPP": { @@ -10297,6 +11174,11 @@ "s_noise": { "name": "s噪波" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "SamplerEulerCFGpp": { @@ -10337,37 +11219,73 @@ "order": { "name": "顺序" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "SamplerSASolver": { "display_name": "SASolver采样器", "inputs": { - "corrector_order": { - "name": "校正器阶数" + "model": { + "name": "模型" }, "eta": { "name": "eta" }, - "model": { - "name": "模型" - }, - "predictor_order": { - "name": "预测器阶数" - }, - "s_noise": { - "name": "s_noise" + "sde_start_percent": { + "name": "SDE 起始百分比" }, "sde_end_percent": { "name": "SDE 结束百分比" }, - "sde_start_percent": { - "name": "SDE 起始百分比" + "s_noise": { + "name": "s_noise" }, - "simple_order_2": { - "name": "简单二阶" + "predictor_order": { + "name": "预测器阶数" + }, + "corrector_order": { + "name": "校正器阶数" }, "use_pece": { "name": "使用 PECE" + }, + "simple_order_2": { + "name": "简单二阶" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "SamplerSEEDS2": { + "display_name": "SEEDS2采样器", + "description": "该采样器节点可以表示多个采样器:\n\nseeds 2\n-默认设置\n\nexp_heun_2_x0\n- 求解器=phi 2, r=1.0, eta=0.0\n\nexp_heun_2_x0_sde\n- 求解器=phi 2, r=1.0, eta=1.0, s noise=1.0", + "inputs": { + "solver_type": { + "name": "求解器" + }, + "eta": { + "name": "eta", + "tooltip": "Stochastic strength" + }, + "s_noise": { + "name": "s_noise", + "tooltip": "SDE noise multiplier" + }, + "r": { + "name": "r", + "tooltip": "Relative step size for the intermediate stage (c2 node)" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, @@ -10377,25 +11295,26 @@ "model": { "name": "模型" }, + "sampling_percent": { + "name": "采样百分比" + }, "return_actual_sigma": { "name": "返回实际 sigma 值", "tooltip": "返回实际的 sigma 值而不是用于区间检查的值。\n这仅影响 0.0 和 1.0 处的结果。" - }, - "sampling_percent": { - "name": "采样百分比" } }, "outputs": { "0": { - "name": "sigma 值" + "name": "sigma 值", + "tooltip": null } } }, "SaveAnimatedPNG": { "display_name": "保存动画(APNG)", "inputs": { - "compress_level": { - "name": "压缩级别" + "images": { + "name": "图片" }, "filename_prefix": { "name": "文件名前缀" @@ -10403,31 +11322,31 @@ "fps": { "name": "帧率" }, - "images": { - "name": "图片" + "compress_level": { + "name": "压缩级别" } } }, "SaveAnimatedWEBP": { "display_name": "保存动画(WEBP)", "inputs": { + "images": { + "name": "图片" + }, "filename_prefix": { "name": "文件名前缀" }, "fps": { "name": "帧率" }, - "images": { - "name": "图片" - }, "lossless": { "name": "无损" }, - "method": { - "name": "方法" - }, "quality": { "name": "质量" + }, + "method": { + "name": "方法" } } }, @@ -10437,11 +11356,11 @@ "audio": { "name": "音频" }, - "audioUI": { - "name": "音频UI" - }, "filename_prefix": { "name": "文件名前缀" + }, + "audioUI": { + "name": "音频UI" } } }, @@ -10451,14 +11370,14 @@ "audio": { "name": "音频" }, - "audioUI": { - "name": "audioUI" - }, "filename_prefix": { "name": "文件名前缀" }, "quality": { "name": "质量" + }, + "audioUI": { + "name": "audioUI" } } }, @@ -10468,42 +11387,80 @@ "audio": { "name": "音频" }, - "audioUI": { - "name": "audioUI" - }, "filename_prefix": { "name": "文件名前缀" }, "quality": { "name": "质量" + }, + "audioUI": { + "name": "audioUI" } } }, "SaveGLB": { "display_name": "保存GLB", "inputs": { + "mesh": { + "name": "网格" + }, "filename_prefix": { "name": "文件名前缀" }, "image": { "name": "图像" - }, - "mesh": { - "name": "网格" } } }, "SaveImage": { - "description": "将输入图像保存到您的ComfyUI输出目录。", "display_name": "保存图像", + "description": "将输入图像保存到您的ComfyUI输出目录。", "inputs": { - "filename_prefix": { - "name": "文件名前缀", - "tooltip": "保存文件的文件名的前缀。可使用格式信息如 %date:yyyy-MM-dd% 或 %空Latent.width%,以包含来自工作流内的信息。" - }, "images": { "name": "图片", "tooltip": "要保存的图像。" + }, + "filename_prefix": { + "name": "文件名前缀", + "tooltip": "保存文件的文件名的前缀。可使用格式信息如 %date:yyyy-MM-dd% 或 %空Latent.width%,以包含来自工作流内的信息。" + } + } + }, + "SaveImageDataSetToFolder": { + "display_name": "保存图像数据集", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要保存的图像序列。" + }, + "folder_name": { + "name": "文件夹名", + "tooltip": "保存训练数据集的文件夹名(在 输出 文件夹内)。" + }, + "filename_prefix": { + "name": "文件名前缀", + "tooltip": "保存的图像的文件名前缀。" + } + } + }, + "SaveImageTextDataSetToFolder": { + "display_name": "保存图像文本数据集", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要保存的图像序列。" + }, + "texts": { + "name": "文本", + "tooltip": "需要保存的标注文本序列。" + }, + "folder_name": { + "name": "文件夹名", + "tooltip": "保存训练数据集的文件夹名(在 输出 文件夹内)。" + }, + "filename_prefix": { + "name": "文件名前缀", + "tooltip": "保存的图像的文件名前缀。" } } }, @@ -10518,34 +11475,72 @@ "SaveLatent": { "display_name": "保存Latent", "inputs": { - "filename_prefix": { - "name": "文件名前缀" - }, "samples": { "name": "Latent" + }, + "filename_prefix": { + "name": "文件名前缀" + } + } + }, + "SaveLoRA": { + "display_name": "保存 LoRA", + "inputs": { + "lora": { + "name": "LoRA", + "tooltip": "需要保存的 LoRA 模型。不要使用分层 LoRA。" + }, + "prefix": { + "name": "前缀", + "tooltip": "保存的 LoRA 文件的文件名前缀。" + }, + "steps": { + "name": "步数", + "tooltip": "可选:LoRA 的训练步数,用于保存文件命名。" } } }, "SaveSVGNode": { - "description": "在磁盘上保存 SVG 文件。", "display_name": "保存SVG", + "description": "在磁盘上保存 SVG 文件。", "inputs": { + "svg": { + "name": "svg" + }, "filename_prefix": { "name": "文件名前缀", "tooltip": "保存文件的前缀。可包含格式化信息,如 %date:yyyy-MM-dd% 或 %Empty Latent Image.width% 以包含节点中的值。" + } + } + }, + "SaveTrainingDataset": { + "display_name": "保存训练数据集", + "inputs": { + "latents": { + "name": "Latent", + "tooltip": "制作训练数据集 节点输出的 Latent 字典" }, - "svg": { - "name": "svg" + "conditioning": { + "name": "条件", + "tooltip": "制作训练数据集 节点输出的条件字典" + }, + "folder_name": { + "name": "文件夹名", + "tooltip": "包含训练数据集的文件夹名(在 输出 文件夹内)。" + }, + "shard_size": { + "name": "shard_size", + "tooltip": "Number of samples per shard file." } } }, "SaveVideo": { - "description": "将输入图像保存到您的 ComfyUI 输出目录。", "display_name": "保存视频", + "description": "将输入图像保存到您的 ComfyUI 输出目录。", "inputs": { - "codec": { - "name": "编码器", - "tooltip": "用于视频的编码器。" + "video": { + "name": "视频", + "tooltip": "要保存的视频。" }, "filename_prefix": { "name": "文件名前缀", @@ -10555,57 +11550,110 @@ "name": "格式", "tooltip": "保存视频的格式。" }, - "video": { - "name": "视频", - "tooltip": "要保存的视频。" + "codec": { + "name": "编码器", + "tooltip": "用于视频的编码器。" } } }, "SaveWEBM": { "display_name": "保存WEBM", "inputs": { - "codec": { - "name": "编解码器" - }, - "crf": { - "name": "crf", - "tooltip": "更高的crf意味着更低的质量和更小的文件大小,更低的crf意味着更高的质量和更大的文件大小。" + "images": { + "name": "图像" }, "filename_prefix": { "name": "文件名前缀" }, + "codec": { + "name": "编解码器" + }, "fps": { "name": "帧率" }, - "images": { - "name": "图像" + "crf": { + "name": "crf", + "tooltip": "更高的crf意味着更低的质量和更小的文件大小,更低的crf意味着更高的质量和更大的文件大小。" } } }, "ScaleROPE": { - "description": "缩放和偏移模型的ROPE。", "display_name": "缩放ROPE", + "description": "缩放和偏移模型的ROPE。", "inputs": { "model": { "name": "模型" }, - "scale_t": { - "name": "scale_t" - }, "scale_x": { "name": "scale_x" }, - "scale_y": { - "name": "scale_y" - }, - "shift_t": { - "name": "shift_t" - }, "shift_x": { "name": "shift_x" }, + "scale_y": { + "name": "scale_y" + }, "shift_y": { "name": "shift_y" + }, + "scale_t": { + "name": "scale_t" + }, + "shift_t": { + "name": "shift_t" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "SD_4XUpscale_Conditioning": { + "display_name": "SD_4X放大条件", + "inputs": { + "images": { + "name": "图片" + }, + "positive": { + "name": "正面条件" + }, + "negative": { + "name": "负面条件" + }, + "scale_ratio": { + "name": "缩放比例" + }, + "noise_augmentation": { + "name": "噪波增强" + } + }, + "outputs": { + "0": { + "name": "正面条件", + "tooltip": null + }, + "1": { + "name": "负面条件", + "tooltip": null + }, + "2": { + "name": "Latent", + "tooltip": null + } + } + }, + "SDTurboScheduler": { + "display_name": "SDTurbo调度器", + "inputs": { + "model": { + "name": "模型" + }, + "steps": { + "name": "步数" + }, + "denoise": { + "name": "降噪" } }, "outputs": { @@ -10617,14 +11665,14 @@ "SelfAttentionGuidance": { "display_name": "SAG自注意力引导", "inputs": { - "blur_sigma": { - "name": "模糊Sigma" - }, "model": { "name": "模型" }, "scale": { "name": "缩放" + }, + "blur_sigma": { + "name": "模糊Sigma" } }, "outputs": { @@ -10636,50 +11684,55 @@ "SetClipHooks": { "display_name": "设置CLIP约束", "inputs": { - "apply_to_conds": { - "name": "应用于条件" - }, "clip": { "name": "clip" }, - "hooks": { - "name": "约束" + "apply_to_conds": { + "name": "应用于条件" }, "schedule_clip": { "name": "安排clip" + }, + "hooks": { + "name": "约束" } } }, "SetFirstSigma": { "display_name": "设置第一个Sigma", "inputs": { - "sigma": { - "name": "sigma" - }, "sigmas": { "name": "sigmas" + }, + "sigma": { + "name": "sigma" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "SetHookKeyframes": { "display_name": "设置约束关键帧", "inputs": { - "hook_kf": { - "name": "约束关键帧" - }, "hooks": { "name": "约束" + }, + "hook_kf": { + "name": "约束关键帧" } } }, "SetLatentNoiseMask": { "display_name": "设置Latent噪波遮罩", "inputs": { - "mask": { - "name": "遮罩" - }, "samples": { "name": "Latent" + }, + "mask": { + "name": "遮罩" } } }, @@ -10699,30 +11752,82 @@ } } }, - "SkipLayerGuidanceDiT": { - "description": "通用的跳过层引导节点,可用于每个DiT模型。", - "display_name": "跳过层引导(DiT)", + "ShuffleDataset": { + "display_name": "打乱图像数据集", "inputs": { - "double_layers": { - "name": "双层" + "images": { + "name": "图像", + "tooltip": "需要处理的图像序列。" }, - "end_percent": { - "name": "结束百分比" + "seed": { + "name": "随机种", + "tooltip": "随机种" }, + "control_after_generate": { + "name": "生成后控制" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "处理后的图像" + } + } + }, + "ShuffleImageTextDataset": { + "display_name": "打乱图像文本数据集", + "inputs": { + "images": { + "name": "图像", + "tooltip": "需要打乱的图像序列。" + }, + "texts": { + "name": "文本", + "tooltip": "需要打乱的文本序列" + }, + "seed": { + "name": "随机种", + "tooltip": "随机种" + }, + "control_after_generate": { + "name": "生成后控制" + } + }, + "outputs": { + "0": { + "name": "图像", + "tooltip": "打乱后的图像" + }, + "1": { + "name": "文本", + "tooltip": "打乱后的文本" + } + } + }, + "SkipLayerGuidanceDiT": { + "display_name": "跳过层引导(DiT)", + "description": "通用的跳过层引导节点,可用于每个DiT模型。", + "inputs": { "model": { "name": "模型" }, - "rescaling_scale": { - "name": "重新缩放比例" - }, - "scale": { - "name": "缩放" + "double_layers": { + "name": "双层" }, "single_layers": { "name": "单层" }, + "scale": { + "name": "缩放" + }, "start_percent": { "name": "开始百分比" + }, + "end_percent": { + "name": "结束百分比" + }, + "rescaling_scale": { + "name": "重新缩放比例" } }, "outputs": { @@ -10732,23 +11837,23 @@ } }, "SkipLayerGuidanceDiTSimple": { - "description": "跳过层引导(DiT)节点的简化版本,仅修改无条件传递。", "display_name": "跳过层引导(DiT简化)", + "description": "跳过层引导(DiT)节点的简化版本,仅修改无条件传递。", "inputs": { - "double_layers": { - "name": "双层" - }, - "end_percent": { - "name": "结束百分比" - }, "model": { "name": "模型" }, + "double_layers": { + "name": "双层" + }, "single_layers": { "name": "单层" }, "start_percent": { "name": "开始百分比" + }, + "end_percent": { + "name": "结束百分比" } }, "outputs": { @@ -10758,23 +11863,23 @@ } }, "SkipLayerGuidanceSD3": { - "description": "通用版本的跳过层引导节点,可用于每个DiT模型。", "display_name": "跳过层引导(SD3)", + "description": "通用版本的跳过层引导节点,可用于每个DiT模型。", "inputs": { - "end_percent": { - "name": "结束百分比" + "model": { + "name": "模型" }, "layers": { "name": "层" }, - "model": { - "name": "模型" - }, "scale": { "name": "缩放" }, "start_percent": { "name": "开始百分比" + }, + "end_percent": { + "name": "结束百分比" } }, "outputs": { @@ -10786,20 +11891,25 @@ "SolidMask": { "display_name": "纯块遮罩", "inputs": { - "height": { - "name": "高度" - }, "value": { "name": "明度" }, "width": { "name": "宽度" + }, + "height": { + "name": "高度" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "SplitAudioChannels": { - "description": "将音频分离为左右声道。", "display_name": "分离音频通道", + "description": "将音频分离为左右声道。", "inputs": { "audio": { "name": "音频" @@ -10807,10 +11917,12 @@ }, "outputs": { "0": { - "name": "左声道" + "name": "左声道", + "tooltip": null }, "1": { - "name": "右声道" + "name": "右声道", + "tooltip": null } } }, @@ -10842,59 +11954,54 @@ }, "outputs": { "0": { - "name": "高方差" + "name": "高方差", + "tooltip": null }, "1": { - "name": "低方差" + "name": "低方差", + "tooltip": null } } }, "SplitSigmasDenoise": { "display_name": "分离Sigma降噪", "inputs": { - "denoise": { - "name": "降噪" - }, "sigmas": { "name": "Sigmas" + }, + "denoise": { + "name": "降噪" } }, "outputs": { "0": { - "name": "高方差" + "name": "高方差", + "tooltip": null }, "1": { - "name": "低方差" + "name": "低方差", + "tooltip": null } } }, "StabilityAudioInpaint": { - "description": "使用文本指令转换现有音频样本的部分内容。", "display_name": "Stability AI 音频重绘", + "description": "使用文本指令转换现有音频样本的部分内容。", "inputs": { - "audio": { - "name": "音频", - "tooltip": "音频长度必须在6到190秒之间。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "控制生成音频的时长(秒)。" - }, - "mask_end": { - "name": "结束遮罩" - }, - "mask_start": { - "name": "开始遮罩" - }, "model": { "name": "模型" }, "prompt": { "name": "提示词" }, + "audio": { + "name": "音频", + "tooltip": "音频长度必须在6到190秒之间。" + }, + "duration": { + "name": "时长", + "tooltip": "控制生成音频的时长(秒)。" + }, "seed": { "name": "随机种", "tooltip": "用于生成的随机种子。" @@ -10902,6 +12009,15 @@ "steps": { "name": "步数", "tooltip": "控制采样步数。" + }, + "mask_start": { + "name": "开始遮罩" + }, + "mask_end": { + "name": "结束遮罩" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -10911,26 +12027,23 @@ } }, "StabilityAudioToAudio": { - "description": "使用文本指令将现有音频样本转换为新的高质量作品。", "display_name": "Stability AI 音频到音频", + "description": "使用文本指令将现有音频样本转换为新的高质量作品。", "inputs": { - "audio": { - "name": "音频", - "tooltip": "音频长度必须在6到190秒之间。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "控制生成音频的时长(秒)。" - }, "model": { "name": "模型" }, "prompt": { "name": "提示词" }, + "audio": { + "name": "音频", + "tooltip": "音频长度必须在6到190秒之间。" + }, + "duration": { + "name": "时长", + "tooltip": "控制生成音频的时长(秒)。" + }, "seed": { "name": "随机种", "tooltip": "用于生成的随机种子。" @@ -10942,6 +12055,9 @@ "strength": { "name": "强度", "tooltip": "参数控制音频参数对生成音频的影响程度。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -10951,45 +12067,45 @@ } }, "StabilityStableImageSD_3_5Node": { - "description": "根据提示词和分辨率同步生成图像。", "display_name": "Stability AI Stable Diffusion 3.5 图像", + "description": "根据提示词和分辨率同步生成图像。", "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "你希望在输出图像中看到的内容。强有力且描述清晰的提示词,能够明确定义元素、颜色和主题,将带来更好的结果。" + }, + "model": { + "name": "模型" + }, "aspect_ratio": { "name": "宽高比", "tooltip": "生成图像的宽高比。" }, + "style_preset": { + "name": "风格预设", + "tooltip": "可选,生成图像的期望风格。" + }, "cfg_scale": { "name": "CFG", "tooltip": "扩散过程对提示词文本的遵循程度(数值越高,生成的图像越接近你的提示词)" }, - "control_after_generate": { - "name": "生成后控制" + "seed": { + "name": "随机种", + "tooltip": "用于生成噪声的随机种子。" }, "image": { "name": "图像" }, - "image_denoise": { - "name": "图像降噪", - "tooltip": "输入图像的去噪程度;0.0 表示与输入图像完全相同,1.0 表示完全不使用输入图像。" - }, - "model": { - "name": "模型" - }, "negative_prompt": { "name": "负面提示词", "tooltip": "你不希望在输出图像中出现的关键词。此为高级功能。" }, - "prompt": { - "name": "提示词", - "tooltip": "你希望在输出图像中看到的内容。强有力且描述清晰的提示词,能够明确定义元素、颜色和主题,将带来更好的结果。" + "image_denoise": { + "name": "图像降噪", + "tooltip": "输入图像的去噪程度;0.0 表示与输入图像完全相同,1.0 表示完全不使用输入图像。" }, - "seed": { - "name": "随机种", - "tooltip": "用于生成噪声的随机种子。" - }, - "style_preset": { - "name": "风格预设", - "tooltip": "可选,生成图像的期望风格。" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -10999,38 +12115,38 @@ } }, "StabilityStableImageUltraNode": { - "description": "根据提示词和分辨率同步生成图像。", "display_name": "Stability AI Stable 图像 Ultra", + "description": "根据提示词和分辨率同步生成图像。", "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "你希望在输出图像中看到的内容。一个强有力且描述清晰的提示词,能够明确界定元素、颜色和主题,将带来更好的结果。要控制某个词的权重,请使用格式 `(word:weight)`,其中 `word` 是你想要控制权重的词,`weight` 是介于 0 到 1 之间的数值。例如:`The sky was a crisp (blue:0.3) and (green:0.8)` 表示天空是蓝色和绿色,但绿色多于蓝色。" + }, "aspect_ratio": { "name": "宽高比", "tooltip": "生成图像的宽高比。" }, - "control_after_generate": { - "name": "生成后控制" - }, - "image": { - "name": "图像" - }, - "image_denoise": { - "name": "降噪", - "tooltip": "输入图像的去噪强度;0.0 表示与输入图像完全相同,1.0 表示完全不参考输入图像。" - }, - "negative_prompt": { - "name": "负面提示词", - "tooltip": "描述你不希望在输出图像中出现内容的文本。这是一个高级功能。" - }, - "prompt": { - "name": "提示词", - "tooltip": "你希望在输出图像中看到的内容。一个强有力且描述清晰的提示词,能够明确界定元素、颜色和主题,将带来更好的结果。要控制某个词的权重,请使用格式 `(word:weight)`,其中 `word` 是你想要控制权重的词,`weight` 是介于 0 到 1 之间的数值。例如:`The sky was a crisp (blue:0.3) and (green:0.8)` 表示天空是蓝色和绿色,但绿色多于蓝色。" + "style_preset": { + "name": "风格预设", + "tooltip": "可选的生成图像风格。" }, "seed": { "name": "随机种", "tooltip": "用于生成噪声的随机种子。" }, - "style_preset": { - "name": "风格预设", - "tooltip": "可选的生成图像风格。" + "image": { + "name": "图像" + }, + "negative_prompt": { + "name": "负面提示词", + "tooltip": "描述你不希望在输出图像中出现内容的文本。这是一个高级功能。" + }, + "image_denoise": { + "name": "降噪", + "tooltip": "输入图像的去噪强度;0.0 表示与输入图像完全相同,1.0 表示完全不参考输入图像。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -11040,22 +12156,19 @@ } }, "StabilityTextToAudio": { - "description": "根据文本描述生成高质量音乐和音效。", "display_name": "Stability AI 文本转音频", + "description": "根据文本描述生成高质量音乐和音效。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "控制生成音频的时长(秒)。" - }, "model": { "name": "模型" }, "prompt": { "name": "提示词" }, + "duration": { + "name": "时长", + "tooltip": "控制生成音频的时长(秒)。" + }, "seed": { "name": "种子", "tooltip": "用于生成的随机种子。" @@ -11063,6 +12176,9 @@ "steps": { "name": "步数", "tooltip": "控制采样步数。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -11072,30 +12188,30 @@ } }, "StabilityUpscaleConservativeNode": { - "description": "以最小改动将图像放大至 4K 分辨率。", "display_name": "Stability AI 保守放大", + "description": "以最小改动将图像放大至 4K 分辨率。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "creativity": { - "name": "创造性", - "tooltip": "控制生成与初始图像不强相关的额外细节的可能性。" - }, "image": { "name": "图像" }, - "negative_prompt": { - "name": "反向提示词", - "tooltip": "你不希望在输出图像中出现的关键词。此为高级功能。" - }, "prompt": { "name": "提示词", "tooltip": "你希望在输出图像中看到什么。强有力且描述清晰的提示词,能更好地定义元素、颜色和主题,从而获得更佳效果。" }, + "creativity": { + "name": "创造性", + "tooltip": "控制生成与初始图像不强相关的额外细节的可能性。" + }, "seed": { "name": "种子", "tooltip": "用于生成噪声的随机种子。" + }, + "negative_prompt": { + "name": "反向提示词", + "tooltip": "你不希望在输出图像中出现的关键词。此为高级功能。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -11105,34 +12221,34 @@ } }, "StabilityUpscaleCreativeNode": { - "description": "以最小改动将图像放大至4K分辨率。", "display_name": "Stability AI 创意放大", + "description": "以最小改动将图像放大至4K分辨率。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "creativity": { - "name": "创造性", - "tooltip": "控制生成不受初始图像强烈约束的额外细节的可能性。" - }, "image": { "name": "图像" }, - "negative_prompt": { - "name": "反向提示词", - "tooltip": "你不希望在输出图像中出现的关键词。此为高级功能。" - }, "prompt": { "name": "提示词", "tooltip": "你希望在输出图像中看到什么。强有力且描述清晰的提示词,明确元素、颜色和主题,将获得更好的结果。" }, - "seed": { - "name": "随机种子", - "tooltip": "用于生成噪声的随机种子。" + "creativity": { + "name": "创造性", + "tooltip": "控制生成不受初始图像强烈约束的额外细节的可能性。" }, "style_preset": { "name": "风格预设", "tooltip": "可选,生成图像的期望风格。" + }, + "seed": { + "name": "随机种子", + "tooltip": "用于生成噪声的随机种子。" + }, + "negative_prompt": { + "name": "反向提示词", + "tooltip": "你不希望在输出图像中出现的关键词。此为高级功能。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -11142,8 +12258,8 @@ } }, "StabilityUpscaleFastNode": { - "description": "通过 Stability API 快速将图像放大至原始尺寸的 4 倍;适用于低质量或压缩图像的放大。", "display_name": "Stability AI 极速放大", + "description": "通过 Stability API 快速将图像放大至原始尺寸的 4 倍;适用于低质量或压缩图像的放大。", "inputs": { "image": { "name": "图像" @@ -11158,17 +12274,17 @@ "StableCascade_EmptyLatentImage": { "display_name": "空Latent图像(Stable Cascade)", "inputs": { - "batch_size": { - "name": "批量大小" - }, - "compression": { - "name": "压缩" + "width": { + "name": "宽度" }, "height": { "name": "高度" }, - "width": { - "name": "宽度" + "compression": { + "name": "压缩" + }, + "batch_size": { + "name": "批量大小" } }, "outputs": { @@ -11201,14 +12317,14 @@ "StableCascade_StageC_VAEEncode": { "display_name": "Stable Cascade_C阶段_VAE编码", "inputs": { - "compression": { - "name": "压缩" - }, "image": { "name": "图像" }, "vae": { "name": "vae" + }, + "compression": { + "name": "压缩" } }, "outputs": { @@ -11250,21 +12366,9 @@ "StableZero123_Conditioning": { "display_name": "StableZero123条件", "inputs": { - "azimuth": { - "name": "方位角" - }, - "batch_size": { - "name": "批量大小" - }, "clip_vision": { "name": "clip视觉" }, - "elevation": { - "name": "俯仰角" - }, - "height": { - "name": "高度" - }, "init_image": { "name": "初始图像" }, @@ -11273,6 +12377,18 @@ }, "width": { "name": "宽度" + }, + "height": { + "name": "高度" + }, + "batch_size": { + "name": "批量大小" + }, + "elevation": { + "name": "俯仰角" + }, + "azimuth": { + "name": "方位角" } }, "outputs": { @@ -11293,27 +12409,9 @@ "StableZero123_Conditioning_Batched": { "display_name": "StableZero123条件_批处理", "inputs": { - "azimuth": { - "name": "方位角" - }, - "azimuth_batch_increment": { - "name": "方位角增量" - }, - "batch_size": { - "name": "批量大小" - }, "clip_vision": { "name": "clip视觉" }, - "elevation": { - "name": "俯仰角" - }, - "elevation_batch_increment": { - "name": "俯仰角增量" - }, - "height": { - "name": "高度" - }, "init_image": { "name": "初始图像" }, @@ -11322,6 +12420,24 @@ }, "width": { "name": "宽度" + }, + "height": { + "name": "高度" + }, + "batch_size": { + "name": "批量大小" + }, + "elevation": { + "name": "俯仰角" + }, + "azimuth": { + "name": "方位角" + }, + "elevation_batch_increment": { + "name": "俯仰角增量" + }, + "azimuth_batch_increment": { + "name": "方位角增量" } }, "outputs": { @@ -11342,17 +12458,17 @@ "StringCompare": { "display_name": "比较", "inputs": { - "case_sensitive": { - "name": "区分大小写" - }, - "mode": { - "name": "模式" - }, "string_a": { "name": "字符串A" }, "string_b": { "name": "字符串B" + }, + "mode": { + "name": "模式" + }, + "case_sensitive": { + "name": "区分大小写" } }, "outputs": { @@ -11364,14 +12480,14 @@ "StringConcatenate": { "display_name": "连接", "inputs": { - "delimiter": { - "name": "分隔符" - }, "string_a": { "name": "字符串A" }, "string_b": { "name": "字符串B" + }, + "delimiter": { + "name": "分隔符" } }, "outputs": { @@ -11383,14 +12499,14 @@ "StringContains": { "display_name": "包含", "inputs": { - "case_sensitive": { - "name": "区分大小写" - }, "string": { "name": "字符串" }, "substring": { "name": "子字符串" + }, + "case_sensitive": { + "name": "区分大小写" } }, "outputs": { @@ -11417,14 +12533,14 @@ "StringReplace": { "display_name": "替换", "inputs": { + "string": { + "name": "字符串" + }, "find": { "name": "查找" }, "replace": { "name": "替换" - }, - "string": { - "name": "字符串" } }, "outputs": { @@ -11436,14 +12552,14 @@ "StringSubstring": { "display_name": "子字符串", "inputs": { - "end": { - "name": "结束" + "string": { + "name": "字符串" }, "start": { "name": "起始" }, - "string": { - "name": "字符串" + "end": { + "name": "结束" } }, "outputs": { @@ -11455,11 +12571,11 @@ "StringTrim": { "display_name": "修剪", "inputs": { - "mode": { - "name": "模式" - }, "string": { "name": "字符串" + }, + "mode": { + "name": "模式" } }, "outputs": { @@ -11468,23 +12584,38 @@ } } }, + "StripWhitespace": { + "display_name": "清理空字符", + "inputs": { + "texts": { + "name": "文本", + "tooltip": "需要处理的文本" + } + }, + "outputs": { + "0": { + "name": "文本", + "tooltip": "已处理的文本" + } + } + }, "StyleModelApply": { "display_name": "应用风格模型", "inputs": { - "clip_vision_output": { - "name": "clip视觉输出" - }, "conditioning": { "name": "条件" }, + "style_model": { + "name": "风格模型" + }, + "clip_vision_output": { + "name": "clip视觉输出" + }, "strength": { "name": "强度" }, "strength_type": { "name": "强度类型" - }, - "style_model": { - "name": "风格模型" } } }, @@ -11496,17 +12627,100 @@ } } }, + "SV3D_Conditioning": { + "display_name": "SV3D条件", + "inputs": { + "clip_vision": { + "name": "clip视觉" + }, + "init_image": { + "name": "初始图像" + }, + "vae": { + "name": "vae" + }, + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" + }, + "video_frames": { + "name": "帧数" + }, + "elevation": { + "name": "俯仰角" + } + }, + "outputs": { + "0": { + "name": "正面条件", + "tooltip": null + }, + "1": { + "name": "负面条件", + "tooltip": null + }, + "2": { + "name": "Latent", + "tooltip": null + } + } + }, + "SVD_img2vid_Conditioning": { + "display_name": "SVD_img2vid条件", + "inputs": { + "clip_vision": { + "name": "clip视觉" + }, + "init_image": { + "name": "初始图像" + }, + "vae": { + "name": "vae" + }, + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" + }, + "video_frames": { + "name": "帧数" + }, + "motion_bucket_id": { + "name": "动态bucketID" + }, + "fps": { + "name": "帧率" + }, + "augmentation_level": { + "name": "增强" + } + }, + "outputs": { + "0": { + "name": "正面条件" + }, + "1": { + "name": "负面条件" + }, + "2": { + "name": "Latent" + } + } + }, "T5TokenizerOptions": { "display_name": "T5Tokenizer设置", "inputs": { "clip": { "name": "clip" }, - "min_length": { - "name": "最小长度" - }, "min_padding": { "name": "最小填充" + }, + "min_length": { + "name": "最小长度" } }, "outputs": { @@ -11516,8 +12730,8 @@ } }, "TCFG": { - "description": "TCFG – 切向阻尼CFG (2503.18137)\n\n优化无条件(负向)以与有条件(正向)对齐,从而提高质量。", "display_name": "切向阻尼CFG", + "description": "TCFG – 切向阻尼CFG (2503.18137)\n\n优化无条件(负向)以与有条件(正向)对齐,从而提高质量。", "inputs": { "model": { "name": "模型" @@ -11531,8 +12745,8 @@ } }, "TemporalScoreRescaling": { - "description": "[后CFG函数]\nTSR - 时序分数重缩放 (2510.01184)\n\n重缩放模型的分数或噪声以引导采样多样性。", "display_name": "TSR - 时序分数重缩放", + "description": "[后CFG函数]\nTSR - 时序分数重缩放 (2510.01184)\n\n重缩放模型的分数或噪声以引导采样多样性。", "inputs": { "model": { "name": "模型" @@ -11559,14 +12773,14 @@ "clip": { "name": "clip" }, + "tags": { + "name": "标签" + }, "lyrics": { "name": "歌词" }, "lyrics_strength": { "name": "歌词强度" - }, - "tags": { - "name": "标签" } }, "outputs": { @@ -11584,12 +12798,12 @@ "clip_vision_output": { "name": "clip视觉输出" }, + "prompt": { + "name": "提示" + }, "image_interleave": { "name": "图像交错", "tooltip": "图像与文本提示的影响程度。数字越高,文本提示的影响越大。" - }, - "prompt": { - "name": "提示" } }, "outputs": { @@ -11604,14 +12818,14 @@ "clip": { "name": "clip" }, - "image": { - "name": "图像" - }, "prompt": { "name": "提示词" }, "vae": { "name": "vae" + }, + "image": { + "name": "图像" } }, "outputs": { @@ -11626,6 +12840,12 @@ "clip": { "name": "clip" }, + "prompt": { + "name": "提示词" + }, + "vae": { + "name": "vae" + }, "image1": { "name": "图像1" }, @@ -11634,12 +12854,6 @@ }, "image3": { "name": "图像3" - }, - "prompt": { - "name": "提示词" - }, - "vae": { - "name": "vae" } }, "outputs": { @@ -11648,6 +12862,36 @@ } } }, + "TextToLowercase": { + "display_name": "文本半角", + "inputs": { + "texts": { + "name": "文本", + "tooltip": "需要处理的文本" + } + }, + "outputs": { + "0": { + "name": "文本", + "tooltip": "已经处理的文本" + } + } + }, + "TextToUppercase": { + "display_name": "文本全角", + "inputs": { + "texts": { + "name": "文本", + "tooltip": "需要处理的文本" + } + }, + "outputs": { + "0": { + "name": "文本", + "tooltip": "已经处理的文本" + } + } + }, "ThresholdMask": { "display_name": "遮罩阈值", "inputs": { @@ -11657,6 +12901,11 @@ "value": { "name": "值" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "TomePatchModel": { @@ -11790,11 +13039,11 @@ "TorchCompileModel": { "display_name": "Torch编译模型", "inputs": { - "backend": { - "name": "后端" - }, "model": { "name": "模型" + }, + "backend": { + "name": "后端" } }, "outputs": { @@ -11806,103 +13055,116 @@ "TrainLoraNode": { "display_name": "训练 LoRA", "inputs": { - "algorithm": { - "name": "算法", - "tooltip": "用于训练的算法。" - }, - "batch_size": { - "name": "批次大小", - "tooltip": "用于训练的批次大小。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "existing_lora": { - "name": "现有LoRA", - "tooltip": "要附加到的现有LoRA。设置为None以创建新LoRA。" - }, - "grad_accumulation_steps": { - "name": "梯度累积步数", - "tooltip": "用于训练的梯度累积步数。" - }, - "gradient_checkpointing": { - "name": "梯度检查点", - "tooltip": "训练时使用梯度检查点。" + "model": { + "name": "模型", + "tooltip": "用于训练 LoRA 的模型。" }, "latents": { "name": "潜变量", "tooltip": "用于训练的潜变量,作为模型的数据集/输入。" }, - "learning_rate": { - "name": "学习率", - "tooltip": "用于训练的学习率。" - }, - "lora_dtype": { - "name": "LoRA 数据类型", - "tooltip": "用于 LoRA 的数据类型。" - }, - "loss_function": { - "name": "损失函数", - "tooltip": "用于训练的损失函数。" - }, - "model": { - "name": "模型", - "tooltip": "用于训练 LoRA 的模型。" - }, - "optimizer": { - "name": "优化器", - "tooltip": "用于训练的优化器。" - }, "positive": { "name": "正向条件", "tooltip": "用于训练的正向条件。" }, - "rank": { - "name": "秩", - "tooltip": "LoRA 层的秩。" + "batch_size": { + "name": "批次大小", + "tooltip": "用于训练的批次大小。" }, - "seed": { - "name": "种子", - "tooltip": "用于训练的种子(用于 LoRA 权重初始化和噪声采样的生成器)" + "grad_accumulation_steps": { + "name": "梯度累积步数", + "tooltip": "用于训练的梯度累积步数。" }, "steps": { "name": "步数", "tooltip": "训练 LoRA 的步数。" }, + "learning_rate": { + "name": "学习率", + "tooltip": "用于训练的学习率。" + }, + "rank": { + "name": "秩", + "tooltip": "LoRA 层的秩。" + }, + "optimizer": { + "name": "优化器", + "tooltip": "用于训练的优化器。" + }, + "loss_function": { + "name": "损失函数", + "tooltip": "用于训练的损失函数。" + }, + "seed": { + "name": "种子", + "tooltip": "用于训练的种子(用于 LoRA 权重初始化和噪声采样的生成器)" + }, "training_dtype": { "name": "训练数据类型", "tooltip": "用于训练的数据类型。" + }, + "lora_dtype": { + "name": "LoRA 数据类型", + "tooltip": "用于 LoRA 的数据类型。" + }, + "algorithm": { + "name": "算法", + "tooltip": "用于训练的算法。" + }, + "gradient_checkpointing": { + "name": "梯度检查点", + "tooltip": "训练时使用梯度检查点。" + }, + "existing_lora": { + "name": "现有LoRA", + "tooltip": "要附加到的现有LoRA。设置为None以创建新LoRA。" + }, + "bucket_mode": { + "name": "bucket模式", + "tooltip": "启用分辨率 bucket 模式。开启后会先使用 分辨率Bucket 节点处理 Latent。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { "0": { - "name": "带LoRA的模型" + "name": "带LoRA的模型", + "tooltip": "已应用 LoRA 的模型" }, "1": { - "name": "LoRA" + "name": "LoRA", + "tooltip": "LoRA 权重" }, "2": { - "name": "损失" + "name": "损失", + "tooltip": "损失历史图" }, "3": { - "name": "步数" + "name": "步数", + "tooltip": "总训练步数" } } }, "TrimAudioDuration": { - "description": "将音频张量修剪到选定的时间范围。", "display_name": "修剪音频时长", + "description": "将音频张量修剪到选定的时间范围。", "inputs": { "audio": { "name": "音频" }, - "duration": { - "name": "时长", - "tooltip": "持续时间(秒)" - }, "start_index": { "name": "起始索引", "tooltip": "开始时间(秒),可为负数表示从末尾开始计数(支持小数秒)。" + }, + "duration": { + "name": "时长", + "tooltip": "持续时间(秒)" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, @@ -11923,8 +13185,8 @@ } }, "TripleCLIPLoader": { - "description": "[配方]\n\nSD3:clip-l,clip-g,t5", "display_name": "三重CLIP加载器", + "description": "[配方]\n\nSD3:clip-l,clip-g,t5", "inputs": { "clip_name1": { "name": "CLIP名称1" @@ -11945,65 +13207,107 @@ "TripoConversionNode": { "display_name": "Tripo:转换模型", "inputs": { - "face_limit": { - "name": "面数限制" + "original_model_task_id": { + "name": "原始模型任务ID" }, "format": { "name": "格式" }, - "original_model_task_id": { - "name": "原始模型任务ID" - }, "quad": { "name": "四边形" }, + "face_limit": { + "name": "面数限制" + }, + "texture_size": { + "name": "纹理大小" + }, "texture_format": { "name": "纹理格式" }, - "texture_size": { - "name": "纹理大小" + "force_symmetry": { + "name": "强制对称" + }, + "flatten_bottom": { + "name": "平滑底部" + }, + "flatten_bottom_threshold": { + "name": "平滑底部阈值" + }, + "pivot_to_center_bottom": { + "name": "对齐底部中心" + }, + "scale_factor": { + "name": "缩放系数" + }, + "with_animation": { + "name": "加入动画" + }, + "pack_uv": { + "name": "打包uv" + }, + "bake": { + "name": "烘焙" + }, + "part_names": { + "name": "部件名称" + }, + "fbx_preset": { + "name": "fbx预设" + }, + "export_vertex_colors": { + "name": "导出顶点色" + }, + "export_orientation": { + "name": "导出朝向" + }, + "animate_in_place": { + "name": "原地动画" } } }, "TripoImageToModelNode": { "display_name": "Tripo:图像转模型", "inputs": { - "face_limit": { - "name": "面数限制" - }, "image": { "name": "图像" }, - "model_seed": { - "name": "模型种子" - }, "model_version": { "name": "模型版本", "tooltip": "用于生成的模型版本" }, - "orientation": { - "name": "朝向" - }, - "pbr": { - "name": "PBR" - }, - "quad": { - "name": "四边形" - }, "style": { "name": "风格" }, "texture": { "name": "纹理" }, - "texture_alignment": { - "name": "纹理对齐" + "pbr": { + "name": "PBR" + }, + "model_seed": { + "name": "模型种子" + }, + "orientation": { + "name": "朝向" + }, + "texture_seed": { + "name": "纹理种子" }, "texture_quality": { "name": "纹理质量" }, - "texture_seed": { - "name": "纹理种子" + "texture_alignment": { + "name": "纹理对齐" + }, + "face_limit": { + "name": "面数限制" + }, + "quad": { + "name": "四边形" + }, + "geometry_quality": { + "name": "几何质量" } }, "outputs": { @@ -12020,24 +13324,18 @@ "TripoMultiviewToModelNode": { "display_name": "Tripo:多视图转模型", "inputs": { - "face_limit": { - "name": "面数限制" - }, "image": { "name": "图像" }, - "image_back": { - "name": "背面图像" - }, "image_left": { "name": "左侧图像" }, + "image_back": { + "name": "背面图像" + }, "image_right": { "name": "右侧图像" }, - "model_seed": { - "name": "模型种子" - }, "model_version": { "name": "模型版本", "tooltip": "用于生成的模型版本" @@ -12045,23 +13343,32 @@ "orientation": { "name": "朝向" }, - "pbr": { - "name": "PBR" - }, - "quad": { - "name": "四边形" - }, "texture": { "name": "纹理" }, - "texture_alignment": { - "name": "纹理对齐" + "pbr": { + "name": "PBR" + }, + "model_seed": { + "name": "模型种子" + }, + "texture_seed": { + "name": "纹理种子" }, "texture_quality": { "name": "纹理质量" }, - "texture_seed": { - "name": "纹理种子" + "texture_alignment": { + "name": "纹理对齐" + }, + "face_limit": { + "name": "面数限制" + }, + "quad": { + "name": "四边形" + }, + "geometry_quality": { + "name": "几何质量" } }, "outputs": { @@ -12076,8 +13383,8 @@ } }, "TripoRefineNode": { - "description": "仅精修由v1.4 Tripo模型创建的草稿模型。", "display_name": "Tripo: 精修草稿模型", + "description": "仅精修由v1.4 Tripo模型创建的草稿模型。", "inputs": { "model_task_id": { "name": "模型任务ID", @@ -12098,11 +13405,11 @@ "TripoRetargetNode": { "display_name": "Tripo: 重定向绑定模型", "inputs": { - "animation": { - "name": "动画" - }, "original_model_task_id": { "name": "原始模型任务ID" + }, + "animation": { + "name": "动画" } }, "outputs": { @@ -12137,29 +13444,14 @@ "TripoTextToModelNode": { "display_name": "Tripo: 文本转模型", "inputs": { - "face_limit": { - "name": "面数限制" - }, - "image_seed": { - "name": "图像种子" - }, - "model_seed": { - "name": "模型种子" - }, - "model_version": { - "name": "模型版本" + "prompt": { + "name": "提示词" }, "negative_prompt": { "name": "负面提示词" }, - "pbr": { - "name": "PBR" - }, - "prompt": { - "name": "提示词" - }, - "quad": { - "name": "四边形" + "model_version": { + "name": "模型版本" }, "style": { "name": "风格" @@ -12167,11 +13459,29 @@ "texture": { "name": "纹理" }, - "texture_quality": { - "name": "纹理质量" + "pbr": { + "name": "PBR" + }, + "image_seed": { + "name": "图像种子" + }, + "model_seed": { + "name": "模型种子" }, "texture_seed": { "name": "纹理种子" + }, + "texture_quality": { + "name": "纹理质量" + }, + "face_limit": { + "name": "面数限制" + }, + "quad": { + "name": "四边形" + }, + "geometry_quality": { + "name": "几何质量" } }, "outputs": { @@ -12191,20 +13501,20 @@ "model_task_id": { "name": "模型任务ID" }, - "pbr": { - "name": "PBR" - }, "texture": { "name": "纹理" }, - "texture_alignment": { - "name": "纹理对齐" + "pbr": { + "name": "PBR" + }, + "texture_seed": { + "name": "纹理种子" }, "texture_quality": { "name": "纹理质量" }, - "texture_seed": { - "name": "纹理种子" + "texture_alignment": { + "name": "纹理对齐" } }, "outputs": { @@ -12218,6 +13528,75 @@ } } }, + "TruncateText": { + "display_name": "截断文本", + "inputs": { + "texts": { + "name": "文本", + "tooltip": "需要处理的文本" + }, + "max_length": { + "name": "长度上限", + "tooltip": "文本长度上限" + } + }, + "outputs": { + "0": { + "name": "文本", + "tooltip": "已处理的文本" + } + } + }, + "unCLIPCheckpointLoader": { + "display_name": "unCLIPCheckpoint加载器", + "inputs": { + "ckpt_name": { + "name": "Checkpoint名称" + } + } + }, + "unCLIPConditioning": { + "display_name": "unCLIP条件", + "inputs": { + "conditioning": { + "name": "条件" + }, + "clip_vision_output": { + "name": "CLIP视觉输出" + }, + "strength": { + "name": "强度" + }, + "noise_augmentation": { + "name": "噪波增强" + } + } + }, + "UNetCrossAttentionMultiply": { + "display_name": "UNet交叉注意力乘数", + "inputs": { + "model": { + "name": "模型" + }, + "q": { + "name": "q" + }, + "k": { + "name": "k" + }, + "v": { + "name": "v" + }, + "out": { + "name": "输出" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, "UNETLoader": { "display_name": "UNet加载器", "inputs": { @@ -12229,48 +13608,23 @@ } } }, - "UNetCrossAttentionMultiply": { - "display_name": "UNet交叉注意力乘数", - "inputs": { - "k": { - "name": "k" - }, - "model": { - "name": "模型" - }, - "out": { - "name": "输出" - }, - "q": { - "name": "q" - }, - "v": { - "name": "v" - } - }, - "outputs": { - "0": { - "tooltip": null - } - } - }, "UNetSelfAttentionMultiply": { "display_name": "UNet自注意力乘数", "inputs": { - "k": { - "name": "k" - }, "model": { "name": "模型" }, - "out": { - "name": "输出" - }, "q": { "name": "q" }, + "k": { + "name": "k" + }, "v": { "name": "v" + }, + "out": { + "name": "输出" } }, "outputs": { @@ -12282,12 +13636,6 @@ "UNetTemporalAttentionMultiply": { "display_name": "UNet时间注意力乘数", "inputs": { - "cross_structural": { - "name": "交叉结构" - }, - "cross_temporal": { - "name": "交叉时间" - }, "model": { "name": "模型" }, @@ -12296,6 +13644,12 @@ }, "self_temporal": { "name": "自我时间" + }, + "cross_structural": { + "name": "交叉结构" + }, + "cross_temporal": { + "name": "交叉时间" } }, "outputs": { @@ -12304,20 +13658,6 @@ } } }, - "USOStyleReference": { - "display_name": "USO风格参考", - "inputs": { - "clip_vision_output": { - "name": "CLIP视觉输出" - }, - "model": { - "name": "模型" - }, - "model_patch": { - "name": "模型补丁" - } - } - }, "UpscaleModelLoader": { "display_name": "加载放大模型", "inputs": { @@ -12331,9 +13671,23 @@ } } }, + "USOStyleReference": { + "display_name": "USO风格参考", + "inputs": { + "model": { + "name": "模型" + }, + "model_patch": { + "name": "模型补丁" + }, + "clip_vision_output": { + "name": "CLIP视觉输出" + } + } + }, "VAEDecode": { - "description": "将 Latent 图像解码为像素空间的图像。", "display_name": "VAE解码", + "description": "将 Latent 图像解码为像素空间的图像。", "inputs": { "samples": { "name": "Latent", @@ -12359,47 +13713,57 @@ "vae": { "name": "vae" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "VAEDecodeHunyuan3D": { "display_name": "VAE解码(Hunyuan3D)", "inputs": { - "num_chunks": { - "name": "块数" - }, - "octree_resolution": { - "name": "八叉树分辨率" - }, "samples": { "name": "样本" }, "vae": { "name": "vae" + }, + "num_chunks": { + "name": "块数" + }, + "octree_resolution": { + "name": "八叉树分辨率" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "VAEDecodeTiled": { "display_name": "VAE解码(分块)", "inputs": { - "overlap": { - "name": "重叠" - }, "samples": { "name": "Latent" }, - "temporal_overlap": { - "name": "时间重叠", - "tooltip": "仅用于视频VAE:重叠的帧数。" + "vae": { + "name": "vae" + }, + "tile_size": { + "name": "分块尺寸" + }, + "overlap": { + "name": "重叠" }, "temporal_size": { "name": "时间尺寸", "tooltip": "仅用于视频VAE:一次解码的帧数。" }, - "tile_size": { - "name": "分块尺寸" - }, - "vae": { - "name": "vae" + "temporal_overlap": { + "name": "时间重叠", + "tooltip": "仅用于视频VAE:重叠的帧数。" } } }, @@ -12423,47 +13787,52 @@ "vae": { "name": "vae" } + }, + "outputs": { + "0": { + "tooltip": null + } } }, "VAEEncodeForInpaint": { "display_name": "VAE编码(局部重绘)", "inputs": { - "grow_mask_by": { - "name": "扩展遮罩" - }, - "mask": { - "name": "遮罩" - }, "pixels": { "name": "像素" }, "vae": { "name": "vae" + }, + "mask": { + "name": "遮罩" + }, + "grow_mask_by": { + "name": "扩展遮罩" } } }, "VAEEncodeTiled": { "display_name": "VAE编码分块)", "inputs": { - "overlap": { - "name": "重叠" - }, "pixels": { "name": "像素" }, - "temporal_overlap": { - "name": "时间重叠", - "tooltip": "仅用于视频VAE:重叠的帧数。" + "vae": { + "name": "vae" + }, + "tile_size": { + "name": "分块尺寸" + }, + "overlap": { + "name": "重叠" }, "temporal_size": { "name": "时间尺寸", "tooltip": "仅用于视频VAE:一次编码的帧数。" }, - "tile_size": { - "name": "分块尺寸" - }, - "vae": { - "name": "vae" + "temporal_overlap": { + "name": "时间重叠", + "tooltip": "仅用于视频VAE:重叠的帧数。" } } }, @@ -12478,41 +13847,81 @@ "VAESave": { "display_name": "保存VAE", "inputs": { - "filename_prefix": { - "name": "文件名前缀" - }, "vae": { "name": "vae" + }, + "filename_prefix": { + "name": "文件名前缀" } } }, - "VPScheduler": { - "display_name": "VPS调度器", + "Veo3FirstLastFrameNode": { + "display_name": "Google Veo 3 首尾帧视频", + "description": "使用首尾帧和提示词生成视频", "inputs": { - "beta_d": { - "name": "beta_d" + "prompt": { + "name": "提示词", + "tooltip": "视频的文本描述" }, - "beta_min": { - "name": "beta_min" + "negative_prompt": { + "name": "负面提示词", + "tooltip": "避免视频出现内容的文本描述" }, - "eps_s": { - "name": "eps_s" + "resolution": { + "name": "分辨率" }, - "steps": { - "name": "步数" - } - } - }, - "Veo3VideoGenerationNode": { - "description": "使用 Google Veo 3 API 从文本提示生成视频", - "display_name": "Google Veo 3 视频生成", - "inputs": { "aspect_ratio": { "name": "宽高比", "tooltip": "输出视频的宽高比" }, + "duration": { + "name": "时长", + "tooltip": "输出视频的秒数" + }, + "seed": { + "name": "随机种", + "tooltip": "生成视频的随机种" + }, + "first_frame": { + "name": "初始帧", + "tooltip": "初始帧" + }, + "last_frame": { + "name": "结束帧", + "tooltip": "结束帧" + }, + "model": { + "name": "模型" + }, + "generate_audio": { + "name": "生成音频", + "tooltip": "为视频生成音频" + }, "control_after_generate": { "name": "生成后控制" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "Veo3VideoGenerationNode": { + "display_name": "Google Veo 3 视频生成", + "description": "使用 Google Veo 3 API 从文本提示生成视频", + "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "视频的文本描述" + }, + "aspect_ratio": { + "name": "宽高比", + "tooltip": "输出视频的宽高比" + }, + "negative_prompt": { + "name": "负面提示词", + "tooltip": "负面文本提示,指导视频中应避免的内容" }, "duration_seconds": { "name": "时长", @@ -12522,9 +13931,13 @@ "name": "优化提示词", "tooltip": "是否使用 AI 辅助增强提示" }, - "generate_audio": { - "name": "生成音频", - "tooltip": "为视频生成音频。所有 Veo 3 模型均支持此功能。" + "person_generation": { + "name": "生成人类", + "tooltip": "是否允许在视频中生成人物" + }, + "seed": { + "name": "随机种", + "tooltip": "视频生成的种子值(0 表示随机)" }, "image": { "name": "图像", @@ -12534,21 +13947,12 @@ "name": "模型", "tooltip": "用于视频生成的 Veo 3 模型" }, - "negative_prompt": { - "name": "负面提示词", - "tooltip": "负面文本提示,指导视频中应避免的内容" + "generate_audio": { + "name": "生成音频", + "tooltip": "为视频生成音频。所有 Veo 3 模型均支持此功能。" }, - "person_generation": { - "name": "生成人类", - "tooltip": "是否允许在视频中生成人物" - }, - "prompt": { - "name": "提示词", - "tooltip": "视频的文本描述" - }, - "seed": { - "name": "随机种", - "tooltip": "视频生成的种子值(0 表示随机)" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -12558,15 +13962,20 @@ } }, "VeoVideoGenerationNode": { - "description": "使用 Google 的 Veo API 根据文本提示生成视频", "display_name": "Google Veo2 视频生成", + "description": "使用 Google 的 Veo API 根据文本提示生成视频", "inputs": { + "prompt": { + "name": "提示词", + "tooltip": "视频的文本描述" + }, "aspect_ratio": { "name": "宽高比", "tooltip": "输出视频的宽高比" }, - "control_after_generate": { - "name": "生成后控制" + "negative_prompt": { + "name": "负面提示词", + "tooltip": "用于指导视频中应避免内容的负面文本提示" }, "duration_seconds": { "name": "时长", @@ -12576,6 +13985,14 @@ "name": "优化提示词", "tooltip": "是否使用 AI 辅助增强提示词" }, + "person_generation": { + "name": "生成人类", + "tooltip": "是否允许在视频中生成人物" + }, + "seed": { + "name": "随机种", + "tooltip": "视频生成的种子(0 表示随机)" + }, "image": { "name": "图像", "tooltip": "可选的参考图像,用于引导视频生成" @@ -12584,21 +14001,8 @@ "name": "模型", "tooltip": "用于视频生成的 Veo 2 模型" }, - "negative_prompt": { - "name": "负面提示词", - "tooltip": "用于指导视频中应避免内容的负面文本提示" - }, - "person_generation": { - "name": "生成人类", - "tooltip": "是否允许在视频中生成人物" - }, - "prompt": { - "name": "提示词", - "tooltip": "视频的文本描述" - }, - "seed": { - "name": "随机种", - "tooltip": "视频生成的种子(0 表示随机)" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -12610,59 +14014,59 @@ "VideoLinearCFGGuidance": { "display_name": "视频线性CFG引导", "inputs": { - "min_cfg": { - "name": "最小配置" - }, "model": { "name": "模型" + }, + "min_cfg": { + "name": "最小配置" } } }, "VideoTriangleCFGGuidance": { "display_name": "视频三角形CFG引导", "inputs": { - "min_cfg": { - "name": "最小配置" - }, "model": { "name": "模型" + }, + "min_cfg": { + "name": "最小配置" } } }, "ViduImageToVideoNode": { - "description": "从图像和可选提示生成视频", "display_name": "Vidu 图像转视频生成", + "description": "从图像和可选提示生成视频", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "输出视频的时长(秒)" + "model": { + "name": "模型", + "tooltip": "模型名称" }, "image": { "name": "图像", "tooltip": "用作生成视频起始帧的图像" }, - "model": { - "name": "模型", - "tooltip": "模型名称" - }, - "movement_amplitude": { - "name": "运动幅度", - "tooltip": "画面中对象的运动幅度" - }, "prompt": { "name": "提示词", "tooltip": "用于视频生成的文本描述" }, + "duration": { + "name": "时长", + "tooltip": "输出视频的时长(秒)" + }, + "seed": { + "name": "随机种", + "tooltip": "视频生成的种子值(0 表示随机)" + }, "resolution": { "name": "分辨率", "tooltip": "支持的值可能因模型和时长而异" }, - "seed": { - "name": "随机种", - "tooltip": "视频生成的种子值(0 表示随机)" + "movement_amplitude": { + "name": "运动幅度", + "tooltip": "画面中对象的运动幅度" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -12672,43 +14076,43 @@ } }, "ViduReferenceVideoNode": { - "description": "从多张图像和提示生成视频", "display_name": "Vidu 参考转视频生成", + "description": "从多张图像和提示生成视频", "inputs": { - "aspect_ratio": { - "name": "宽高比", - "tooltip": "输出视频的宽高比" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "输出视频的时长(秒)" + "model": { + "name": "模型", + "tooltip": "模型名称" }, "images": { "name": "图像", "tooltip": "用作参考以生成具有一致主体的图像(最多 7 张图像)" }, - "model": { - "name": "模型", - "tooltip": "模型名称" - }, - "movement_amplitude": { - "name": "运动幅度", - "tooltip": "画面中物体的运动幅度" - }, "prompt": { "name": "提示词", "tooltip": "用于视频生成的文本描述" }, + "duration": { + "name": "时长", + "tooltip": "输出视频的时长(秒)" + }, + "seed": { + "name": "种子", + "tooltip": "视频生成的种子值(0表示随机)" + }, + "aspect_ratio": { + "name": "宽高比", + "tooltip": "输出视频的宽高比" + }, "resolution": { "name": "分辨率", "tooltip": "支持的值可能因模型和时长而异" }, - "seed": { - "name": "种子", - "tooltip": "视频生成的种子值(0表示随机)" + "movement_amplitude": { + "name": "运动幅度", + "tooltip": "画面中物体的运动幅度" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -12718,43 +14122,43 @@ } }, "ViduStartEndToVideoNode": { - "description": "根据起始帧、结束帧和提示词生成视频", "display_name": "Vidu 起始结束帧转视频生成", + "description": "根据起始帧、结束帧和提示词生成视频", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "输出视频的时长(秒)" - }, - "end_frame": { - "name": "结束帧", - "tooltip": "结束帧" + "model": { + "name": "模型", + "tooltip": "模型名称" }, "first_frame": { "name": "起始帧", "tooltip": "开始帧" }, - "model": { - "name": "模型", - "tooltip": "模型名称" - }, - "movement_amplitude": { - "name": "运动幅度", - "tooltip": "画面中物体的运动幅度" + "end_frame": { + "name": "结束帧", + "tooltip": "结束帧" }, "prompt": { "name": "提示词", "tooltip": "用于视频生成的文本描述" }, - "resolution": { - "name": "分辨率", - "tooltip": "支持的值可能因模型和时长而异" + "duration": { + "name": "时长", + "tooltip": "输出视频的时长(秒)" }, "seed": { "name": "种子", "tooltip": "视频生成的种子值(0表示随机)" + }, + "resolution": { + "name": "分辨率", + "tooltip": "支持的值可能因模型和时长而异" + }, + "movement_amplitude": { + "name": "运动幅度", + "tooltip": "画面中物体的运动幅度" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -12764,39 +14168,39 @@ } }, "ViduTextToVideoNode": { - "description": "根据文本提示词生成视频", "display_name": "Vidu 文本转视频生成", + "description": "根据文本提示词生成视频", "inputs": { - "aspect_ratio": { - "name": "宽高比", - "tooltip": "输出视频的宽高比" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "输出视频的时长(秒)" - }, "model": { "name": "模型", "tooltip": "模型名称" }, - "movement_amplitude": { - "name": "运动幅度", - "tooltip": "画面中物体的运动幅度" - }, "prompt": { "name": "提示词", "tooltip": "用于视频生成的文本描述" }, - "resolution": { - "name": "分辨率", - "tooltip": "支持的值可能因模型和时长而异" + "duration": { + "name": "时长", + "tooltip": "输出视频的时长(秒)" }, "seed": { "name": "种子", "tooltip": "视频生成的种子值(0表示随机)" + }, + "aspect_ratio": { + "name": "宽高比", + "tooltip": "输出视频的宽高比" + }, + "resolution": { + "name": "分辨率", + "tooltip": "支持的值可能因模型和时长而异" + }, + "movement_amplitude": { + "name": "运动幅度", + "tooltip": "画面中物体的运动幅度" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -12808,36 +14212,74 @@ "VoxelToMesh": { "display_name": "体素到网格", "inputs": { + "voxel": { + "name": "体素" + }, "algorithm": { "name": "算法" }, "threshold": { "name": "阈值" - }, - "voxel": { - "name": "体素" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "VoxelToMeshBasic": { "display_name": "体素到网格(基础)", "inputs": { - "threshold": { - "name": "阈值" - }, "voxel": { "name": "体素" + }, + "threshold": { + "name": "阈值" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "VPScheduler": { + "display_name": "VPS调度器", + "inputs": { + "steps": { + "name": "步数" + }, + "beta_d": { + "name": "beta_d" + }, + "beta_min": { + "name": "beta_min" + }, + "eps_s": { + "name": "eps_s" + } + }, + "outputs": { + "0": { + "tooltip": null } } }, "Wan22FunControlToVideo": { "display_name": "Wan22FunControl视频", "inputs": { - "batch_size": { - "name": "批次大小" + "positive": { + "name": "正面提示词" }, - "control_video": { - "name": "控制视频" + "negative": { + "name": "负面提示词" + }, + "vae": { + "name": "VAE" + }, + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -12845,20 +14287,14 @@ "length": { "name": "长度" }, - "negative": { - "name": "负面提示词" - }, - "positive": { - "name": "正面提示词" + "batch_size": { + "name": "批次大小" }, "ref_image": { "name": "参考图像" }, - "vae": { - "name": "VAE" - }, - "width": { - "name": "宽度" + "control_video": { + "name": "控制视频" } }, "outputs": { @@ -12879,8 +14315,11 @@ "Wan22ImageToVideoLatent": { "display_name": "Wan22图像转视频潜变量", "inputs": { - "batch_size": { - "name": "批次大小" + "vae": { + "name": "VAE" + }, + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -12888,14 +14327,11 @@ "length": { "name": "长度" }, + "batch_size": { + "name": "批次大小" + }, "start_image": { "name": "起始图像" - }, - "vae": { - "name": "VAE" - }, - "width": { - "name": "宽度" } }, "outputs": { @@ -12907,26 +14343,17 @@ "WanAnimateToVideo": { "display_name": "Wan动画转视频", "inputs": { - "background_video": { - "name": "背景视频" + "positive": { + "name": "正向提示" }, - "batch_size": { - "name": "批次大小" + "negative": { + "name": "负向提示" }, - "character_mask": { - "name": "角色遮罩" + "vae": { + "name": "VAE" }, - "clip_vision_output": { - "name": "CLIP视觉输出" - }, - "continue_motion": { - "name": "继续运动" - }, - "continue_motion_max_frames": { - "name": "继续运动最大帧数" - }, - "face_video": { - "name": "面部视频" + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -12934,27 +14361,36 @@ "length": { "name": "长度" }, - "negative": { - "name": "负向提示" + "batch_size": { + "name": "批次大小" }, - "pose_video": { - "name": "姿态视频" - }, - "positive": { - "name": "正向提示" - }, - "reference_image": { - "name": "参考图像" - }, - "vae": { - "name": "VAE" + "continue_motion_max_frames": { + "name": "继续运动最大帧数" }, "video_frame_offset": { "name": "视频帧偏移", "tooltip": "在所有输入视频中跳过的帧数。用于通过分块生成更长的视频。连接到上一个节点的video_frame_offset输出以扩展视频。" }, - "width": { - "name": "宽度" + "clip_vision_output": { + "name": "CLIP视觉输出" + }, + "reference_image": { + "name": "参考图像" + }, + "face_video": { + "name": "面部视频" + }, + "pose_video": { + "name": "姿态视频" + }, + "background_video": { + "name": "背景视频" + }, + "character_mask": { + "name": "角色遮罩" + }, + "continue_motion": { + "name": "继续运动" } }, "outputs": { @@ -13004,17 +14440,8 @@ "camera_pose": { "name": "相机姿态" }, - "cx": { - "name": "cx" - }, - "cy": { - "name": "cy" - }, - "fx": { - "name": "fx" - }, - "fy": { - "name": "fy" + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -13025,8 +14452,17 @@ "speed": { "name": "速度" }, - "width": { - "name": "宽度" + "fx": { + "name": "fx" + }, + "fy": { + "name": "fy" + }, + "cx": { + "name": "cx" + }, + "cy": { + "name": "cy" } }, "outputs": { @@ -13051,14 +14487,17 @@ "WanCameraImageToVideo": { "display_name": "万相机图像转视频", "inputs": { - "batch_size": { - "name": "批次大小" + "positive": { + "name": "正面提示词" }, - "camera_conditions": { - "name": "相机条件" + "negative": { + "name": "负面提示词" }, - "clip_vision_output": { - "name": "CLIP视觉输出" + "vae": { + "name": "VAE" + }, + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -13066,20 +14505,17 @@ "length": { "name": "长度" }, - "negative": { - "name": "负面提示词" + "batch_size": { + "name": "批次大小" }, - "positive": { - "name": "正面提示词" + "clip_vision_output": { + "name": "CLIP视觉输出" }, "start_image": { "name": "起始图像" }, - "vae": { - "name": "VAE" - }, - "width": { - "name": "宽度" + "camera_conditions": { + "name": "相机条件" } }, "outputs": { @@ -13098,12 +14534,12 @@ } }, "WanContextWindowsManual": { - "description": "手动设置类WAN模型的上下文窗口(维度=2)。", "display_name": "WAN上下文窗口(手动)", + "description": "手动设置类WAN模型的上下文窗口(维度=2)。", "inputs": { - "closed_loop": { - "name": "闭环", - "tooltip": "是否关闭上下文窗口循环;仅适用于循环调度。" + "model": { + "name": "模型", + "tooltip": "在采样过程中应用上下文窗口的模型。" }, "context_length": { "name": "上下文长度", @@ -13121,13 +14557,17 @@ "name": "上下文步长", "tooltip": "上下文窗口的步长;仅适用于均匀调度。" }, + "closed_loop": { + "name": "闭环", + "tooltip": "是否关闭上下文窗口循环;仅适用于循环调度。" + }, "fuse_method": { "name": "融合方法", "tooltip": "用于融合上下文窗口的方法。" }, - "model": { - "name": "模型", - "tooltip": "在采样过程中应用上下文窗口的模型。" + "freenoise": { + "name": "Freenoise", + "tooltip": "是否应用 Freenoise,优化窗口融合。" } }, "outputs": { @@ -13139,17 +14579,17 @@ "WanFirstLastFrameToVideo": { "display_name": "Wan首尾帧视频", "inputs": { - "batch_size": { - "name": "批量大小" + "positive": { + "name": "正向" }, - "clip_vision_end_image": { - "name": "clip 视觉结束图像" + "negative": { + "name": "负向" }, - "clip_vision_start_image": { - "name": "clip 视觉起始图像" + "vae": { + "name": "vae" }, - "end_image": { - "name": "结束图像" + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -13157,20 +14597,20 @@ "length": { "name": "长度" }, - "negative": { - "name": "负向" + "batch_size": { + "name": "批量大小" }, - "positive": { - "name": "正向" + "clip_vision_start_image": { + "name": "clip 视觉起始图像" + }, + "clip_vision_end_image": { + "name": "clip 视觉结束图像" }, "start_image": { "name": "起始图像" }, - "vae": { - "name": "vae" - }, - "width": { - "name": "宽度" + "end_image": { + "name": "结束图像" } }, "outputs": { @@ -13191,14 +14631,17 @@ "WanFunControlToVideo": { "display_name": "WanFunControl视频", "inputs": { - "batch_size": { - "name": "批量大小" + "positive": { + "name": "正向" }, - "clip_vision_output": { - "name": "CLIP视觉输出" + "negative": { + "name": "负向" }, - "control_video": { - "name": "控制视频" + "vae": { + "name": "vae" + }, + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -13206,20 +14649,17 @@ "length": { "name": "长度" }, - "negative": { - "name": "负向" + "batch_size": { + "name": "批量大小" }, - "positive": { - "name": "正向" + "clip_vision_output": { + "name": "CLIP视觉输出" }, "start_image": { "name": "起始图像" }, - "vae": { - "name": "vae" - }, - "width": { - "name": "宽度" + "control_video": { + "name": "控制视频" } }, "outputs": { @@ -13240,14 +14680,17 @@ "WanFunInpaintToVideo": { "display_name": "WanFunInpaint视频", "inputs": { - "batch_size": { - "name": "批量大小" + "positive": { + "name": "正向" }, - "clip_vision_output": { - "name": "CLIP视觉输出" + "negative": { + "name": "负向" }, - "end_image": { - "name": "结束图像" + "vae": { + "name": "vae" + }, + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -13255,20 +14698,17 @@ "length": { "name": "长度" }, - "negative": { - "name": "负向" + "batch_size": { + "name": "批量大小" }, - "positive": { - "name": "正向" + "clip_vision_output": { + "name": "CLIP视觉输出" }, "start_image": { "name": "起始图像" }, - "vae": { - "name": "vae" - }, - "width": { - "name": "宽度" + "end_image": { + "name": "结束图像" } }, "outputs": { @@ -13289,11 +14729,17 @@ "WanHuMoImageToVideo": { "display_name": "万虎魔图像转视频", "inputs": { - "audio_encoder_output": { - "name": "音频编码器输出" + "positive": { + "name": "正面提示词" }, - "batch_size": { - "name": "批次大小" + "negative": { + "name": "负面提示词" + }, + "vae": { + "name": "VAE" + }, + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -13301,20 +14747,14 @@ "length": { "name": "长度" }, - "negative": { - "name": "负面提示词" + "batch_size": { + "name": "批次大小" }, - "positive": { - "name": "正面提示词" + "audio_encoder_output": { + "name": "音频编码器输出" }, "ref_image": { "name": "参考图像" - }, - "vae": { - "name": "VAE" - }, - "width": { - "name": "宽度" } }, "outputs": { @@ -13333,28 +14773,25 @@ } }, "WanImageToImageApi": { + "display_name": "Wan 图像转图像", "description": "根据一张或两张输入图像和文本提示生成图像。输出图像目前固定为160万像素;其宽高比与输入图像匹配。", - "display_name": "万图像转图像", "inputs": { - "control_after_generate": { - "name": "生成后控制" + "model": { + "name": "模型", + "tooltip": "要使用的模型。" }, "image": { "name": "图像", "tooltip": "单图编辑或多图融合,最多2张图像。" }, - "model": { - "name": "模型", - "tooltip": "要使用的模型。" + "prompt": { + "name": "提示词", + "tooltip": "用于描述元素和视觉特征的提示词,支持英文/中文。" }, "negative_prompt": { "name": "负面提示词", "tooltip": "用于指导避免内容的负面文本提示。" }, - "prompt": { - "name": "提示词", - "tooltip": "用于描述元素和视觉特征的提示词,支持英文/中文。" - }, "seed": { "name": "种子", "tooltip": "生成使用的种子值。" @@ -13362,6 +14799,9 @@ "watermark": { "name": "水印", "tooltip": "是否在结果中添加\"AI生成\"水印。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -13371,13 +14811,19 @@ } }, "WanImageToVideo": { - "display_name": "Wan图像到视频", + "display_name": "图像到视频(Wan)", "inputs": { - "batch_size": { - "name": "批量大小" + "positive": { + "name": "正面" }, - "clip_vision_output": { - "name": "clip视觉输出" + "negative": { + "name": "负面" + }, + "vae": { + "name": "vae" + }, + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -13385,20 +14831,14 @@ "length": { "name": "长度" }, - "negative": { - "name": "负面" + "batch_size": { + "name": "批量大小" }, - "positive": { - "name": "正面" + "clip_vision_output": { + "name": "clip视觉输出" }, "start_image": { "name": "开始图像" - }, - "vae": { - "name": "vae" - }, - "width": { - "name": "宽度" } }, "outputs": { @@ -13417,53 +14857,174 @@ } }, "WanImageToVideoApi": { + "display_name": "Wan 图生视频", "description": "基于首帧图像和文本提示生成视频。", - "display_name": "万图生视频", "inputs": { - "audio": { - "name": "音频", - "tooltip": "音频必须包含清晰、响亮的人声,无杂音和背景音乐。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "可用时长:5秒和10秒" - }, - "generate_audio": { - "name": "生成音频", - "tooltip": "若无音频输入,则自动生成音频。" - }, - "image": { - "name": "图像" - }, "model": { "name": "模型", "tooltip": "要使用的模型。" }, - "negative_prompt": { - "name": "负面提示词", - "tooltip": "用于指导避免内容的负面文本提示。" + "image": { + "name": "图像" }, "prompt": { "name": "提示词", "tooltip": "用于描述元素和视觉特征的提示词,支持英文/中文。" }, - "prompt_extend": { - "name": "提示词扩展", - "tooltip": "是否通过AI辅助增强提示词。" + "negative_prompt": { + "name": "负面提示词", + "tooltip": "用于指导避免内容的负面文本提示。" }, "resolution": { "name": "分辨率" }, + "duration": { + "name": "时长", + "tooltip": "可用时长:5秒和10秒" + }, + "audio": { + "name": "音频", + "tooltip": "音频必须包含清晰、响亮的人声,无杂音和背景音乐。" + }, "seed": { "name": "种子", "tooltip": "生成使用的种子值。" }, + "generate_audio": { + "name": "生成音频", + "tooltip": "若无音频输入,则自动生成音频。" + }, + "prompt_extend": { + "name": "优化提示词", + "tooltip": "是否通过AI辅助增强提示词。" + }, "watermark": { "name": "水印", "tooltip": "是否在结果中添加\"AI生成\"水印。" + }, + "shot_type": { + "name": "镜头类型", + "tooltip": "选择生成的视频的镜头类型,即视频是单个连续镜头还是多个剪辑镜头。需要开启 优化提示词。" + }, + "control_after_generate": { + "name": "生成后控制" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "WanMoveConcatTrack": { + "display_name": "WanMove合并轨道", + "inputs": { + "tracks_1": { + "name": "轨道1" + }, + "tracks_2": { + "name": "轨道2" + } + }, + "outputs": { + "0": { + "tooltip": null + } + } + }, + "WanMoveTracksFromCoords": { + "display_name": "WanMove坐标到轨道", + "inputs": { + "track_coords": { + "name": "轨道坐标" + }, + "track_mask": { + "name": "轨道遮罩" + } + }, + "outputs": { + "0": { + "tooltip": null + }, + "1": { + "name": "轨道长度", + "tooltip": null + } + } + }, + "WanMoveTrackToVideo": { + "display_name": "WanMove轨道到视频", + "inputs": { + "positive": { + "name": "正面条件" + }, + "negative": { + "name": "负面条件" + }, + "vae": { + "name": "VAE" + }, + "strength": { + "name": "强度", + "tooltip": "轨道条件的强度。" + }, + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" + }, + "length": { + "name": "时长" + }, + "batch_size": { + "name": "批次大小" + }, + "start_image": { + "name": "起始帧" + }, + "tracks": { + "name": "轨道" + }, + "clip_vision_output": { + "name": "CLIP视觉输出" + } + }, + "outputs": { + "0": { + "name": "正面条件", + "tooltip": null + }, + "1": { + "name": "负面条件", + "tooltip": null + }, + "2": { + "name": "Latent", + "tooltip": null + } + } + }, + "WanMoveVisualizeTracks": { + "display_name": "WanMove预览轨道", + "inputs": { + "images": { + "name": "图像" + }, + "line_resolution": { + "name": "线条分辨率" + }, + "circle_size": { + "name": "圆环尺寸" + }, + "opacity": { + "name": "不透明度" + }, + "line_width": { + "name": "线条宽度" + }, + "tracks": { + "name": "轨道" } }, "outputs": { @@ -13473,31 +15034,31 @@ } }, "WanPhantomSubjectToVideo": { - "display_name": "万幻主体转视频", + "display_name": "WanPhantom主体转视频", "inputs": { - "batch_size": { - "name": "批次大小" - }, - "height": { - "name": "高度" - }, - "images": { - "name": "图像" - }, - "length": { - "name": "长度" + "positive": { + "name": "正面提示词" }, "negative": { "name": "负面提示词" }, - "positive": { - "name": "正面提示词" - }, "vae": { "name": "VAE" }, "width": { "name": "宽度" + }, + "height": { + "name": "高度" + }, + "length": { + "name": "长度" + }, + "batch_size": { + "name": "批次大小" + }, + "images": { + "name": "图像" } }, "outputs": { @@ -13520,16 +15081,19 @@ } }, "WanSoundImageToVideo": { - "display_name": "WanSound图像到视频", + "display_name": "图像到视频(WanSound)", "inputs": { - "audio_encoder_output": { - "name": "音频编码器输出" + "positive": { + "name": "正面提示词" }, - "batch_size": { - "name": "批次大小" + "negative": { + "name": "负面提示词" }, - "control_video": { - "name": "控制视频" + "vae": { + "name": "VAE" + }, + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -13537,23 +15101,20 @@ "length": { "name": "长度" }, - "negative": { - "name": "负面提示词" + "batch_size": { + "name": "批次大小" }, - "positive": { - "name": "正面提示词" + "audio_encoder_output": { + "name": "音频编码器输出" }, "ref_image": { "name": "参考图像" }, + "control_video": { + "name": "控制视频" + }, "ref_motion": { "name": "参考动作" - }, - "vae": { - "name": "VAE" - }, - "width": { - "name": "宽度" } }, "outputs": { @@ -13572,31 +15133,31 @@ } }, "WanSoundImageToVideoExtend": { - "display_name": "WanSound图像到视频扩展", + "display_name": "图像到视频扩展(WanSound)", "inputs": { - "audio_encoder_output": { - "name": "音频编码器输出" - }, - "control_video": { - "name": "控制视频" - }, - "length": { - "name": "长度" + "positive": { + "name": "正面提示词" }, "negative": { "name": "负面提示词" }, - "positive": { - "name": "正面提示词" + "vae": { + "name": "VAE" + }, + "length": { + "name": "长度" + }, + "video_latent": { + "name": "视频潜变量" + }, + "audio_encoder_output": { + "name": "音频编码器输出" }, "ref_image": { "name": "参考图像" }, - "vae": { - "name": "VAE" - }, - "video_latent": { - "name": "视频潜变量" + "control_video": { + "name": "控制视频" } }, "outputs": { @@ -13615,41 +15176,41 @@ } }, "WanTextToImageApi": { - "description": "基于文本提示生成图像。", "display_name": "Wan文生图", + "description": "基于文本提示生成图像。", "inputs": { - "control_after_generate": { - "name": "生成后控制" - }, - "height": { - "name": "高度" - }, "model": { "name": "模型", "tooltip": "要使用的模型。" }, - "negative_prompt": { - "name": "负面提示词", - "tooltip": "用于指导避免内容的负面文本提示。" - }, "prompt": { "name": "提示词", "tooltip": "用于描述元素和视觉特征的提示词,支持英文/中文。" }, - "prompt_extend": { - "name": "提示词增强", - "tooltip": "是否使用AI辅助增强提示词。" + "negative_prompt": { + "name": "负面提示词", + "tooltip": "用于指导避免内容的负面文本提示。" + }, + "width": { + "name": "宽度" + }, + "height": { + "name": "高度" }, "seed": { "name": "种子", "tooltip": "用于生成的种子值。" }, + "prompt_extend": { + "name": "提示词增强", + "tooltip": "是否使用AI辅助增强提示词。" + }, "watermark": { "name": "水印", "tooltip": "是否在结果中添加\"AI生成\"水印。" }, - "width": { - "name": "宽度" + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -13659,50 +15220,54 @@ } }, "WanTextToVideoApi": { - "description": "基于文本提示生成视频。", "display_name": "Wan文生视频", + "description": "基于文本提示生成视频。", "inputs": { - "audio": { - "name": "音频", - "tooltip": "音频必须包含清晰、响亮的人声,无杂音和背景音乐。" - }, - "control_after_generate": { - "name": "生成后控制" - }, - "duration": { - "name": "时长", - "tooltip": "可用时长:5秒和10秒" - }, - "generate_audio": { - "name": "生成音频", - "tooltip": "若无音频输入,则自动生成音频。" - }, "model": { "name": "模型", "tooltip": "要使用的模型。" }, - "negative_prompt": { - "name": "负面提示词", - "tooltip": "用于引导避免内容的负面文本提示。" - }, "prompt": { "name": "提示词", "tooltip": "用于描述元素和视觉特征的提示词,支持英文/中文。" }, - "prompt_extend": { - "name": "优化提示词", - "tooltip": "是否通过AI辅助增强提示词。" + "negative_prompt": { + "name": "负面提示词", + "tooltip": "用于引导避免内容的负面文本提示。" + }, + "size": { + "name": "尺寸" + }, + "duration": { + "name": "时长", + "tooltip": "可用时长:5秒和10秒" + }, + "audio": { + "name": "音频", + "tooltip": "音频必须包含清晰、响亮的人声,无杂音和背景音乐。" }, "seed": { "name": "随机种", "tooltip": "用于生成的种子值。" }, - "size": { - "name": "尺寸" + "generate_audio": { + "name": "生成音频", + "tooltip": "若无音频输入,则自动生成音频。" + }, + "prompt_extend": { + "name": "优化提示词", + "tooltip": "是否通过AI辅助增强提示词。" }, "watermark": { "name": "水印", "tooltip": "是否在结果中添加“AI生成”水印。" + }, + "shot_type": { + "name": "镜头类型", + "tooltip": "选择生成的视频的镜头类型,即视频是单个连续镜头还是多个剪辑镜头。需要开启 优化提示词。" + }, + "control_after_generate": { + "name": "生成后控制" } }, "outputs": { @@ -13714,11 +15279,20 @@ "WanTrackToVideo": { "display_name": "WanTrack视频", "inputs": { - "batch_size": { - "name": "批次大小" + "positive": { + "name": "正面条件" }, - "clip_vision_output": { - "name": "CLIP视觉输出" + "negative": { + "name": "负面条件" + }, + "vae": { + "name": "vae" + }, + "tracks": { + "name": "tracks" + }, + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -13726,14 +15300,8 @@ "length": { "name": "长度" }, - "negative": { - "name": "负面条件" - }, - "positive": { - "name": "正面条件" - }, - "start_image": { - "name": "图像" + "batch_size": { + "name": "批次大小" }, "temperature": { "name": "温度" @@ -13741,14 +15309,11 @@ "topk": { "name": "topk" }, - "tracks": { - "name": "tracks" + "start_image": { + "name": "图像" }, - "vae": { - "name": "vae" - }, - "width": { - "name": "宽度" + "clip_vision_output": { + "name": "CLIP视觉输出" } }, "outputs": { @@ -13769,14 +15334,17 @@ "WanVaceToVideo": { "display_name": "WanVace视频", "inputs": { - "batch_size": { - "name": "批量大小" + "positive": { + "name": "正面条件" }, - "control_masks": { - "name": "控制遮罩" + "negative": { + "name": "负面条件" }, - "control_video": { - "name": "控制视频" + "vae": { + "name": "vae" + }, + "width": { + "name": "宽度" }, "height": { "name": "高度" @@ -13784,23 +15352,20 @@ "length": { "name": "长度" }, - "negative": { - "name": "负面条件" - }, - "positive": { - "name": "正面条件" - }, - "reference_image": { - "name": "参考图像" + "batch_size": { + "name": "批量大小" }, "strength": { "name": "强度" }, - "vae": { - "name": "vae" + "control_video": { + "name": "控制视频" }, - "width": { - "name": "宽度" + "control_masks": { + "name": "控制遮罩" + }, + "reference_image": { + "name": "参考图像" } }, "outputs": { @@ -13825,45 +15390,45 @@ "WebcamCapture": { "display_name": "网络摄像头捕获", "inputs": { - "capture_on_queue": { - "name": "执行时捕获" + "image": { + "name": "图像" + }, + "width": { + "name": "宽度" }, "height": { "name": "高度" }, - "image": { - "name": "图像" + "capture_on_queue": { + "name": "执行时捕获" }, - "waiting for camera___": { - }, - "width": { - "name": "宽度" - } + "waiting for camera___": {} } }, - "unCLIPCheckpointLoader": { - "display_name": "unCLIPCheckpoint加载器", + "ZImageFunControlnet": { + "display_name": "ZImageFunControlnet", "inputs": { - "ckpt_name": { - "name": "Checkpoint名称" - } - } - }, - "unCLIPConditioning": { - "display_name": "unCLIP条件", - "inputs": { - "clip_vision_output": { - "name": "CLIP视觉输出" + "model": { + "name": "模型" }, - "conditioning": { - "name": "条件" + "model_patch": { + "name": "模型补丁" }, - "noise_augmentation": { - "name": "噪波增强" + "vae": { + "name": "VAE" }, "strength": { "name": "强度" + }, + "image": { + "name": "图像" + }, + "inpaint_image": { + "name": "重绘图像" + }, + "mask": { + "name": "遮罩" } } } -} +} \ No newline at end of file diff --git a/src/locales/zh/settings.json b/src/locales/zh/settings.json index 8098393e3..847861dfe 100644 --- a/src/locales/zh/settings.json +++ b/src/locales/zh/settings.json @@ -19,11 +19,11 @@ }, "Comfy-Desktop_WindowStyle": { "name": "窗口样式", + "tooltip": "选择自定义选项以隐藏系统标题栏", "options": { - "custom": "自定义", - "default": "默认" - }, - "tooltip": "选择自定义选项以隐藏系统标题栏" + "default": "默认", + "custom": "自定义" + } }, "Comfy_Canvas_BackgroundImage": { "name": "画布背景图像", @@ -46,9 +46,9 @@ "Comfy_Canvas_NavigationMode": { "name": "画布导航模式", "options": { - "Custom": "自定义", + "Standard (New)": "标准(新)", "Drag Navigation": "拖动画布", - "Standard (New)": "标准(新)" + "Custom": "自定义" } }, "Comfy_Canvas_SelectionToolbox": { @@ -81,14 +81,14 @@ }, "Comfy_Execution_PreviewMethod": { "name": "实时预览", + "tooltip": "图像生成过程中实时预览。 \"默认\" 使用服务器 CLI 设置。", "options": { - "auto": "自动", "default": "默认", - "latent2rgb": "latent2rgb", "none": "无", + "auto": "自动", + "latent2rgb": "latent2rgb", "taesd": "taesd" - }, - "tooltip": "图像生成过程中实时预览。 \"默认\" 使用服务器 CLI 设置。" + } }, "Comfy_FloatRoundingPrecision": { "name": "浮点组件四舍五入的小数位数 [0 = 自动]。", @@ -106,9 +106,9 @@ "Comfy_Graph_LinkMarkers": { "name": "连线中点标记", "options": { - "Arrow": "箭头", + "None": "无", "Circle": "圆", - "None": "无" + "Arrow": "箭头" } }, "Comfy_Graph_LiveSelection": { @@ -128,25 +128,25 @@ "name": "释放连线时的操作", "options": { "context menu": "上下文菜单", - "no action": "无操作", - "search box": "搜索框" + "search box": "搜索框", + "no action": "无操作" } }, "Comfy_LinkRelease_ActionShift": { "name": "释放连线时的操作(Shift)", "options": { "context menu": "上下文菜单", - "no action": "无操作", - "search box": "搜索框" + "search box": "搜索框", + "no action": "无操作" } }, "Comfy_LinkRenderMode": { "name": "连线渲染样式", "options": { - "Hidden": "隐藏", + "Straight": "直角线", "Linear": "直线", "Spline": "曲线", - "Straight": "直角线" + "Hidden": "隐藏" } }, "Comfy_Load3D_3DViewerEnable": { @@ -159,11 +159,11 @@ }, "Comfy_Load3D_CameraType": { "name": "摄像机类型", + "tooltip": "控制创建新的3D小部件时,默认的相机是透视还是正交。这个默认设置仍然可以在创建后为每个小部件单独切换。", "options": { - "orthographic": "正交", - "perspective": "透视" - }, - "tooltip": "控制创建新的3D小部件时,默认的相机是透视还是正交。这个默认设置仍然可以在创建后为每个小部件单独切换。" + "perspective": "透视", + "orthographic": "正交" + } }, "Comfy_Load3D_LightAdjustmentIncrement": { "name": "光照调整步长", @@ -183,12 +183,12 @@ }, "Comfy_Load3D_PLYEngine": { "name": "PLY 引擎", + "tooltip": "选择加载 PLY 文件的引擎。 \"threejs\" 使用原生 Three.js PLY 加载器(最适合网格 PLY)。 \"fastply\" 使用专用于 ASCII 点云的 PLY 文件加载器。 \"sparkjs\" 使用 Spark.js 加载 3D 高斯泼溅 PLY 文件。", "options": { + "threejs": "threejs", "fastply": "fastply", - "sparkjs": "sparkjs", - "threejs": "threejs" - }, - "tooltip": "选择加载 PLY 文件的引擎。 \"threejs\" 使用原生 Three.js PLY 加载器(最适合网格 PLY)。 \"fastply\" 使用专用于 ASCII 点云的 PLY 文件加载器。 \"sparkjs\" 使用 Spark.js 加载 3D 高斯泼溅 PLY 文件。" + "sparkjs": "sparkjs" + } }, "Comfy_Load3D_ShowGrid": { "name": "显示网格", @@ -211,11 +211,11 @@ }, "Comfy_ModelLibrary_NameFormat": { "name": "在模型库树视图中显示的名称", + "tooltip": "选择“文件名”以在模型列表中显示原始文件名的简化视图(不带目录和“.safetensors”后缀名)。选择“标题”以显示可配置的模型元数据标题。", "options": { "filename": "文件名", "title": "标题" - }, - "tooltip": "选择“文件名”以在模型列表中显示原始文件名的简化视图(不带目录和“.safetensors”后缀名)。选择“标题”以显示可配置的模型元数据标题。" + } }, "Comfy_Node_AllowImageSizeDraw": { "name": "在图像预览下方显示宽度×高度" @@ -266,9 +266,9 @@ "Comfy_NodeBadge_NodeSourceBadgeMode": { "name": "节点源标签", "options": { - "Hide built-in": "仅第三方", "None": "无", - "Show all": "显示全部" + "Show all": "显示全部", + "Hide built-in": "仅第三方" } }, "Comfy_NodeBadge_ShowApiPricing": { @@ -349,8 +349,8 @@ "Comfy_Sidebar_Style": { "name": "侧边栏样式", "options": { - "connected": "连接式", - "floating": "浮动式" + "floating": "浮动式", + "connected": "连接式" } }, "Comfy_Sidebar_UnifiedWidth": { @@ -371,11 +371,11 @@ }, "Comfy_UseNewMenu": { "name": "使用新菜单", + "tooltip": "选单列位置。在行动装置上,选单始终显示于顶端。", "options": { "Disabled": "禁用", "Top": "顶部" - }, - "tooltip": "选单列位置。在行动装置上,选单始终显示于顶端。" + } }, "Comfy_Validation_Workflows": { "name": "校验工作流" @@ -390,11 +390,11 @@ }, "Comfy_WidgetControlMode": { "name": "组件控制模式", + "tooltip": "控制组件值的更新时机(随机/增加/减少),可以在执行工作流之前或之后。", "options": { - "after": "之后", - "before": "之前" - }, - "tooltip": "控制组件值的更新时机(随机/增加/减少),可以在执行工作流之前或之后。" + "before": "之前", + "after": "之后" + } }, "Comfy_Window_UnloadConfirmation": { "name": "关闭窗口时显示确认" @@ -402,8 +402,8 @@ "Comfy_Workflow_AutoSave": { "name": "自动保存", "options": { - "after delay": "延迟后", - "off": "关闭" + "off": "关闭", + "after delay": "延迟后" } }, "Comfy_Workflow_AutoSaveDelay": { diff --git a/tests-ui/platform/assets/components/AssetBrowserModal.test.ts b/src/platform/assets/components/AssetBrowserModal.test.ts similarity index 100% rename from tests-ui/platform/assets/components/AssetBrowserModal.test.ts rename to src/platform/assets/components/AssetBrowserModal.test.ts diff --git a/src/platform/assets/components/AssetBrowserModal.vue b/src/platform/assets/components/AssetBrowserModal.vue index 40cc1fb1b..cd89591aa 100644 --- a/src/platform/assets/components/AssetBrowserModal.vue +++ b/src/platform/assets/components/AssetBrowserModal.vue @@ -83,6 +83,7 @@ import { useModelUpload } from '@/platform/assets/composables/useModelUpload' import type { AssetItem } from '@/platform/assets/schemas/assetSchema' import { assetService } from '@/platform/assets/services/assetService' import { formatCategoryLabel } from '@/platform/assets/utils/categoryLabel' +import { useAssetDownloadStore } from '@/stores/assetDownloadStore' import { useModelToNodeStore } from '@/stores/modelToNodeStore' import { OnCloseKey } from '@/types/widgetTypes' @@ -132,6 +133,17 @@ watch( { immediate: true } ) +const assetDownloadStore = useAssetDownloadStore() + +watch( + () => assetDownloadStore.hasActiveDownloads, + async (currentlyActive, previouslyActive) => { + if (previouslyActive && !currentlyActive) { + await execute() + } + } +) + const { searchQuery, selectedCategory, diff --git a/tests-ui/platform/assets/components/AssetFilterBar.test.ts b/src/platform/assets/components/AssetFilterBar.test.ts similarity index 100% rename from tests-ui/platform/assets/components/AssetFilterBar.test.ts rename to src/platform/assets/components/AssetFilterBar.test.ts diff --git a/src/platform/assets/components/MediaAssetFilterBar.vue b/src/platform/assets/components/MediaAssetFilterBar.vue index 0eca412bd..6a0fcdb93 100644 --- a/src/platform/assets/components/MediaAssetFilterBar.vue +++ b/src/platform/assets/components/MediaAssetFilterBar.vue @@ -31,18 +31,26 @@ /> + diff --git a/src/platform/assets/components/UploadModelDialog.vue b/src/platform/assets/components/UploadModelDialog.vue index d6be9e97e..3a7c76bfe 100644 --- a/src/platform/assets/components/UploadModelDialog.vue +++ b/src/platform/assets/components/UploadModelDialog.vue @@ -25,8 +25,8 @@ {{ $t('assetBrowser.upload') }} () const emit = defineEmits<{ diff --git a/src/platform/assets/components/UploadModelProgress.vue b/src/platform/assets/components/UploadModelProgress.vue index 839b5d3b4..e541e9bc0 100644 --- a/src/platform/assets/components/UploadModelProgress.vue +++ b/src/platform/assets/components/UploadModelProgress.vue @@ -1,22 +1,36 @@