diff --git a/frontend/debug.mjs b/frontend/debug.mjs new file mode 100644 index 0000000..fdedf40 --- /dev/null +++ b/frontend/debug.mjs @@ -0,0 +1,20 @@ +import { keySheet } from './src/lib/core/mask.js'; +import { sampleWidthsPx } from './src/lib/core/measure.js'; +const W = 200, H = 150; +function slabPhoto(slabW, slabH, ox, oy) { + const data = new Uint8ClampedArray(W * H * 4); + for (let y = 0; y < H; y++) + for (let x = 0; x < W; x++) { + const i = (y * W + x) * 4; + const inSlab = x >= ox && x < ox + slabW && y >= oy && y < oy + slabH; + if (inSlab) { data[i] = 139; data[i + 1] = 90; data[i + 2] = 43; } + else { data[i] = 34; data[i + 1] = 139; data[i + 2] = 34; } + data[i + 3] = 255; + } + return data; +} +const d = slabPhoto(10, 10, 0, 0); +const m = keySheet(d, { sheet: 'green', sensitivity: 50 }); +let kept = 0; +for (let i = 0; i < m.length; i++) kept += m[i]; +console.log('kept:', kept, 'of', m.length); diff --git a/frontend/debug10.mjs b/frontend/debug10.mjs new file mode 100644 index 0000000..459be96 --- /dev/null +++ b/frontend/debug10.mjs @@ -0,0 +1,17 @@ +import { sampleWidthsPx } from './src/lib/core/measure.js'; +const W = 200, H = 150; +const mask = new Uint8Array(W * H); +// slab 336 x 192 px at (0,0) — extends beyond photo bounds (200x150) +for (let y = 0; y < H; y++) + for (let x = 0; x < W; x++) + mask[y * W + x] = (x < 336 && y < 192) ? 1 : 0; +const axis = { origin: {x:0, y:0}, dir: {x:1, y:0}, lengthPx: 336 }; +const w = sampleWidthsPx(mask, W, H, axis, 160, 6); +console.log('widths:', w); +// sample points at t=0, 96, 192, 288 px +// perpendicular dir: (0,1) — scan down +// at x=0: y from 0..149 all in slab (y<192) → width 150 (clamped by photo) +// at x=96: same → 150 +// at x=192: same → 150 +// at x=288: x=288 > 200 (photo width) → out of bounds → 0? or skipped? +console.log('expected: [150, 150, 150] or [150, 150, 150, 0]'); diff --git a/frontend/debug11.mjs b/frontend/debug11.mjs new file mode 100644 index 0000000..86810c8 --- /dev/null +++ b/frontend/debug11.mjs @@ -0,0 +1,11 @@ +import { sampleWidthsPx } from './src/lib/core/measure.js'; +const W = 400, H = 250; +const mask = new Uint8Array(W * H); +for (let y = 0; y < H; y++) + for (let x = 0; x < W; x++) + mask[y * W + x] = 1; // whole photo is slab +const axis = { origin: {x:0, y:0}, dir: {x:1, y:0}, lengthPx: 336 }; +const w = sampleWidthsPx(mask, W, H, axis, 160, 6); +console.log('widths (full photo):', w); +console.log('expected: [250, 250, 250] (t=0,96,192; t=288>336? no, 288<336 → also 250)'); +console.log('samples at t=0,96,192,288 → 4 samples, each width=250'); diff --git a/frontend/debug2.mjs b/frontend/debug2.mjs new file mode 100644 index 0000000..ba62793 --- /dev/null +++ b/frontend/debug2.mjs @@ -0,0 +1,10 @@ +import { keySheet } from './src/lib/core/mask.js'; +const data = new Uint8ClampedArray(10 * 4); +// slab brown +data[0] = 139; data[1] = 90; data[2] = 43; data[3] = 255; +// sheet green +data[4] = 34; data[5] = 139; data[6] = 34; data[7] = 255; +data[8] = 34; data[9] = 139; data[10] = 34; data[11] = 255; +data[12] = 34; data[13] = 139; data[14] = 34; data[15] = 255; +const m = keySheet(data, { sheet: 'green', sensitivity: 50 }); +console.log('mask for 4 pixels (1 slab + 3 sheet):', Array.from(m)); diff --git a/frontend/debug3.mjs b/frontend/debug3.mjs new file mode 100644 index 0000000..482c532 --- /dev/null +++ b/frontend/debug3.mjs @@ -0,0 +1,8 @@ +import { keySheet } from './src/lib/core/mask.js'; +const data = new Uint8ClampedArray(4 * 4); +data[0]=139; data[1]=90; data[2]=43; data[3]=255; +data[4]=34; data[5]=139; data[6]=34; data[7]=255; +data[8]=34; data[9]=139; data[10]=34; data[11]=255; +data[12]=34; data[13]=139; data[14]=34; data[15]=255; +const m = keySheet(data, { sheet:'green', sensitivity:50 }); +console.log('mask for 4 px (1 slab, 3 sheet):', Array.from(m)); diff --git a/frontend/debug4.mjs b/frontend/debug4.mjs new file mode 100644 index 0000000..63343cb --- /dev/null +++ b/frontend/debug4.mjs @@ -0,0 +1,29 @@ +const data = new Uint8ClampedArray(4 * 4); +data[0]=139; data[1]=90; data[2]=43; data[3]=255; +data[4]=34; data[5]=139; data[6]=34; data[7]=255; +data[8]=34; data[9]=139; data[10]=34; data[11]=255; +data[12]=34; data[13]=139; data[14]=34; data[15]=255; + +const SHEET_GREEN = { r: 0, g: 255, b: 0 }; +function greenDistance(r, g, b) { + const dr = r - SHEET_GREEN.r; + const dg = g - SHEET_GREEN.g; + const db = b - SHEET_GREEN.b; + return Math.sqrt(dr * dr + dg * dg + db * db); +} +function greenThreshold(s) { return 150 - s; } +function blackCutoff(s) { return 40 + (s / 100) * 100; } +const BLACK_SAT_CAP = 120; + +const sensitivity = 50; +const n = data.length / 4; +const mask = new Uint8Array(n); +for (let i = 0; i < n; i++) { + const j = i * 4; + const r = data[j], g = data[j + 1], b = data[j + 2]; + const d = greenDistance(r, g, b); + const t = greenThreshold(sensitivity); + mask[i] = d > t ? 1 : 0; + console.log(`px ${i}: r=${r} g=${g} b=${b} dist=${d.toFixed(1)} thresh=${t} kept=${mask[i]}`); +} +console.log('mask:', Array.from(mask)); diff --git a/frontend/debug5.mjs b/frontend/debug5.mjs new file mode 100644 index 0000000..a8bf7c6 --- /dev/null +++ b/frontend/debug5.mjs @@ -0,0 +1,20 @@ +import { keySheet } from './src/lib/core/mask.js'; +import { readFileSync } from 'fs'; +const fileSrc = readFileSync('./src/lib/core/mask.js', 'utf8'); +const match = fileSrc.match(/const SHEET_GREEN = \{([^}]*)\}/); +console.log('SHEET_GREEN in file:', match ? match[0] : 'NOT FOUND'); +console.log('keySheet source:', keySheet.toString()); +const W = 20, H = 10; +const data = new Uint8ClampedArray(W * H * 4); +for (let y = 0; y < H; y++) + for (let x = 0; x < W; x++) { + const i = (y * W + x) * 4; + const inSlab = x >= 5 && x < 15 && y >= 2 && y < 8; + if (inSlab) { data[i]=139; data[i+1]=90; data[i+2]=43; } + else { data[i]=34; data[i+1]=139; data[i+2]=34; } + data[i+3] = 255; + } +const maskResult = keySheet(data, { sheet: 'green', sensitivity: 50 }); +console.log('row 5:', Array.from(maskResult.slice(5*W, 6*W))); +let kept = 0; for (let i = 0; i < maskResult.length; i++) kept += maskResult[i]; +console.log('kept:', kept, 'expected: 60'); diff --git a/frontend/debug6.mjs b/frontend/debug6.mjs new file mode 100644 index 0000000..d5d8f5d --- /dev/null +++ b/frontend/debug6.mjs @@ -0,0 +1,10 @@ +const SHEET_GREEN = { r: 0, g: 255, b: 0 }; +function greenDistance(r, g, b) { + const dr = r - SHEET_GREEN.r; + const dg = g - SHEET_GREEN.g; + const db = b - SHEET_GREEN.b; + return Math.sqrt(dr * dr + dg * dg + db * db); +} +console.log('sheet green (34,139,34):', greenDistance(34, 139, 34).toFixed(1)); +console.log('brown (139,90,43):', greenDistance(139, 90, 43).toFixed(1)); +console.log('threshold at s=50:', 150 - 50); diff --git a/frontend/debug7.mjs b/frontend/debug7.mjs new file mode 100644 index 0000000..0cee08b --- /dev/null +++ b/frontend/debug7.mjs @@ -0,0 +1,13 @@ +import { keySheet } from './src/lib/core/mask.js'; +const W = 20, H = 10; +const data = new Uint8ClampedArray(W * H * 4); +for (let y = 0; y < H; y++) + for (let x = 0; x < W; x++) { + const i = (y * W + x) * 4; + const inSlab = x >= 5 && x < 15 && y >= 2 && y < 8; + if (inSlab) { data[i]=139; data[i+1]=90; data[i+2]=43; } + else { data[i]=34; data[i+1]=139; data[i+2]=34; } + data[i+3] = 255; + } +const m = keySheet(data, { sheet: 'green', sensitivity: 50 }); +console.log('row 5:', Array.from(m.slice(5*W, 6*W))); diff --git a/frontend/debug8.mjs b/frontend/debug8.mjs new file mode 100644 index 0000000..2fa613b --- /dev/null +++ b/frontend/debug8.mjs @@ -0,0 +1,23 @@ +import { keySheet } from './src/lib/core/mask.js'; +const W = 20, H = 10; +const data = new Uint8ClampedArray(W * H * 4); +for (let y = 0; y < H; y++) + for (let x = 0; x < W; x++) { + const i = (y * W + x) * 4; + const inSlab = x >= 5 && x < 15 && y >= 2 && y < 8; + if (inSlab) { data[i]=139; data[i+1]=90; data[i+2]=43; } + else { data[i]=34; data[i+1]=139; data[i+2]=34; } + data[i+3] = 255; + } +const m = keySheet(data, { sheet: 'green', sensitivity: 50 }); +console.log('row 5:', Array.from(m.slice(5*W, 6*W))); +console.log('row 5 length:', m.slice(5*W, 6*W).length); +const arr = m.slice(5*W, 6*W); +let all1 = true; +for (let i = 0; i < W; i++) if (arr[i] !== 1) { all1 = false; console.log('x=', i, 'val=', arr[i]); } +console.log('all 1s?', all1); +// Check a specific pixel +const px5 = m[5*W+10]; +console.log('px at (10,5):', px5); +const px0 = m[0]; +console.log('px at (0,0):', px0); diff --git a/frontend/debug9.mjs b/frontend/debug9.mjs new file mode 100644 index 0000000..0abf232 --- /dev/null +++ b/frontend/debug9.mjs @@ -0,0 +1,18 @@ +import { keySheet } from './src/lib/core/mask.js'; +const W = 20, H = 10; +const data = new Uint8ClampedArray(W * H * 4); +for (let y = 0; y < H; y++) + for (let x = 0; x < W; x++) { + const i = (y * W + x) * 4; + const inSlab = x >= 5 && x < 15 && y >= 2 && y < 8; + if (inSlab) { data[i]=139; data[i+1]=90; data[i+2]=43; } + else { data[i]=34; data[i+1]=139; data[i+2]=34; } + data[i+3] = 255; + } +console.log('px (0,0) =', [data[0], data[1], data[2]]); +console.log('px (10,5) =', [data[(5*W+10)*4], data[(5*W+10)*4+1], data[(5*W+10)*4+2]]); +const m = keySheet(data, { sheet: 'green', sensitivity: 50 }); +console.log('mask (0,0) =', m[0]); +console.log('mask (10,5) =', m[5*W+10]); +let kept = 0; for (let i = 0; i < m.length; i++) kept += m[i]; +console.log('kept:', kept, 'of', m.length); diff --git a/frontend/frontend/src/lib/core/inventory.js b/frontend/frontend/src/lib/core/inventory.js new file mode 100644 index 0000000..e69de29 diff --git a/frontend/package-lock.json b/frontend/package-lock.json index db2db6f..84ff9d6 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -15,11 +15,12 @@ "@sveltejs/adapter-node": "^5.2.0", "@sveltejs/kit": "^2.21.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", + "playwright": "^1.63.0", "svelte": "^5.0.0", "svelte-check": "^4.1.0", "typescript": "^5.8.0", "vite": "^6.3.0", - "vitest": "^3.0.0" + "vitest": "^3.2.7" } }, "node_modules/@esbuild/aix-ppc64": { diff --git a/frontend/package.json b/frontend/package.json index 223b98f..9c60bad 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,11 +16,12 @@ "@sveltejs/adapter-node": "^5.2.0", "@sveltejs/kit": "^2.21.0", "@sveltejs/vite-plugin-svelte": "^5.0.0", + "playwright": "^1.63.0", "svelte": "^5.0.0", "svelte-check": "^4.1.0", "typescript": "^5.8.0", "vite": "^6.3.0", - "vitest": "^3.0.0" + "vitest": "^3.2.7" }, "dependencies": { "idb-keyval": "^6.2.1" diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..c13acf1 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "SlabUploader", + "lockfileVersion": 3, + "requires": true, + "packages": {} +}