LFM2.5-VL-3B-WebGPU / src /document-parsing.js
shubeydoo's picture
Initial release
6c30253
Raw
History Blame Contribute Delete
2.32 kB
const COORDINATE = '(\\d+(?:\\.\\d+)?)';
const HEADER_PATTERN = new RegExp(`^image_index\\s*=\\s*(\\d+)\\s+([^\\[\\]\\n]+?)\\s+\\[\\s*${COORDINATE}\\s*,\\s*${COORDINATE}\\s*,\\s*${COORDINATE}\\s*,\\s*${COORDINATE}\\s*\\]\\s*$`);
function normalizeRegion(match, content, imageCount) {
if (!content) return null;
const [, rawImageIndex, rawLabel, ...rawCoordinates] = match;
const imageId = Number(rawImageIndex);
const label = rawLabel.trim();
let coordinates = rawCoordinates.map(Number);
if (imageId < 0 || imageId >= imageCount || !label) return null;
if (coordinates.every(value => value >= 0 && value <= 1)) {
coordinates = coordinates.map(value => Math.round(value * 1000));
} else if (coordinates.some(value => !Number.isInteger(value) || value < 0 || value > 1000)) {
return null;
}
const [xmin, ymin, xmax, ymax] = coordinates;
if (xmax <= xmin || ymax <= ymin) return null;
return { imageId, label, type: 'box', coordinates, content };
}
export function parseDocumentRegions(text, imageCount) {
if (!Number.isInteger(imageCount) || imageCount < 1 || typeof text !== 'string' || !text.trim()) return null;
const lines = text.trim().replace(/\r\n?/g, '\n').split('\n');
const regions = [];
let currentMatch = null;
let contentLines = [];
let sawHeader = false;
const finishCurrentRegion = () => {
if (!currentMatch) return;
const region = normalizeRegion(currentMatch, contentLines.join('\n').trim(), imageCount);
if (region) regions.push(region);
};
for (const line of lines) {
const match = HEADER_PATTERN.exec(line);
if (match) {
if (currentMatch) {
finishCurrentRegion();
} else if (!sawHeader && contentLines.some(value => value.trim())) {
return null;
}
sawHeader = true;
currentMatch = match;
contentLines = [];
} else if (/^\s*image_index\b/.test(line)) {
finishCurrentRegion();
sawHeader = true;
currentMatch = null;
contentLines = [];
} else if (currentMatch || !sawHeader) {
contentLines.push(line);
} else {
// Ignore content belonging to an incomplete or malformed region while
// retaining complete regions that were already parsed.
}
}
finishCurrentRegion();
return regions.length ? regions : null;
}