<commit_before>

function sortIx( a, b ) { return b.parameter - a.parameter; }

function splitPath( _ixs, other ) {
    other = other || false;
    var i, j, k, l, len, ixs, ix, path, crv, vals;
    var ixPoint, nuSeg;
    var paths = {}, lastPathId = null;
    for (i = 0, l = _ixs.length; i < l; i++) {
        ix = ( other )? _ixs[i].getIntersection() : _ixs[i];
        if( !paths[ix.path.id] ){
            paths[ix.path.id] = ix.path;
        }
        if( !ix.curve._ixParams ){ix.curve._ixParams = []; }
        ix.curve._ixParams.push( { parameter: ix.parameter, pair: ix.getIntersection() } );
    }
    for (k in paths) {
        if( !paths.hasOwnProperty( k ) ){ continue; }
        path = paths[k];
        var lastNode = path.lastSegment, firstNode = path.firstSegment;
        var nextNode = null, left = null, right = null, parts = null, isLinear;
        var handleIn, handleOut;
        while( nextNode !== firstNode){
            nextNode = ( nextNode )? nextNode.previous: lastNode;
            if( nextNode.curve._ixParams ){
                ixs = nextNode.curve._ixParams;
                ixs.sort( sortIx );
                crv = nextNode.curve;
                isLinear = crv.isLinear();
                crv = vals = null;
                for (i = 0, l = ixs.length; i < l; i++) {
                    ix = ixs[i];
                    crv = nextNode.curve;
                    if( !vals ) vals = crv.getValues();
                    if( ix.parameter === 0.0 || ix.parameter === 1.0 ){
                        // Intersection is on an existing node
                        // no need to create a new segment,
                        // we just link the corresponding intersections together
                        nuSeg = ( ix.parameter === 0.0 )? crv.segment1 : crv.segment2;
                        nuSeg._ixPair = ix.pair;
                        nuSeg._ixPair._segment = nuSeg;
                    } else {
                        parts = Curve.subdivide( vals, ix.parameter );
                        left = parts[0];
                        right = parts[1];
                        handleIn = handleOut = null;
                        ixPoint = new Point( right[0], right[1] );
                        if( !isLinear ){
                            crv.segment1.handleOut = new Point( left[2] - left[0], left[3] - left[1] );
                            crv.segment2.handleIn = new Point( right[4] - right[6], right[5] - right[7] );
                            handleIn = new Point( left[4] - ixPoint.x, left[5] - ixPoint.y );
                            handleOut = new Point( right[2] - ixPoint.x, right[3] - ixPoint.y );
                        }
                        nuSeg = new Segment( ixPoint, handleIn, handleOut );
                        nuSeg._ixPair = ix.pair;
                        nuSeg._ixPair._segment = nuSeg;
                        path.insert( nextNode.index + 1,  nuSeg );
                    }
                    for (j = i + 1; j < l; j++) {
                        ixs[j].parameter = ixs[j].parameter / ix.parameter;
                    }
                    vals = left;
                }
            }
        }
    }
}

/**
 * To deal with a HTML canvas requirement where CompoundPaths' child contours
 * has to be of different winding direction for correctly filling holes.
 * But if some individual countours are disjoint, i.e. islands, we have to
 * reorient them so that
 *   the holes have opposit winding direction ( already handled by paperjs )
 *   islands has to have same winding direction ( as the first child of the path )
 *
 * Does NOT handle selfIntersecting CompoundPaths.
 *
 * @param  {CompoundPath} path - Input CompoundPath, Note: This path could be modified if need be.
 * @return {boolean}      the winding direction of the base contour( true if clockwise )
 */
 function reorientCompoundPath( path ){
    if( !(path instanceof CompoundPath) ){
        path.closed = true;
        return path.clockwise;
    }
    var children = path.children, len = children.length, baseWinding;
    var bounds = new Array( len );
    var tmparray = new Array( len );
    baseWinding = children[0].clockwise;
    // Omit the first path
    for (i = 0; i < len; i++) {
        children[i].closed = true;
        bounds[i] = children[i].bounds;
        tmparray[i] = 0;
    }
    for (i = 0; i < len; i++) {
        var p1 = children[i];
        for (j = 0; j < len; j++) {
            var p2 = children[j];
            if( i !== j && bounds[i].contains( bounds[j] ) ){
                tmparray[j]++;
            }
        }
    }
    for (i = 1; i < len; i++) {
        if ( tmparray[i] % 2 === 0 ) {
            children[i].clockwise = baseWinding;
        }
    }
    return baseWinding;
}

