splitExons()

in client/client/app/shared/components/ngbVariantDetails/ngbVariantVisualizer/ngbVariantVisualizer.service.js [779:882]


    splitExons(exons, breakpointPosition, anotherBreakpoints, takeLeftPart = true, revert = false) {
        let leftBorder = 0;
        let rightBorder = 0;
        for (let i = 0; i < exons.length; i++) {
            if (exons[i].relativePosition.end > rightBorder) {
                rightBorder = exons[i].relativePosition.end;
            }
        }
        for (let i = 0; i < anotherBreakpoints.length; i++) {
            if (anotherBreakpoints[i] === breakpointPosition)
                continue;
            if (anotherBreakpoints[i] > leftBorder && anotherBreakpoints[i] < breakpointPosition) {
                leftBorder = anotherBreakpoints[i];
            }
            if (anotherBreakpoints[i] < rightBorder && anotherBreakpoints[i] > breakpointPosition) {
                rightBorder = anotherBreakpoints[i];
            }
        }
        let result = [];
        for (let i = 0; i < exons.length; i++) {
            if (takeLeftPart) {
                if (exons[i].relativePosition.start < breakpointPosition && exons[i].relativePosition.end >= leftBorder) {
                    const exon = Object.assign({}, exons[i]);
                    exon.relativePosition = {
                        start: exons[i].relativePosition.start,
                        end: exons[i].relativePosition.end
                    };
                    exon.relativePosition.start = Math.max(leftBorder, exon.relativePosition.start);
                    exon.relativePosition.end = Math.min(breakpointPosition, exon.relativePosition.end);
                    if (exon.relativePosition.end === breakpointPosition) {
                        exon.isBreakpoint = true;
                        exon.breakpointPosition = revert ? 'start' : 'end';
                    }
                    exon.domains = [];
                    for (let j = 0; j < exons[i].domains.length; j++) {
                        const domain = Object.assign({}, exons[i].domains[j]);
                        domain.range = {
                            start: exons[i].domains[j].range.start,
                            end: exons[i].domains[j].range.end
                        };
                        exon.domains.push(domain);
                    }
                    result.push(exon);
                }
            }
            else {
                if (exons[i].relativePosition.end > breakpointPosition && exons[i].relativePosition.start <= rightBorder) {
                    const exon = Object.assign({}, exons[i]);
                    exon.relativePosition = {
                        start: exons[i].relativePosition.start,
                        end: exons[i].relativePosition.end
                    };
                    exon.relativePosition.start = Math.max(breakpointPosition, exon.relativePosition.start);
                    exon.relativePosition.end = Math.min(rightBorder, exon.relativePosition.end);
                    if (exon.relativePosition.start === breakpointPosition) {
                        exon.isBreakpoint = true;
                        exon.breakpointPosition = revert ? 'end' : 'start';
                    }
                    exon.domains = [];
                    for (let j = 0; j < exons[i].domains.length; j++) {
                        const domain = Object.assign({}, exons[i].domains[j]);
                        domain.range = {
                            start: exons[i].domains[j].range.start,
                            end: exons[i].domains[j].range.end
                        };
                        exon.domains.push(domain);
                    }
                    result.push(exon);
                }
            }
        }
        if (revert) {
            const revertedResult = [];
            for (let i = 0; i < result.length; i++) {
                const exon = result[result.length - 1 - i];
                if (exon.strand !== null)
                    exon.strand = !exon.strand;
                revertedResult.push(exon);
            }
            result = revertedResult;
        }
        let prevPosition = 0;
        for (let i = 0; i < result.length; i++) {
            const exon = result[i];
            const exonLength = exon.relativePosition.end - exon.relativePosition.start;
            for (let j = 0; j < exon.domains.length; j++) {
                const domain = exon.domains[j];
                domain.range.start -= (exon.relativePosition.start - prevPosition);
                domain.range.end -= (exon.relativePosition.start - prevPosition);
            }
            exon.relativePosition.start = prevPosition;
            exon.relativePosition.end = prevPosition + exonLength;
            if (revert) {
                for (let j = 0; j < exon.domains.length; j++) {
                    const domain = exon.domains[j];
                    const domainLength = domain.range.end - domain.range.start;
                    domain.range.end = exon.relativePosition.end - (domain.range.start - exon.relativePosition.start);
                    domain.range.start = domain.range.end - domainLength;
                }
            }
            prevPosition += exonLength + 1;
        }
        return result;
    }