make models only train one at the time closes #48

This commit is contained in:
Andre Henriques 2024-04-15 23:04:53 +01:00
parent 2318bad5d8
commit f4e70d7a73
11 changed files with 607 additions and 475 deletions

View File

@ -19,11 +19,17 @@ import (
type BasePack interface {
GetDb() *sql.DB
GetLogger() *log.Logger
GetHost() string
}
type BasePackStruct struct {
Db *sql.DB
Logger *log.Logger
Host string
}
func (b BasePackStruct) GetHost() string {
return b.Host
}
func (b BasePackStruct) GetDb() *sql.DB {

View File

@ -5,7 +5,6 @@ import (
"errors"
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/db_types"
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/utils"
)
type ModelClass struct {
@ -15,8 +14,8 @@ type ModelClass struct {
Status int `json:"status"`
}
func ListClasses(c *Context, model_id string) (cls []*ModelClass, err error) {
return GetDbMultitple[ModelClass](c, "model_classes where model_id=$1", model_id)
func ListClasses(c BasePack, model_id string) (cls []*ModelClass, err error) {
return GetDbMultitple[ModelClass](c.GetDb(), "model_classes where model_id=$1", model_id)
}
func ModelHasDataPoints(db *sql.DB, model_id string) (result bool, err error) {

File diff suppressed because it is too large Load Diff

View File

@ -3,13 +3,16 @@ package task_runner
import (
"database/sql"
"fmt"
"math"
"os"
"runtime/debug"
"time"
"github.com/charmbracelet/log"
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/db_types"
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/models"
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/models/train"
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/tasks/utils"
. "git.andr3h3nriqu3s.com/andr3/fyp/logic/utils"
)
@ -17,7 +20,7 @@ import (
/**
* Actually runs the code
*/
func runner(db *sql.DB, task_channel chan Task, index int, back_channel chan int) {
func runner(config Config, db *sql.DB, task_channel chan Task, index int, back_channel chan int) {
logger := log.NewWithOptions(os.Stdout, log.Options{
ReportCaller: true,
ReportTimestamp: true,
@ -27,36 +30,46 @@ func runner(db *sql.DB, task_channel chan Task, index int, back_channel chan int
defer func() {
if r := recover(); r != nil {
logger.Error("Recovered in file processor", "processor id", index, "due to", r)
logger.Error("Recovered in runner", "processor id", index, "due to", r, "stack", string(debug.Stack()))
back_channel <- -index
}
}()
logger.Info("Started up")
var err error
var err error
base := BasePackStruct{
Db: db,
Logger: logger,
}
base := BasePackStruct{
Db: db,
Logger: logger,
Host: config.Hostname,
}
for task := range task_channel {
logger.Info("Got task", "task", task)
task.UpdateStatusLog(base, TASK_PICKED_UP, "Runner picked up task")
if task.TaskType == int(TASK_TYPE_CLASSIFICATION) {
logger.Info("Classification Task")
if err = ClassifyTask(base, task); err != nil {
logger.Error("Classification task failed", "error", "err")
}
if task.TaskType == int(TASK_TYPE_CLASSIFICATION) {
logger.Info("Classification Task")
if err = ClassifyTask(base, task); err != nil {
logger.Error("Classification task failed", "error", err)
}
back_channel <- index
continue
}
back_channel <- index
continue
} else if task.TaskType == int(TASK_TYPE_TRAINING) {
logger.Info("Training Task")
if err = RunTaskTrain(base, task); err != nil {
logger.Error("Failed to tain the model", "error", err)
}
back_channel <- index
continue
}
logger.Error("Do not know how to route task", "task", task)
back_channel <- index
logger.Error("Do not know how to route task", "task", task)
task.UpdateStatusLog(base, TASK_FAILED_RUNNING, "Do not know how to route task")
back_channel <- index
}
}
@ -71,18 +84,24 @@ func attentionSeeker(config Config, back_channel chan int) {
Prefix: "Runner Orchestrator Logger [Attention]",
})
defer func() {
if r := recover(); r != nil {
logger.Error("Attencion seeker dies", "due to", r)
}
}()
logger.Info("Started up")
t, err := time.ParseDuration(config.GpuWorker.Pulling)
if err != nil {
logger.Error("Failed to load", "error", err)
return
}
t, err := time.ParseDuration(config.GpuWorker.Pulling)
if err != nil {
logger.Error("Failed to load", "error", err)
return
}
for true {
back_channel <- 0
time.Sleep(t)
time.Sleep(t)
}
}
@ -106,16 +125,27 @@ func RunnerOrchestrator(db *sql.DB, config Config) {
// One more to accomudate the Attention Seeker channel
back_channel := make(chan int, gpu_workers+1)
defer func() {
if r := recover(); r != nil {
logger.Error("Recovered in Orchestrator restarting", "due to", r)
for x := range task_runners {
close(task_runners[x])
}
close(back_channel)
go RunnerOrchestrator(db, config)
}
}()
go attentionSeeker(config, back_channel)
// Start the runners
for i := 0; i < gpu_workers; i++ {
task_runners[i] = make(chan Task, 10)
task_runners_used[i] = false
go runner(db, task_runners[i], i+1, back_channel)
go runner(config, db, task_runners[i], i+1, back_channel)
}
var task_to_dispatch *Task = nil
var task_to_dispatch *Task = nil
for i := range back_channel {
@ -124,34 +154,35 @@ func RunnerOrchestrator(db *sql.DB, config Config) {
task_runners_used[i-1] = false
} else if i < 0 {
logger.Error("Runner died! Restarting!", "runner", i)
task_runners_used[i-1] = false
go runner(db, task_runners[i-1], i, back_channel)
i = int(math.Abs(float64(i)) - 1)
task_runners_used[i] = false
go runner(config, db, task_runners[i], i+1, back_channel)
}
if task_to_dispatch == nil {
var task Task
err := GetDBOnce(db, &task, "tasks where status=$1 limit 1", TASK_TODO)
if err != NotFoundError && err != nil{
log.Error("Failed to get tasks from db")
continue
}
if err == NotFoundError {
task_to_dispatch = nil
} else {
task_to_dispatch = &task
}
}
if task_to_dispatch == nil {
var task Task
err := GetDBOnce(db, &task, "tasks where status=$1 limit 1", TASK_TODO)
if err != NotFoundError && err != nil {
log.Error("Failed to get tasks from db")
continue
}
if err == NotFoundError {
task_to_dispatch = nil
} else {
task_to_dispatch = &task
}
}
if task_to_dispatch != nil {
for i := 0; i < len(task_runners_used); i += 1 {
if !task_runners_used[i] {
task_runners[i] <- *task_to_dispatch
task_runners_used[i] = true
task_to_dispatch = nil
break
}
}
}
if task_to_dispatch != nil {
for i := 0; i < len(task_runners_used); i += 1 {
if !task_runners_used[i] {
task_runners[i] <- *task_to_dispatch
task_runners_used[i] = true
task_to_dispatch = nil
break
}
}
}
}
}

View File

@ -16,6 +16,7 @@ type Task struct {
UserConfirmed int `db:"user_confirmed" json:"user_confirmed"`
Compacted int `db:"compacted" json:"compacted"`
TaskType int `db:"task_type" json:"type"`
ExtraTaskInfo string `db:"extra_task_info" json:"extra_task_info"`
Result string `db:"result" json:"result"`
CreatedOn time.Time `db:"created_on" json:"created"`
}
@ -35,7 +36,8 @@ const (
type TaskType int
const (
TASK_TYPE_CLASSIFICATION TaskType = 1
TASK_TYPE_CLASSIFICATION TaskType = 1 + iota
TASK_TYPE_TRAINING
)
func (t Task) UpdateStatus(base BasePack, status TaskStatus, message string) (err error) {

View File

@ -199,6 +199,10 @@ func (c Context) GetLogger() *log.Logger {
return c.Logger
}
func (c Context) GetHost() string {
return c.Handle.Config.Hostname
}
func (c Context) Query(query string, args ...any) (*sql.Rows, error) {
return c.Db.Query(query, args...)
}
@ -337,11 +341,11 @@ func (c *Context) GetModelFromId(id_path string) (*dbtypes.BaseModel, *Error) {
return model, nil
}
func ModelUpdateStatus(c *Context, id string, status int) {
_, err := c.Db.Exec("update models set status=$1 where id=$2;", status, id)
func ModelUpdateStatus(c dbtypes.BasePack, id string, status int) {
_, err := c.GetDb().Exec("update models set status=$1 where id=$2;", status, id)
if err != nil {
c.Logger.Error("Failed to update model status", "err", err)
c.Logger.Warn("TODO Maybe handle better")
c.GetLogger().Error("Failed to update model status", "err", err)
c.GetLogger().Warn("TODO Maybe handle better")
}
}

View File

@ -15,6 +15,7 @@ create table if not exists tasks (
status_message text default '',
result text default '',
extra_task_info text default '',
-- -1: user said task is wrong
-- 0: no user input

View File

@ -13,23 +13,23 @@
"format": "prettier --write ."
},
"devDependencies": {
"@sveltejs/adapter-auto": "^3.0.0",
"@sveltejs/adapter-auto": "^3.2.0",
"@sveltejs/kit": "^2.5.6",
"@sveltejs/vite-plugin-svelte": "3.0.0",
"@types/eslint": "^8.56.0",
"@typescript-eslint/eslint-plugin": "^7.0.0",
"@typescript-eslint/parser": "^7.0.0",
"eslint": "^8.56.0",
"@types/eslint": "^8.56.9",
"@typescript-eslint/eslint-plugin": "^7.7.0",
"@typescript-eslint/parser": "^7.7.0",
"eslint": "^8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-svelte": "^2.36.0-next.4",
"prettier": "^3.1.1",
"prettier-plugin-svelte": "^3.1.2",
"sass": "^1.71.1",
"svelte": "^5.0.0-next.102",
"svelte-check": "^3.6.0",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^5.0.3"
"eslint-plugin-svelte": "^2.37.0",
"prettier": "^3.2.5",
"prettier-plugin-svelte": "^3.2.3",
"sass": "^1.75.0",
"svelte": "5.0.0-next.104",
"svelte-check": "^3.6.9",
"tslib": "^2.6.2",
"typescript": "^5.4.5",
"vite": "^5.2.8"
},
"type": "module",
"dependencies": {

View File

@ -11,55 +11,55 @@ dependencies:
devDependencies:
'@sveltejs/adapter-auto':
specifier: ^3.0.0
specifier: ^3.2.0
version: 3.2.0(@sveltejs/kit@2.5.6)
'@sveltejs/kit':
specifier: ^2.5.6
version: 2.5.6(@sveltejs/vite-plugin-svelte@3.0.0)(svelte@5.0.0-next.102)(vite@5.2.8)
version: 2.5.6(@sveltejs/vite-plugin-svelte@3.0.0)(svelte@5.0.0-next.104)(vite@5.2.8)
'@sveltejs/vite-plugin-svelte':
specifier: 3.0.0
version: 3.0.0(svelte@5.0.0-next.102)(vite@5.2.8)
version: 3.0.0(svelte@5.0.0-next.104)(vite@5.2.8)
'@types/eslint':
specifier: ^8.56.0
specifier: ^8.56.9
version: 8.56.9
'@typescript-eslint/eslint-plugin':
specifier: ^7.0.0
version: 7.6.0(@typescript-eslint/parser@7.6.0)(eslint@8.57.0)(typescript@5.4.5)
specifier: ^7.7.0
version: 7.7.0(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/parser':
specifier: ^7.0.0
version: 7.6.0(eslint@8.57.0)(typescript@5.4.5)
specifier: ^7.7.0
version: 7.7.0(eslint@8.57.0)(typescript@5.4.5)
eslint:
specifier: ^8.56.0
specifier: ^8.57.0
version: 8.57.0
eslint-config-prettier:
specifier: ^9.1.0
version: 9.1.0(eslint@8.57.0)
eslint-plugin-svelte:
specifier: ^2.36.0-next.4
version: 2.37.0(eslint@8.57.0)(svelte@5.0.0-next.102)
specifier: ^2.37.0
version: 2.37.0(eslint@8.57.0)(svelte@5.0.0-next.104)
prettier:
specifier: ^3.1.1
specifier: ^3.2.5
version: 3.2.5
prettier-plugin-svelte:
specifier: ^3.1.2
version: 3.2.3(prettier@3.2.5)(svelte@5.0.0-next.102)
specifier: ^3.2.3
version: 3.2.3(prettier@3.2.5)(svelte@5.0.0-next.104)
sass:
specifier: ^1.71.1
specifier: ^1.75.0
version: 1.75.0
svelte:
specifier: ^5.0.0-next.102
version: 5.0.0-next.102
specifier: 5.0.0-next.104
version: 5.0.0-next.104
svelte-check:
specifier: ^3.6.0
version: 3.6.9(postcss@8.4.38)(sass@1.75.0)(svelte@5.0.0-next.102)
specifier: ^3.6.9
version: 3.6.9(postcss@8.4.38)(sass@1.75.0)(svelte@5.0.0-next.104)
tslib:
specifier: ^2.4.1
specifier: ^2.6.2
version: 2.6.2
typescript:
specifier: ^5.0.0
specifier: ^5.4.5
version: 5.4.5
vite:
specifier: ^5.0.3
specifier: ^5.2.8
version: 5.2.8(sass@1.75.0)
packages:
@ -400,120 +400,128 @@ packages:
resolution: {integrity: sha512-j7P6Rgr3mmtdkeDGTe0E/aYyWEWVtc5yFXtHCRHs28/jptDEWfaVOc5T7cblqy1XKPPfCxJc/8DwQ5YgLOZOVQ==}
dev: true
/@rollup/rollup-android-arm-eabi@4.14.2:
resolution: {integrity: sha512-ahxSgCkAEk+P/AVO0vYr7DxOD3CwAQrT0Go9BJyGQ9Ef0QxVOfjDZMiF4Y2s3mLyPrjonchIMH/tbWHucJMykQ==}
/@rollup/rollup-android-arm-eabi@4.14.3:
resolution: {integrity: sha512-X9alQ3XM6I9IlSlmC8ddAvMSyG1WuHk5oUnXGw+yUBs3BFoTizmG1La/Gr8fVJvDWAq+zlYTZ9DBgrlKRVY06g==}
cpu: [arm]
os: [android]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-android-arm64@4.14.2:
resolution: {integrity: sha512-lAarIdxZWbFSHFSDao9+I/F5jDaKyCqAPMq5HqnfpBw8dKDiCaaqM0lq5h1pQTLeIqueeay4PieGR5jGZMWprw==}
/@rollup/rollup-android-arm64@4.14.3:
resolution: {integrity: sha512-eQK5JIi+POhFpzk+LnjKIy4Ks+pwJ+NXmPxOCSvOKSNRPONzKuUvWE+P9JxGZVxrtzm6BAYMaL50FFuPe0oWMQ==}
cpu: [arm64]
os: [android]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-darwin-arm64@4.14.2:
resolution: {integrity: sha512-SWsr8zEUk82KSqquIMgZEg2GE5mCSfr9sE/thDROkX6pb3QQWPp8Vw8zOq2GyxZ2t0XoSIUlvHDkrf5Gmf7x3Q==}
/@rollup/rollup-darwin-arm64@4.14.3:
resolution: {integrity: sha512-Od4vE6f6CTT53yM1jgcLqNfItTsLt5zE46fdPaEmeFHvPs5SjZYlLpHrSiHEKR1+HdRfxuzXHjDOIxQyC3ptBA==}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-darwin-x64@4.14.2:
resolution: {integrity: sha512-o/HAIrQq0jIxJAhgtIvV5FWviYK4WB0WwV91SLUnsliw1lSAoLsmgEEgRWzDguAFeUEUUoIWXiJrPqU7vGiVkA==}
/@rollup/rollup-darwin-x64@4.14.3:
resolution: {integrity: sha512-0IMAO21axJeNIrvS9lSe/PGthc8ZUS+zC53O0VhF5gMxfmcKAP4ESkKOCwEi6u2asUrt4mQv2rjY8QseIEb1aw==}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-arm-gnueabihf@4.14.2:
resolution: {integrity: sha512-nwlJ65UY9eGq91cBi6VyDfArUJSKOYt5dJQBq8xyLhvS23qO+4Nr/RreibFHjP6t+5ap2ohZrUJcHv5zk5ju/g==}
/@rollup/rollup-linux-arm-gnueabihf@4.14.3:
resolution: {integrity: sha512-ge2DC7tHRHa3caVEoSbPRJpq7azhG+xYsd6u2MEnJ6XzPSzQsTKyXvh6iWjXRf7Rt9ykIUWHtl0Uz3T6yXPpKw==}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-arm64-gnu@4.14.2:
resolution: {integrity: sha512-Pg5TxxO2IVlMj79+c/9G0LREC9SY3HM+pfAwX7zj5/cAuwrbfj2Wv9JbMHIdPCfQpYsI4g9mE+2Bw/3aeSs2rQ==}
/@rollup/rollup-linux-arm-musleabihf@4.14.3:
resolution: {integrity: sha512-ljcuiDI4V3ySuc7eSk4lQ9wU8J8r8KrOUvB2U+TtK0TiW6OFDmJ+DdIjjwZHIw9CNxzbmXY39wwpzYuFDwNXuw==}
cpu: [arm]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-arm64-gnu@4.14.3:
resolution: {integrity: sha512-Eci2us9VTHm1eSyn5/eEpaC7eP/mp5n46gTRB3Aar3BgSvDQGJZuicyq6TsH4HngNBgVqC5sDYxOzTExSU+NjA==}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-arm64-musl@4.14.2:
resolution: {integrity: sha512-cAOTjGNm84gc6tS02D1EXtG7tDRsVSDTBVXOLbj31DkwfZwgTPYZ6aafSU7rD/4R2a34JOwlF9fQayuTSkoclA==}
/@rollup/rollup-linux-arm64-musl@4.14.3:
resolution: {integrity: sha512-UrBoMLCq4E92/LCqlh+blpqMz5h1tJttPIniwUgOFJyjWI1qrtrDhhpHPuFxULlUmjFHfloWdixtDhSxJt5iKw==}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-powerpc64le-gnu@4.14.2:
resolution: {integrity: sha512-4RyT6v1kXb7C0fn6zV33rvaX05P0zHoNzaXI/5oFHklfKm602j+N4mn2YvoezQViRLPnxP8M1NaY4s/5kXO5cw==}
/@rollup/rollup-linux-powerpc64le-gnu@4.14.3:
resolution: {integrity: sha512-5aRjvsS8q1nWN8AoRfrq5+9IflC3P1leMoy4r2WjXyFqf3qcqsxRCfxtZIV58tCxd+Yv7WELPcO9mY9aeQyAmw==}
cpu: [ppc64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-riscv64-gnu@4.14.2:
resolution: {integrity: sha512-KNUH6jC/vRGAKSorySTyc/yRYlCwN/5pnMjXylfBniwtJx5O7X17KG/0efj8XM3TZU7raYRXJFFReOzNmL1n1w==}
/@rollup/rollup-linux-riscv64-gnu@4.14.3:
resolution: {integrity: sha512-sk/Qh1j2/RJSX7FhEpJn8n0ndxy/uf0kI/9Zc4b1ELhqULVdTfN6HL31CDaTChiBAOgLcsJ1sgVZjWv8XNEsAQ==}
cpu: [riscv64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-s390x-gnu@4.14.2:
resolution: {integrity: sha512-xPV4y73IBEXToNPa3h5lbgXOi/v0NcvKxU0xejiFw6DtIYQqOTMhZ2DN18/HrrP0PmiL3rGtRG9gz1QE8vFKXQ==}
/@rollup/rollup-linux-s390x-gnu@4.14.3:
resolution: {integrity: sha512-jOO/PEaDitOmY9TgkxF/TQIjXySQe5KVYB57H/8LRP/ux0ZoO8cSHCX17asMSv3ruwslXW/TLBcxyaUzGRHcqg==}
cpu: [s390x]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-x64-gnu@4.14.2:
resolution: {integrity: sha512-QBhtr07iFGmF9egrPOWyO5wciwgtzKkYPNLVCFZTmr4TWmY0oY2Dm/bmhHjKRwZoGiaKdNcKhFtUMBKvlchH+Q==}
/@rollup/rollup-linux-x64-gnu@4.14.3:
resolution: {integrity: sha512-8ybV4Xjy59xLMyWo3GCfEGqtKV5M5gCSrZlxkPGvEPCGDLNla7v48S662HSGwRd6/2cSneMQWiv+QzcttLrrOA==}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-linux-x64-musl@4.14.2:
resolution: {integrity: sha512-8zfsQRQGH23O6qazZSFY5jP5gt4cFvRuKTpuBsC1ZnSWxV8ZKQpPqOZIUtdfMOugCcBvFGRa1pDC/tkf19EgBw==}
/@rollup/rollup-linux-x64-musl@4.14.3:
resolution: {integrity: sha512-s+xf1I46trOY10OqAtZ5Rm6lzHre/UiLA1J2uOhCFXWkbZrJRkYBPO6FhvGfHmdtQ3Bx793MNa7LvoWFAm93bg==}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-win32-arm64-msvc@4.14.2:
resolution: {integrity: sha512-H4s8UjgkPnlChl6JF5empNvFHp77Jx+Wfy2EtmYPe9G22XV+PMuCinZVHurNe8ggtwoaohxARJZbaH/3xjB/FA==}
/@rollup/rollup-win32-arm64-msvc@4.14.3:
resolution: {integrity: sha512-+4h2WrGOYsOumDQ5S2sYNyhVfrue+9tc9XcLWLh+Kw3UOxAvrfOrSMFon60KspcDdytkNDh7K2Vs6eMaYImAZg==}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-win32-ia32-msvc@4.14.2:
resolution: {integrity: sha512-djqpAjm/i8erWYF0K6UY4kRO3X5+T4TypIqw60Q8MTqSBaQNpNXDhxdjpZ3ikgb+wn99svA7jxcXpiyg9MUsdw==}
/@rollup/rollup-win32-ia32-msvc@4.14.3:
resolution: {integrity: sha512-T1l7y/bCeL/kUwh9OD4PQT4aM7Bq43vX05htPJJ46RTI4r5KNt6qJRzAfNfM+OYMNEVBWQzR2Gyk+FXLZfogGw==}
cpu: [ia32]
os: [win32]
requiresBuild: true
dev: true
optional: true
/@rollup/rollup-win32-x64-msvc@4.14.2:
resolution: {integrity: sha512-teAqzLT0yTYZa8ZP7zhFKEx4cotS8Tkk5XiqNMJhD4CpaWB1BHARE4Qy+RzwnXvSAYv+Q3jAqCVBS+PS+Yee8Q==}
/@rollup/rollup-win32-x64-msvc@4.14.3:
resolution: {integrity: sha512-/BypzV0H1y1HzgYpxqRaXGBRqfodgoBBCcsrujT6QRcakDQdfU+Lq9PENPh5jB4I44YWq+0C2eHsHya+nZY1sA==}
cpu: [x64]
os: [win32]
requiresBuild: true
@ -525,11 +533,11 @@ packages:
peerDependencies:
'@sveltejs/kit': ^2.0.0
dependencies:
'@sveltejs/kit': 2.5.6(@sveltejs/vite-plugin-svelte@3.0.0)(svelte@5.0.0-next.102)(vite@5.2.8)
'@sveltejs/kit': 2.5.6(@sveltejs/vite-plugin-svelte@3.0.0)(svelte@5.0.0-next.104)(vite@5.2.8)
import-meta-resolve: 4.0.0
dev: true
/@sveltejs/kit@2.5.6(@sveltejs/vite-plugin-svelte@3.0.0)(svelte@5.0.0-next.102)(vite@5.2.8):
/@sveltejs/kit@2.5.6(@sveltejs/vite-plugin-svelte@3.0.0)(svelte@5.0.0-next.104)(vite@5.2.8):
resolution: {integrity: sha512-AYb02Jm5MfNqJHc8zrj7ScQAFAKmTUCkpkfoi8EVaZZDdnjkvI7L2GtnTDhpiXSAZRVitZX4qm59sMS1FgL+lQ==}
engines: {node: '>=18.13'}
hasBin: true
@ -539,7 +547,7 @@ packages:
svelte: ^4.0.0 || ^5.0.0-next.0
vite: ^5.0.3
dependencies:
'@sveltejs/vite-plugin-svelte': 3.0.0(svelte@5.0.0-next.102)(vite@5.2.8)
'@sveltejs/vite-plugin-svelte': 3.0.0(svelte@5.0.0-next.104)(vite@5.2.8)
'@types/cookie': 0.6.0
cookie: 0.6.0
devalue: 4.3.2
@ -551,12 +559,12 @@ packages:
sade: 1.8.1
set-cookie-parser: 2.6.0
sirv: 2.0.4
svelte: 5.0.0-next.102
svelte: 5.0.0-next.104
tiny-glob: 0.2.9
vite: 5.2.8(sass@1.75.0)
dev: true
/@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.0.0)(svelte@5.0.0-next.102)(vite@5.2.8):
/@sveltejs/vite-plugin-svelte-inspector@2.1.0(@sveltejs/vite-plugin-svelte@3.0.0)(svelte@5.0.0-next.104)(vite@5.2.8):
resolution: {integrity: sha512-9QX28IymvBlSCqsCll5t0kQVxipsfhFFL+L2t3nTWfXnddYwxBuAEtTtlaVQpRz9c37BhJjltSeY4AJSC03SSg==}
engines: {node: ^18.0.0 || >=20}
peerDependencies:
@ -564,28 +572,28 @@ packages:
svelte: ^4.0.0 || ^5.0.0-next.0
vite: ^5.0.0
dependencies:
'@sveltejs/vite-plugin-svelte': 3.0.0(svelte@5.0.0-next.102)(vite@5.2.8)
'@sveltejs/vite-plugin-svelte': 3.0.0(svelte@5.0.0-next.104)(vite@5.2.8)
debug: 4.3.4
svelte: 5.0.0-next.102
svelte: 5.0.0-next.104
vite: 5.2.8(sass@1.75.0)
transitivePeerDependencies:
- supports-color
dev: true
/@sveltejs/vite-plugin-svelte@3.0.0(svelte@5.0.0-next.102)(vite@5.2.8):
/@sveltejs/vite-plugin-svelte@3.0.0(svelte@5.0.0-next.104)(vite@5.2.8):
resolution: {integrity: sha512-Th0nupxk8hl5Rcg9jm+1xWylwco4bSUAvutWxM4W4bjOAollpXLmrYqSSnYo9pPbZOO6ZGRm6sSqYa/v1d/Saw==}
engines: {node: ^18.0.0 || >=20}
peerDependencies:
svelte: ^4.0.0 || ^5.0.0-next.0
vite: ^5.0.0
dependencies:
'@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.0.0)(svelte@5.0.0-next.102)(vite@5.2.8)
'@sveltejs/vite-plugin-svelte-inspector': 2.1.0(@sveltejs/vite-plugin-svelte@3.0.0)(svelte@5.0.0-next.104)(vite@5.2.8)
debug: 4.3.4
deepmerge: 4.3.1
kleur: 4.1.5
magic-string: 0.30.9
svelte: 5.0.0-next.102
svelte-hmr: 0.15.3(svelte@5.0.0-next.102)
svelte: 5.0.0-next.104
svelte-hmr: 0.15.3(svelte@5.0.0-next.104)
vite: 5.2.8(sass@1.75.0)
vitefu: 0.2.5(vite@5.2.8)
transitivePeerDependencies:
@ -619,8 +627,8 @@ packages:
resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==}
dev: true
/@typescript-eslint/eslint-plugin@7.6.0(@typescript-eslint/parser@7.6.0)(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-gKmTNwZnblUdnTIJu3e9kmeRRzV2j1a/LUO27KNNAnIC5zjy1aSvXSRp4rVNlmAoHlQ7HzX42NbKpcSr4jF80A==}
/@typescript-eslint/eslint-plugin@7.7.0(@typescript-eslint/parser@7.7.0)(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-GJWR0YnfrKnsRoluVO3PRb9r5aMZriiMMM/RHj5nnTrBy1/wIgk76XCtCKcnXGjpZQJQRFtGV9/0JJ6n30uwpQ==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
'@typescript-eslint/parser': ^7.0.0
@ -631,11 +639,11 @@ packages:
optional: true
dependencies:
'@eslint-community/regexpp': 4.10.0
'@typescript-eslint/parser': 7.6.0(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/scope-manager': 7.6.0
'@typescript-eslint/type-utils': 7.6.0(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/utils': 7.6.0(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 7.6.0
'@typescript-eslint/parser': 7.7.0(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/scope-manager': 7.7.0
'@typescript-eslint/type-utils': 7.7.0(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/utils': 7.7.0(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 7.7.0
debug: 4.3.4
eslint: 8.57.0
graphemer: 1.4.0
@ -648,8 +656,8 @@ packages:
- supports-color
dev: true
/@typescript-eslint/parser@7.6.0(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-usPMPHcwX3ZoPWnBnhhorc14NJw9J4HpSXQX4urF2TPKG0au0XhJoZyX62fmvdHONUkmyUe74Hzm1//XA+BoYg==}
/@typescript-eslint/parser@7.7.0(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-fNcDm3wSwVM8QYL4HKVBggdIPAy9Q41vcvC/GtDobw3c4ndVT3K6cqudUmjHPw8EAp4ufax0o58/xvWaP2FmTg==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
@ -658,10 +666,10 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/scope-manager': 7.6.0
'@typescript-eslint/types': 7.6.0
'@typescript-eslint/typescript-estree': 7.6.0(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 7.6.0
'@typescript-eslint/scope-manager': 7.7.0
'@typescript-eslint/types': 7.7.0
'@typescript-eslint/typescript-estree': 7.7.0(typescript@5.4.5)
'@typescript-eslint/visitor-keys': 7.7.0
debug: 4.3.4
eslint: 8.57.0
typescript: 5.4.5
@ -669,16 +677,16 @@ packages:
- supports-color
dev: true
/@typescript-eslint/scope-manager@7.6.0:
resolution: {integrity: sha512-ngttyfExA5PsHSx0rdFgnADMYQi+Zkeiv4/ZxGYUWd0nLs63Ha0ksmp8VMxAIC0wtCFxMos7Lt3PszJssG/E6w==}
/@typescript-eslint/scope-manager@7.7.0:
resolution: {integrity: sha512-/8INDn0YLInbe9Wt7dK4cXLDYp0fNHP5xKLHvZl3mOT5X17rK/YShXaiNmorl+/U4VKCVIjJnx4Ri5b0y+HClw==}
engines: {node: ^18.18.0 || >=20.0.0}
dependencies:
'@typescript-eslint/types': 7.6.0
'@typescript-eslint/visitor-keys': 7.6.0
'@typescript-eslint/types': 7.7.0
'@typescript-eslint/visitor-keys': 7.7.0
dev: true
/@typescript-eslint/type-utils@7.6.0(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-NxAfqAPNLG6LTmy7uZgpK8KcuiS2NZD/HlThPXQRGwz6u7MDBWRVliEEl1Gj6U7++kVJTpehkhZzCJLMK66Scw==}
/@typescript-eslint/type-utils@7.7.0(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-bOp3ejoRYrhAlnT/bozNQi3nio9tIgv3U5C0mVDdZC7cpcQEDZXvq8inrHYghLVwuNABRqrMW5tzAv88Vy77Sg==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
@ -687,8 +695,8 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/typescript-estree': 7.6.0(typescript@5.4.5)
'@typescript-eslint/utils': 7.6.0(eslint@8.57.0)(typescript@5.4.5)
'@typescript-eslint/typescript-estree': 7.7.0(typescript@5.4.5)
'@typescript-eslint/utils': 7.7.0(eslint@8.57.0)(typescript@5.4.5)
debug: 4.3.4
eslint: 8.57.0
ts-api-utils: 1.3.0(typescript@5.4.5)
@ -697,13 +705,13 @@ packages:
- supports-color
dev: true
/@typescript-eslint/types@7.6.0:
resolution: {integrity: sha512-h02rYQn8J+MureCvHVVzhl69/GAfQGPQZmOMjG1KfCl7o3HtMSlPaPUAPu6lLctXI5ySRGIYk94clD/AUMCUgQ==}
/@typescript-eslint/types@7.7.0:
resolution: {integrity: sha512-G01YPZ1Bd2hn+KPpIbrAhEWOn5lQBrjxkzHkWvP6NucMXFtfXoevK82hzQdpfuQYuhkvFDeQYbzXCjR1z9Z03w==}
engines: {node: ^18.18.0 || >=20.0.0}
dev: true
/@typescript-eslint/typescript-estree@7.6.0(typescript@5.4.5):
resolution: {integrity: sha512-+7Y/GP9VuYibecrCQWSKgl3GvUM5cILRttpWtnAu8GNL9j11e4tbuGZmZjJ8ejnKYyBRb2ddGQ3rEFCq3QjMJw==}
/@typescript-eslint/typescript-estree@7.7.0(typescript@5.4.5):
resolution: {integrity: sha512-8p71HQPE6CbxIBy2kWHqM1KGrC07pk6RJn40n0DSc6bMOBBREZxSDJ+BmRzc8B5OdaMh1ty3mkuWRg4sCFiDQQ==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
typescript: '*'
@ -711,8 +719,8 @@ packages:
typescript:
optional: true
dependencies:
'@typescript-eslint/types': 7.6.0
'@typescript-eslint/visitor-keys': 7.6.0
'@typescript-eslint/types': 7.7.0
'@typescript-eslint/visitor-keys': 7.7.0
debug: 4.3.4
globby: 11.1.0
is-glob: 4.0.3
@ -724,8 +732,8 @@ packages:
- supports-color
dev: true
/@typescript-eslint/utils@7.6.0(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-x54gaSsRRI+Nwz59TXpCsr6harB98qjXYzsRxGqvA5Ue3kQH+FxS7FYU81g/omn22ML2pZJkisy6Q+ElK8pBCA==}
/@typescript-eslint/utils@7.7.0(eslint@8.57.0)(typescript@5.4.5):
resolution: {integrity: sha512-LKGAXMPQs8U/zMRFXDZOzmMKgFv3COlxUQ+2NMPhbqgVm6R1w+nU1i4836Pmxu9jZAuIeyySNrN/6Rc657ggig==}
engines: {node: ^18.18.0 || >=20.0.0}
peerDependencies:
eslint: ^8.56.0
@ -733,9 +741,9 @@ packages:
'@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0)
'@types/json-schema': 7.0.15
'@types/semver': 7.5.8
'@typescript-eslint/scope-manager': 7.6.0
'@typescript-eslint/types': 7.6.0
'@typescript-eslint/typescript-estree': 7.6.0(typescript@5.4.5)
'@typescript-eslint/scope-manager': 7.7.0
'@typescript-eslint/types': 7.7.0
'@typescript-eslint/typescript-estree': 7.7.0(typescript@5.4.5)
eslint: 8.57.0
semver: 7.6.0
transitivePeerDependencies:
@ -743,11 +751,11 @@ packages:
- typescript
dev: true
/@typescript-eslint/visitor-keys@7.6.0:
resolution: {integrity: sha512-4eLB7t+LlNUmXzfOu1VAIAdkjbu5xNSerURS9X/S5TUKWFRpXRQZbmtPqgKmYx8bj3J0irtQXSiWAOY82v+cgw==}
/@typescript-eslint/visitor-keys@7.7.0:
resolution: {integrity: sha512-h0WHOj8MhdhY8YWkzIF30R379y0NqyOHExI9N9KCzvmu05EgG4FumeYa3ccfKUSphyWkWQE1ybVrgz/Pbam6YA==}
engines: {node: ^18.18.0 || >=20.0.0}
dependencies:
'@typescript-eslint/types': 7.6.0
'@typescript-eslint/types': 7.7.0
eslint-visitor-keys: 3.4.3
dev: true
@ -1038,7 +1046,7 @@ packages:
eslint: 8.57.0
dev: true
/eslint-plugin-svelte@2.37.0(eslint@8.57.0)(svelte@5.0.0-next.102):
/eslint-plugin-svelte@2.37.0(eslint@8.57.0)(svelte@5.0.0-next.104):
resolution: {integrity: sha512-H/2Gz7agYHEMEEzRuLYuCmAIdjuBnbhFG9hOK0yCdSBvvJGJMkjo+lR6j67OIvLOavgp4L7zA5LnDKi8WqdPhQ==}
engines: {node: ^14.17.0 || >=16.0.0}
peerDependencies:
@ -1060,8 +1068,8 @@ packages:
postcss-safe-parser: 6.0.0(postcss@8.4.38)
postcss-selector-parser: 6.0.16
semver: 7.6.0
svelte: 5.0.0-next.102
svelte-eslint-parser: 0.34.1(svelte@5.0.0-next.102)
svelte: 5.0.0-next.104
svelte-eslint-parser: 0.34.1(svelte@5.0.0-next.104)
transitivePeerDependencies:
- supports-color
- ts-node
@ -1660,14 +1668,14 @@ packages:
engines: {node: '>= 0.8.0'}
dev: true
/prettier-plugin-svelte@3.2.3(prettier@3.2.5)(svelte@5.0.0-next.102):
/prettier-plugin-svelte@3.2.3(prettier@3.2.5)(svelte@5.0.0-next.104):
resolution: {integrity: sha512-wJq8RunyFlWco6U0WJV5wNCM7zpBFakS76UBSbmzMGpncpK98NZABaE+s7n8/APDCEVNHXC5Mpq+MLebQtsRlg==}
peerDependencies:
prettier: ^3.0.0
svelte: ^3.2.0 || ^4.0.0-next.0 || ^5.0.0-next.0
dependencies:
prettier: 3.2.5
svelte: 5.0.0-next.102
svelte: 5.0.0-next.104
dev: true
/prettier@3.2.5:
@ -1716,28 +1724,29 @@ packages:
glob: 7.2.3
dev: true
/rollup@4.14.2:
resolution: {integrity: sha512-WkeoTWvuBoFjFAhsEOHKRoZ3r9GfTyhh7Vff1zwebEFLEFjT1lG3784xEgKiTa7E+e70vsC81roVL2MP4tgEEQ==}
/rollup@4.14.3:
resolution: {integrity: sha512-ag5tTQKYsj1bhrFC9+OEWqb5O6VYgtQDO9hPDBMmIbePwhfSr+ExlcU741t8Dhw5DkPCQf6noz0jb36D6W9/hw==}
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
hasBin: true
dependencies:
'@types/estree': 1.0.5
optionalDependencies:
'@rollup/rollup-android-arm-eabi': 4.14.2
'@rollup/rollup-android-arm64': 4.14.2
'@rollup/rollup-darwin-arm64': 4.14.2
'@rollup/rollup-darwin-x64': 4.14.2
'@rollup/rollup-linux-arm-gnueabihf': 4.14.2
'@rollup/rollup-linux-arm64-gnu': 4.14.2
'@rollup/rollup-linux-arm64-musl': 4.14.2
'@rollup/rollup-linux-powerpc64le-gnu': 4.14.2
'@rollup/rollup-linux-riscv64-gnu': 4.14.2
'@rollup/rollup-linux-s390x-gnu': 4.14.2
'@rollup/rollup-linux-x64-gnu': 4.14.2
'@rollup/rollup-linux-x64-musl': 4.14.2
'@rollup/rollup-win32-arm64-msvc': 4.14.2
'@rollup/rollup-win32-ia32-msvc': 4.14.2
'@rollup/rollup-win32-x64-msvc': 4.14.2
'@rollup/rollup-android-arm-eabi': 4.14.3
'@rollup/rollup-android-arm64': 4.14.3
'@rollup/rollup-darwin-arm64': 4.14.3
'@rollup/rollup-darwin-x64': 4.14.3
'@rollup/rollup-linux-arm-gnueabihf': 4.14.3
'@rollup/rollup-linux-arm-musleabihf': 4.14.3
'@rollup/rollup-linux-arm64-gnu': 4.14.3
'@rollup/rollup-linux-arm64-musl': 4.14.3
'@rollup/rollup-linux-powerpc64le-gnu': 4.14.3
'@rollup/rollup-linux-riscv64-gnu': 4.14.3
'@rollup/rollup-linux-s390x-gnu': 4.14.3
'@rollup/rollup-linux-x64-gnu': 4.14.3
'@rollup/rollup-linux-x64-musl': 4.14.3
'@rollup/rollup-win32-arm64-msvc': 4.14.3
'@rollup/rollup-win32-ia32-msvc': 4.14.3
'@rollup/rollup-win32-x64-msvc': 4.14.3
fsevents: 2.3.3
dev: true
@ -1852,7 +1861,7 @@ packages:
has-flag: 4.0.0
dev: true
/svelte-check@3.6.9(postcss@8.4.38)(sass@1.75.0)(svelte@5.0.0-next.102):
/svelte-check@3.6.9(postcss@8.4.38)(sass@1.75.0)(svelte@5.0.0-next.104):
resolution: {integrity: sha512-hDQrk3L0osX07djQyMiXocKysTLfusqi8AriNcCiQxhQR49/LonYolcUGMtZ0fbUR8HTR198Prrgf52WWU9wEg==}
hasBin: true
peerDependencies:
@ -1864,8 +1873,8 @@ packages:
import-fresh: 3.3.0
picocolors: 1.0.0
sade: 1.8.1
svelte: 5.0.0-next.102
svelte-preprocess: 5.1.3(postcss@8.4.38)(sass@1.75.0)(svelte@5.0.0-next.102)(typescript@5.4.5)
svelte: 5.0.0-next.104
svelte-preprocess: 5.1.3(postcss@8.4.38)(sass@1.75.0)(svelte@5.0.0-next.104)(typescript@5.4.5)
typescript: 5.4.5
transitivePeerDependencies:
- '@babel/core'
@ -1879,7 +1888,7 @@ packages:
- sugarss
dev: true
/svelte-eslint-parser@0.34.1(svelte@5.0.0-next.102):
/svelte-eslint-parser@0.34.1(svelte@5.0.0-next.104):
resolution: {integrity: sha512-9+uLA1pqI9AZioKVGJzYYmlOZWxfoCXSbAM9iaNm7H01XlYlzRTtJfZgl9o3StQGN41PfGJIbkKkfk3e/pHFfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
peerDependencies:
@ -1893,19 +1902,19 @@ packages:
espree: 9.6.1
postcss: 8.4.38
postcss-scss: 4.0.9(postcss@8.4.38)
svelte: 5.0.0-next.102
svelte: 5.0.0-next.104
dev: true
/svelte-hmr@0.15.3(svelte@5.0.0-next.102):
/svelte-hmr@0.15.3(svelte@5.0.0-next.104):
resolution: {integrity: sha512-41snaPswvSf8TJUhlkoJBekRrABDXDMdpNpT2tfHIv4JuhgvHqLMhEPGtaQn0BmbNSTkuz2Ed20DF2eHw0SmBQ==}
engines: {node: ^12.20 || ^14.13.1 || >= 16}
peerDependencies:
svelte: ^3.19.0 || ^4.0.0
dependencies:
svelte: 5.0.0-next.102
svelte: 5.0.0-next.104
dev: true
/svelte-preprocess@5.1.3(postcss@8.4.38)(sass@1.75.0)(svelte@5.0.0-next.102)(typescript@5.4.5):
/svelte-preprocess@5.1.3(postcss@8.4.38)(sass@1.75.0)(svelte@5.0.0-next.104)(typescript@5.4.5):
resolution: {integrity: sha512-xxAkmxGHT+J/GourS5mVJeOXZzne1FR5ljeOUAMXUkfEhkLEllRreXpbl3dIYJlcJRfL1LO1uIAPpBpBfiqGPw==}
engines: {node: '>= 16.0.0', pnpm: ^8.0.0}
requiresBuild: true
@ -1950,12 +1959,12 @@ packages:
sass: 1.75.0
sorcery: 0.11.0
strip-indent: 3.0.0
svelte: 5.0.0-next.102
svelte: 5.0.0-next.104
typescript: 5.4.5
dev: true
/svelte@5.0.0-next.102:
resolution: {integrity: sha512-T1U+S5fws4WEaG37U2kCiYrl8II0o4U68BTvIq/9GGk3jwXQ5jFMiFoFZ+FXZ27o1enSOCHGTu7WJHjJ3sk5Ig==}
/svelte@5.0.0-next.104:
resolution: {integrity: sha512-DkyalSMjjFl+5PLl6TFPEtueMMPxUu7vtPUXrJCqRizE986zlLqcZdGGF4OCY/hnxfeeqbS1pD6nxVL8iuhniw==}
engines: {node: '>=18'}
dependencies:
'@ampproject/remapping': 2.3.0
@ -2067,7 +2076,7 @@ packages:
dependencies:
esbuild: 0.20.2
postcss: 8.4.38
rollup: 4.14.2
rollup: 4.14.3
sass: 1.75.0
optionalDependencies:
fsevents: 2.3.3

View File

@ -1,10 +1,15 @@
<script lang="ts">
let { replace_slot, accept, file, notExpand } = $props<{
let {
replace_slot,
accept,
file = $bindable(),
notExpand
}: {
replace_slot?: boolean;
accept?: string;
file?: File;
notExpand?: boolean;
}>();
} = $props();
let fileInput: HTMLInputElement;

View File

@ -83,6 +83,8 @@
<td>
{#if task.type == 1}
Image Run
{:else if task.type == 2}
Model training
{:else}
{task.type}
{/if}
@ -96,7 +98,7 @@
width="30px"
style="object-fit: contain;"
/>
{:else}
{:else if [2].includes(task.type)}{:else}
TODO Show more information {task.status}
{/if}
</td>
@ -115,7 +117,7 @@
{:else}
-
{/if}
{:else}
{:else if [2].includes(task.type)}{:else}
TODO Handle {task.type}
{/if}
</td>