function reversePath( path ){
    if( path instanceof CompoundPath ){
        var children = path.children, i, len;
        for (i = 0, len = children.length; i < len; i++) {
            children[i].reverse();
        }
    } else {
        path.reverse();
    }
}

function computeBoolean( path1, path2, operator ){
    // We do not modify the operands themselves
    // The result might not belong to the same type
    // i.e. subtraction< A:Path, B:Path >:CompoundPath etc.
    var _path1 = path1.clone();
    var _path2 = path2.clone();
    // Do operator specific calculations before we begin
    if( operator.name === "subtraction" ) {
        reversePath( _path2 );
    }
    var path1Clockwise = reorientCompoundPath( _path1 );
    var path2Clockwise = reorientCompoundPath( _path2 );

    var ixs = _path1.getIntersections( _path2 );
    var path1Id = _path1.id;
    var path2Id = _path2.id;
    splitPath( ixs );
    splitPath( ixs, true );

    var i, j, len, path, crv;
    var paths;
    if( _path1 instanceof CompoundPath ){
        paths = new Array().concat( _path1.children );
    } else {
        paths = [ _path1 ];
    }
    if( _path2 instanceof CompoundPath ){
        paths = paths.concat( _path2.children );
    } else {
        paths.push( _path2 );
    }

    _path2.selected = true;
    // step 1: discard invalid links according to the boolean operator
    var lastNode, firstNode, nextNode, midPoint, insidePath1, insidePath2;
    var thisId, thisWinding, contains;
    for (i = 0, len = paths.length; i < len; i++) {
        insidePath1 = insidePath2 = false;
        path = paths[i];
        thisId = ( path.parent instanceof CompoundPath )? path.parent.id : path.id;
        thisWinding = path.clockwise;
        lastNode = path.lastSegment;
        firstNode = path.firstSegment;
        nextNode = null;
        while( nextNode !== firstNode){
            nextNode = ( nextNode )? nextNode.previous: lastNode;
            crv = nextNode.curve;
            midPoint = crv.getPoint( 0.5 );
            if( thisId !== path1Id ){
                contains = _path1.contains( midPoint );
                insidePath1 = (thisWinding === path1Clockwise)? contains :
                contains && !testOnCurve( _path1, midPoint );
            }
            if( thisId !== path2Id ){
                contains = _path2.contains( midPoint );
                insidePath2 = (thisWinding === path2Clockwise)? contains :
                contains && !testOnCurve( _path2, midPoint );
            }
            if( !operator( thisId === path1Id, insidePath1, insidePath2 ) ){
                crv._INVALID = true;
                // markPoint( midPoint, '+' );
            }
        }
    }

    // Final step: Retrieve the resulting paths from the graph
    var boolResult = new CompoundPath();
    var node, nuNode, nuPath, nodeList = [], handle;
    for (i = 0, len = paths.length; i < len; i++) {
        nodeList = nodeList.concat( paths[i].segments );
    }
    for (i = 0, len = nodeList.length; i < len; i++) {
        node = nodeList[i];
        if( node.curve._INVALID || node._visited ){ continue; }
        path = node.path;
        thisId = ( path.parent instanceof CompoundPath )? path.parent.id : path.id;
        thisWinding = path.clockwise;
        nuPath = new Path();
        firstNode = null;
        firstNode_ix = null;
        if( node.previous.curve._INVALID ) {
            node.handleIn = ( node._ixPair )?
            node._ixPair.getIntersection()._segment.handleIn : [ 0, 0 ];
        }<commit_msg>Resolved an issue where overlapping lines were falsely marked invalid<commit_after>

function sortIx( a, b ) { return b.parameter - a.parameter; }

function splitPath( _ixs, other ) {
    other = other || false;
    var i, j, k, l, len, ixs, ix, path, crv, vals;
    var ixPoint, nuSeg;
    var paths = {}, lastPathId = null;
    for (i = 0, l = _ixs.length; i < l; i++) {
        ix = ( other )? _ixs[i].getIntersection() : _ixs[i];
        if( !paths[ix.path.id] ){
            paths[ix.path.id] = ix.path;
        }
        if( !ix.curve._ixParams ){ix.curve._ixParams = []; }
        ix.curve._ixParams.push( { parameter: ix.parameter, pair: ix.getIntersection() } );
    }
    for (k in paths) {
        if( !paths.hasOwnProperty( k ) ){ continue; }
        path = paths[k];
        var lastNode = path.lastSegment, firstNode = path.firstSegment;
        var nextNode = null, left = null, right = null, parts = null, isLinear;
        var handleIn, handleOut;
        while( nextNode !== firstNode){
            nextNode = ( nextNode )? nextNode.previous: lastNode;
            if( nextNode.curve._ixParams ){
                ixs = nextNode.curve._ixParams;
                ixs.sort( sortIx );
                crv = nextNode.curve;
                isLinear = crv.isLinear();
                crv = vals = null;
                for (i = 0, l = ixs.length; i < l; i++) {
                    ix = ixs[i];
                    crv = nextNode.curve;
                    if( !vals ) vals = crv.getValues();
                    if( ix.parameter === 0.0 || ix.parameter === 1.0 ){
                        // Intersection is on an existing node
                        // no need to create a new segment,
                        // we just link the corresponding intersections together
                        nuSeg = ( ix.parameter === 0.0 )? crv.segment1 : crv.segment2;
                        nuSeg._ixPair = ix.pair;
                        nuSeg._ixPair._segment = nuSeg;
                    } else {
                        parts = Curve.subdivide( vals, ix.parameter );
                        left = parts[0];
                        right = parts[1];
                        handleIn = handleOut = null;
                        ixPoint = new Point( right[0], right[1] );
                        if( !isLinear ){
                            crv.segment1.handleOut = new Point( left[2] - left[0], left[3] - left[1] );
                            crv.segment2.handleIn = new Point( right[4] - right[6], right[5] - right[7] );
                            handleIn = new Point( left[4] - ixPoint.x, left[5] - ixPoint.y );
                            handleOut = new Point( right[2] - ixPoint.x, right[3] - ixPoint.y );
                        }
                        nuSeg = new Segment( ixPoint, handleIn, handleOut );
                        nuSeg._ixPair = ix.pair;
                        nuSeg._ixPair._segment = nuSeg;
                        path.insert( nextNode.index + 1,  nuSeg );
                    }
                    for (j = i + 1; j < l; j++) {
                        ixs[j].parameter = ixs[j].parameter / ix.parameter;
                    }
                    vals = left;
                }
            }
        }
    }
}

/**
 * To deal with a HTML canvas requirement where CompoundPaths' child contours
 * has to be of different winding direction for correctly filling holes.
 * But if some individual countours are disjoint, i.e. islands, we have to
 * reorient them so that
 *   the holes have opposit winding direction ( already handled by paperjs )
 *   islands has to have same winding direction ( as the first child of the path )
 *
 * Does NOT handle selfIntersecting CompoundPaths.
 *
 * @param  {CompoundPath} path - Input CompoundPath, Note: This path could be modified if need be.
 * @return {boolean}      the winding direction of the base contour( true if clockwise )
 */
 function reorientCompoundPath( path ){
    if( !(path instanceof CompoundPath) ){
        path.closed = true;
        return path.clockwise;
    }
    var children = path.children, len = children.length, baseWinding;
    var bounds = new Array( len );
    var tmparray = new Array( len );
    baseWinding = children[0].clockwise;
    // Omit the first path
    for (i = 0; i < len; i++) {
        children[i].closed = true;
        bounds[i] = children[i].bounds;
        tmparray[i] = 0;
    }
    for (i = 0; i < len; i++) {
        var p1 = children[i];
        for (j = 0; j < len; j++) {
            var p2 = children[j];
            if( i !== j && bounds[i].contains( bounds[j] ) ){
                tmparray[j]++;
            }
        }
    }
    for (i = 1; i < len; i++) {
        if ( tmparray[i] % 2 === 0 ) {
            children[i].clockwise = baseWinding;
        }
    }
    return baseWinding;
}

function reversePath( path ){
    if( path instanceof CompoundPath ){
        var children = path.children, i, len;
        for (i = 0, len = children.length; i < len; i++) {
            children[i].reverse();
        }
    } else {
        path.reverse();
    }
}

function computeBoolean( path1, path2, operator ){
    // We do not modify the operands themselves
    // The result might not belong to the same type
    // i.e. subtraction< A:Path, B:Path >:CompoundPath etc.
    var _path1 = path1.clone();
    var _path2 = path2.clone();
    // Do operator specific calculations before we begin
    if( operator.name === "subtraction" ) {
        reversePath( _path2 );
    }
    var path1Clockwise = reorientCompoundPath( _path1 );
    var path2Clockwise = reorientCompoundPath( _path2 );

    var ixs = _path1.getIntersections( _path2 );
    var path1Id = _path1.id;
    var path2Id = _path2.id;
    splitPath( ixs );
    splitPath( ixs, true );

    var i, j, len, path, crv;
    var paths;
    if( _path1 instanceof CompoundPath ){
        paths = new Array().concat( _path1.children );
    } else {
        paths = [ _path1 ];
    }
    if( _path2 instanceof CompoundPath ){
        paths = paths.concat( _path2.children );
    } else {
        paths.push( _path2 );
    }

    // step 1: discard invalid links according to the boolean operator
    var lastNode, firstNode, nextNode, midPoint, insidePath1, insidePath2;
    var thisId, thisWinding, contains, subtractionOp = (operator.name === 'subtraction');
    for (i = 0, len = paths.length; i < len; i++) {
        insidePath1 = insidePath2 = false;
        path = paths[i];
        thisId = ( path.parent instanceof CompoundPath )? path.parent.id : path.id;
        thisWinding = path.clockwise;
        lastNode = path.lastSegment;
        firstNode = path.firstSegment;
        nextNode = null;
        while( nextNode !== firstNode){
            nextNode = ( nextNode )? nextNode.previous: lastNode;
            crv = nextNode.curve;
            midPoint = crv.getPoint( 0.5 );
            if( thisId !== path1Id ){
                contains = _path1.contains( midPoint );
                insidePath1 = (thisWinding === path1Clockwise || subtractionOp )? contains :
                contains && !testOnCurve( _path1, midPoint );
            }
            if( thisId !== path2Id ){
                contains = _path2.contains( midPoint );
                insidePath2 = (thisWinding === path2Clockwise )? contains :
                contains && !testOnCurve( _path2, midPoint );
            }
            if( !operator( thisId === path1Id, insidePath1, insidePath2 ) ){
                crv._INVALID = true;
                // markPoint( midPoint, '+' );
            }
        }
    }

    // Final step: Retrieve the resulting paths from the graph
    var boolResult = new CompoundPath();
    var node, nuNode, nuPath, nodeList = [], handle;
    for (i = 0, len = paths.length; i < len; i++) {
        nodeList = nodeList.concat( paths[i].segments );
    }
    for (i = 0, len = nodeList.length; i < len; i++) {
        node = nodeList[i];
        if( node.curve._INVALID || node._visited ){ continue; }
        path = node.path;
        thisId = ( path.parent instanceof CompoundPath )? path.parent.id : path.id;
        thisWinding = path.clockwise;
        nuPath = new Path();
        firstNode = null;
        firstNode_ix = null;
        if( node.previous.curve._INVALID ) {
            node.handleIn = ( node._ixPair )?
            node._ixPair.getIntersection()._segment.handleIn : [ 0, 0 ];
        }
{'fraction_non_alphanumeric': 0.118679606997364, 'fraction_numerical': 0.010723699976036425, 'mean_word_length': 1.6985127707727126, 'pattern_counts': {'":': 0, '<': 27, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2035224', 'n_tokens_mistral': 5067, 'n_tokens_neox': 4829, 'n_words': 1395}