parts: calculateExistingParts()

in web/src/shared/components/annotator/components/table-annotation/helpers.tsx [469:511]


                parts: calculateExistingParts(
                    annotation.table.rows,
                    annotation.bound.height,
                    gutterParams.visibleGutterWidth
                )
            };
        }
    }
    return gutters;
};

const getGutterIdxByRelativeIdx = (
    gutters: TableGutterMap,
    idx: number,
    type: GutterType
): number => {
    for (let gutter of Object.values(gutters)) {
        if (gutter.type !== type) continue;
        if (idx === 0) return gutter.id;
        idx--;
    }
    return -1;
};

const processCellSpan = (
    cell: Annotation,
    selector: 'row' | 'col',
    gutters: TableGutterMap,
    newGutters: TableGutterMap
) => {
    const cellSpan: 'colspan' | 'rowspan' = `${selector}span`;
    const reverseSelector: 'col' | 'row' = selector === 'row' ? 'col' : 'row';
    const reverseCellSpan: 'colspan' | 'rowspan' = `${reverseSelector}span`;
    const gutterType: GutterType = selector === 'row' ? 'horizontal' : 'vertical';
    if (cell.data[cellSpan] > 1) {
        const affectedGutterIdx = getGutterIdxByRelativeIdx(
            gutters,
            cell.data[selector],
            gutterType
        );
        if (affectedGutterIdx < 0) return;
        for (let i = 0; i < cell.data[cellSpan] - 1; ++i) {
            if (cell.data[reverseCellSpan] >= 2) {