Prepare your next release

Upload scripts

Drop files anywhere or choose them below. Review each destination before uploading.

{preferredTarget ? `New version for ${scripts.find(s => s.id === preferredTarget)?.name ?? 'script'}` : 'One file or a whole batch'} Existing filenames are recognized automatically. { void addFiles([...event.currentTarget.files ?? []]); event.currentTarget.value = ''; }} />
{#each queue as item (item.key)}
{item.file.name}{(item.file.size / 1024).toFixed(1)} KB
{#if item.result}

{item.result.reused ? 'Already uploaded' : 'Uploaded'} as v{item.result.version} · View script →

{:else} {#if item.target === 'new'} {:else if item.target !== ''}{@const s = scripts.find(s => s.id === item.target)}

Keeps scope: {s ? scopeLabel(s) : '—'}. Target: {s?.target_rel_path}

{/if} {#if item.inspecting}

Checking file contents…

{:else if duplicate(item)}

Already uploaded as v{duplicate(item)!.version}. We’ll reuse that version.

{:else if item.target !== 'new' && item.target !== ''}

New version for {scripts.find(s => s.id === item.target)?.name}

{/if} {#if validation(item)}

{validation(item)}

{/if} {#if item.error}{#if !item.inspected}{/if}{/if} {/if}
{/each}
{#if pending.length}

Shared upload details

{#if hasNew} {#if scopeType !== 'none'} {#if scopeType === 'map'}{/if} {#if scopeValue}

{matches.length} matching servers: {matches.map(s => s.name).join(', ') || 'None'}

{/if} {#if scopeType === 'map' && scopeGame === 't6'}

Map scope includes every server using this engine map, including its Survival, Grief, or other variants.

{/if} {:else}

Unscoped scripts deploy only to explicitly selected beta targets.

{/if}

Existing scripts keep their current scope.

{/if}
{/if} {#if message}

{message}

{/if}