"""Initial widths and spreadsheet-style resizing for submission tables.""" def column_width(column: str) -> int: if column.startswith(("Young's Modulus (", "Poisson's Ratio (", "Fluid Viscosity (", "Shear Modulus (", "Bulk Modulus (", "Yield Stress (", "Plasticity Viscosity (", "Friction Angle (", "Initial Velocity (")): return 220 widths = { '#': 76, 'ID': 132, 'Submission': 132, 'Status': 132, 'Submitted At': 232, 'Completed At': 232, 'Updated At': 232, 'Team': 280, 'Submitter': 280, 'Method / Model': 280, 'Owner': 240, 'Task': 180, 'Position': 100, 'Scenes': 176, 'Score': 144, 'Error': 320, 'Scene Errors': 320, 'Links': 120, } return widths.get(column, max(112, min(220, len(column) * 7 + 44))) table_resize_js = r"""() => { if (window.physTableResizeInstalled) return; window.physTableResizeInstalled = true; const widths = new WeakMap(); const minimumFor = name => name === '#' ? 76 : name === 'Team' || name === 'Submitter' || name === 'Method / Model' ? 130 : name === 'Submitted At' || name === 'Updated At' || name === 'Completed At' ? 175 : name === 'ID' || name === 'Submission' ? 120 : name === 'Error' || name === 'Scene Errors' ? 140 : 100; const initialWidthFor = name => /^(Young's Modulus|Poisson's Ratio|Fluid Viscosity|Shear Modulus|Bulk Modulus|Yield Stress|Plasticity Viscosity|Friction Angle|Initial Velocity) \(/.test(name) ? 220 : ({ '#': 76, ID: 132, Submission: 132, Status: 132, 'Submitted At': 232, 'Completed At': 232, 'Updated At': 232, Team: 280, Submitter: 280, 'Method / Model': 280, Owner: 240, Task: 180, Position: 100, Scenes: 176, Score: 144, Error: 320, 'Scene Errors': 320, Links: 120 })[name] || Math.max(112, Math.min(220, name.length * 7 + 44)); const formatMetric = value => { const number = '[+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(?:[eE][+-]?\\d+)?'; if (new RegExp(`^${number}$`).test(value) && Number.isFinite(Number(value))) { return Number(value).toFixed(3); } const pair = value.match(new RegExp(`^(${number})\\s*([+±])\\s*(${number})$`)); return pair && Number.isFinite(Number(pair[1])) && Number.isFinite(Number(pair[3])) ? `${Number(pair[1]).toFixed(3)}${pair[2]}${Number(pair[3]).toFixed(3)}` : value; }; const applyWidths = (table, headers, saved) => { let total = 0; headers.forEach((header, index) => { const width = saved.get(index); total += width; const property = `--cell-width-${index}`; if (table.style.getPropertyValue(property) !== `${width}px`) { table.style.setProperty(property, `${width}px`); } header.querySelector('.column-resize-handle')?.setAttribute('aria-valuenow', Math.round(width)); }); if (table.style.getPropertyValue('--table-content-width') !== `${total}px`) { table.style.setProperty('--table-content-width', `${total}px`); } }; const install = () => { document.querySelectorAll('.data-table').forEach(component => { if (component.classList.contains('history-table')) { const table = component.querySelector('table:not([aria-hidden="true"])'); if (table && component.getBoundingClientRect().height > 0) { component.classList.toggle('is-empty', !table.tBodies[0]?.rows.length); } } component.querySelectorAll('table:not([aria-hidden="true"])').forEach(table => { const headers = Array.from(table.querySelectorAll('thead th:not(.row-number)')); if (!headers.length) return; if (!widths.has(component)) widths.set(component, new Map()); const saved = widths.get(component); headers.forEach((header, index) => { const name = header.dataset.columnName || header.getAttribute('title') || header.textContent.trim(); header.dataset.columnName = name; const metric = name.match(/\b(PMF|PSNR|SSIM|LPIPS|FVD)\b/i)?.[1]?.toUpperCase(); const parameter = /^(N|NN|E|P|S) /.test(name) || Boolean(table.closest('.property-material-table') && !['Completed At', 'ID', 'Team', 'Submitter', 'Method / Model', 'Task', 'Status', 'Links', 'Scenes', 'Submission'].includes(name)); const kind = metric || parameter ? 'metric' : name === 'Links' ? 'link-action' : ['Team', 'Submitter', 'Method / Model'].includes(name) ? 'model' : ['Updated At', 'Submitted At', 'Completed At', 'Submission', 'ID', 'Owner', 'Task'].includes(name) ? 'metadata' : ''; header.dataset.columnKind = kind; if ((metric || parameter) && !header.querySelector('.metric-direction')) { const direction = ['LPIPS', 'FVD'].includes(metric) || parameter ? '↓' : '↑'; const badge = document.createElement('span'); badge.className = 'metric-direction'; badge.textContent = direction; header.querySelector('.header-content')?.appendChild(badge); header.title = `${name}: ${direction === '↑' ? 'higher' : 'lower'} is better`; } table.querySelectorAll(`tbody td[data-col="${index}"]`).forEach(cell => { cell.dataset.columnKind = kind; if (kind === 'metric' || name === 'Score') { const walker = document.createTreeWalker(cell, NodeFilter.SHOW_TEXT); let node; while ((node = walker.nextNode())) { const original = node.textContent.trim(); const formatted = formatMetric(original); if (formatted !== original) { cell.title = original; node.textContent = formatted; } } } if (name === '#' && component.classList.contains('leaderboard-table')) { cell.dataset.rank = cell.textContent.trim(); } }); if (!saved.has(index)) { saved.set(index, Math.max(minimumFor(name), initialWidthFor(name))); } if (header.querySelector('.column-resize-handle')) return; const setWidth = requested => { const width = Math.max(minimumFor(name), Math.round(requested)); if (width === saved.get(index)) return; saved.set(index, width); applyWidths(table, headers, saved); }; const handle = document.createElement('span'); handle.className = 'column-resize-handle resize-right'; handle.tabIndex = 0; handle.setAttribute('role', 'separator'); handle.setAttribute('aria-orientation', 'vertical'); handle.setAttribute('aria-label', `Resize ${name} column (right edge)`); handle.setAttribute('aria-valuemin', minimumFor(name)); handle.title = 'Drag to resize column; use arrow keys when focused'; handle.addEventListener('click', event => event.stopPropagation()); handle.addEventListener('pointerdown', event => { if (event.button !== 0) return; event.preventDefault(); event.stopPropagation(); const start = event.clientX; const size = saved.get(index); handle.setPointerCapture(event.pointerId); handle.classList.add('resizing'); handle.onpointermove = move => { move.preventDefault(); move.stopPropagation(); setWidth(size + move.clientX - start); }; const finish = () => { handle.onpointermove = null; handle.classList.remove('resizing'); if (handle.hasPointerCapture(event.pointerId)) handle.releasePointerCapture(event.pointerId); }; handle.onpointerup = finish; handle.onpointercancel = finish; handle.onlostpointercapture = finish; }); handle.addEventListener('keydown', event => { if (!['ArrowLeft', 'ArrowRight'].includes(event.key)) return; event.preventDefault(); event.stopPropagation(); setWidth(saved.get(index) + (event.key === 'ArrowRight' ? 16 : -16)); }); header.appendChild(handle); }); applyWidths(table, headers, saved); }); }); }; let scheduled = false; new MutationObserver(() => { if (scheduled) return; scheduled = true; requestAnimationFrame(() => { scheduled = false; install(); }); }).observe(document.body, { childList: true, characterData: true, subtree: true, attributes: true, attributeFilter: ['style'] }); install(); }"""