ctx.onselect(node.id, e.shiftKey)} style=" width: {node.width}px; --accent: {accentColor}; --accent-dim: {accentDim}; " >
{#if status === "running"} {/if} {#if editingLabel} renameNode(e.currentTarget.value)} onkeydown={(e) => { if (e.key === "Enter") renameNode(e.currentTarget.value); if (e.key === "Escape") editingLabel = false; e.stopPropagation(); }} onmousedown={(e) => e.stopPropagation()} /> {:else} { e.stopPropagation(); if (readOnly) return; editingLabel = true; requestAnimationFrame(() => labelInput?.select()); }}>{node.label} {/if} {#if canRunSolo} {/if} {#if !readOnly} {/if}
{#if node.kind === "transform"} {#if node.space_id || node.model_id || node.dataset_id} {@const itemId = node.space_id ?? node.model_id ?? node.dataset_id ?? ""}
{#if readOnly} {itemId.split("/").pop() ?? itemId} {:else} {/if} e.stopPropagation()} onmousedown={(e) => e.stopPropagation()} onclick={(e) => e.stopPropagation()} aria-label="Open on HuggingFace" >
{:else if node.fn}
{node.fn}()
{:else if !readOnly} {/if} {/if} {#if node.space_id}
e.stopPropagation()} onmousedown={(e) => e.stopPropagation()} > {#if node.endpoints && node.endpoints.length > 1} {:else if !node.endpoints} {/if}
{/if} {#if node.inputs.length > 0} {@const hiddenCount = node.inputs.filter( (p) => p.required === false && !connectedPorts.has(`${node.id}:${p.id}:input`) ).length} {@const collapsible = hiddenCount > 0}
{#each node.inputs as port} {@const portConnected = connectedPorts.has( `${node.id}:${port.id}:input` )} {@const visible = showAllInputs || portConnected || port.required !== false} {#if visible}
ctx.onportpointerdown(e, node.id, port.id, port.type, true)} onclick={(e) => { if (!portConnected && pending === null) { e.stopPropagation(); ctx.onpopout(node.id, port.id, port.type, true); } }} >
{#if !hasWidget} {port.label} {port.type} {/if}
{#if !portConnected && node.kind === "transform" && (port.type === "text" || port.type === "number" || port.type === "boolean" || port.type === "any" || port.type === "json")}
e.stopPropagation()} > {#if port.choices && port.choices.length > 0 && port.multiselect} {@const selected = Array.isArray(node.data?.[port.id]) ? (node.data[port.id] as string[]) : []}
{#each port.choices as choice} {/each}
{:else if port.choices && port.choices.length > 0} {@const raw = node.data?.[port.id] ?? port.default_value} {@const current = raw != null ? String(raw) : ""} {@const hasCurrent = port.choices.includes(current)} {:else if port.type === "number"} ctx.ondatachange( node.id, port.id, parseFloat(e.currentTarget.value) || 0 )} /> {:else if port.type === "boolean"} {:else} ctx.ondatachange(node.id, port.id, e.currentTarget.value)} /> {/if}
{/if} {/if} {/each} {#if collapsible} {/if}
{/if} {#if hasWidget && widgetPortId && widgetType} {/if} {#if node.outputs.length > 0}
{#each node.outputs as port} {@const portConnected = connectedPorts.has( `${node.id}:${port.id}:output` )}
{#if !hasWidget} {port.type} {port.label} {/if}
ctx.onportpointerdown(e, node.id, port.id, port.type, false)} onclick={(e) => { if (!readOnly && !portConnected && pending === null) { e.stopPropagation(); ctx.onpopout(node.id, port.id, port.type, false); } }} >
{/each}
{/if} {#if status === "error" && error}
{error}
{/if}