<commit_before>
L.GeometryUtil = {
    computeAngle: function(a, b) {
        return (Math.atan2(b.y - a.y, b.x - a.x) * 180 / Math.PI) + 90;
    },

    getPointPathPixelLength: function(pts) {
        var nbPts = pts.length;
        if(nbPts < 2) {
            return 0;
        }
        var dist = 0;
        var prevPt = pts[0], pt; 
        for(var i=1, l=pts.length; i<l; i++) {
            dist += prevPt.distanceTo(pt = pts[i]);
            prevPt = pt;
        } 
        return dist;
    },

    getPixelLength: function(pl, map) {
        var ll = (pl instanceof L.Polyline) ? pl.getLatLngs() : pl;
        var nbPts = ll.length;
        if(nbPts < 2) {
            return 0;
        }
        var dist = 0;
        var prevPt = map.latLngToLayerPoint(ll[0]), pt; 
        for(var i=1, l=ll.length; i<l; i++) {
            dist += prevPt.distanceTo(pt = map.latLngToLayerPoint(ll[i]));
            prevPt = pt;
        } 
        return dist;
    },

    /**
    * path: array of L.LatLng
    * offsetRatio: the ratio of the total pixel length where the pattern will start
    * repeatRatio: the ratio of the total pixel length between two points of the pattern 
    * map: the map, to access the current projection state
    */
    projectPatternOnPath: function (path, offsetRatio, repeatRatio, map) {
        var pathAsPoints = [];
        for(var i=0, l=path.length; i<l; i++) {
            pathAsPoints[i] = map.latLngToLayerPoint(path[i]);
        }
        // project the pattern as pixel points
        var pattern = this.projectPatternOnPointPath(pathAsPoints, offsetRatio, repeatRatio);
        // and convert it to latlngs;
        for(var i=0, l=pattern.length; i<l; i++) {
            pattern[i].latLng = map.layerPointToLatLng(pattern[i].pt);
        }        
        return pattern;
    },
    
    projectPatternOnPointPath: function (pts, offsetRatio, repeatRatio) {
        var positions = [];
        // 1. compute the absolute interval length in pixels
        var repeatIntervalLength = L.GeometryUtil.getPointPathPixelLength(pts) * repeatRatio;
        // 2. find the starting point by using the offsetRatio
        var previous = L.GeometryUtil.interpolateOnPointPath(pts, offsetRatio);
        positions.push(previous);
        // 3. consider only the rest of the path, starting at the previous point
        var remainingPath = pts;
        remainingPath = remainingPath.slice(previous.predecessor);
        remainingPath[0] = previous.pt;
        var remainingLength = L.GeometryUtil.getPointPathPixelLength(remainingPath, map);
        // 4. project as a ratio of the remaining length,
        // and repeat while there is room for another point of the pattern
        while(repeatIntervalLength <= remainingLength) {
            previous = L.GeometryUtil.interpolateOnPointPath(remainingPath, repeatIntervalLength/remainingLength);
            positions.push(previous);
            remainingPath = remainingPath.slice(previous.predecessor);
            remainingPath[0] = previous.pt;
            remainingLength = L.GeometryUtil.getPointPathPixelLength(remainingPath, map);
         }
        return positions;
    },

    /**
    * pts: array of L.Point
    * ratio: the ratio of the total length where the point should be computed
    * Returns null if ll has less than 2 LatLng, or an object with the following properties:
    *    latLng: the LatLng of the interpolated point
    *    predecessor: the index of the previous vertex on the path
    *    heading: the heading of the path at this point, in degrees
    */
    interpolateOnPointPath: function (pts, ratio) {
        var nbVertices = pts.length;

        if (nbVertices < 2) {
            return null;<commit_msg>Fixed an infinite loop bug for pattern.repeat:0<commit_after>
L.GeometryUtil = {
    computeAngle: function(a, b) {
        return (Math.atan2(b.y - a.y, b.x - a.x) * 180 / Math.PI) + 90;
    },

    getPointPathPixelLength: function(pts) {
        var nbPts = pts.length;
        if(nbPts < 2) {
            return 0;
        }
        var dist = 0;
        var prevPt = pts[0], pt; 
        for(var i=1, l=pts.length; i<l; i++) {
            dist += prevPt.distanceTo(pt = pts[i]);
            prevPt = pt;
        } 
        return dist;
    },

    getPixelLength: function(pl, map) {
        var ll = (pl instanceof L.Polyline) ? pl.getLatLngs() : pl;
        var nbPts = ll.length;
        if(nbPts < 2) {
            return 0;
        }
        var dist = 0;
        var prevPt = map.latLngToLayerPoint(ll[0]), pt; 
        for(var i=1, l=ll.length; i<l; i++) {
            dist += prevPt.distanceTo(pt = map.latLngToLayerPoint(ll[i]));
            prevPt = pt;
        } 
        return dist;
    },

    /**
    * path: array of L.LatLng
    * offsetRatio: the ratio of the total pixel length where the pattern will start
    * repeatRatio: the ratio of the total pixel length between two points of the pattern 
    * map: the map, to access the current projection state
    */
    projectPatternOnPath: function (path, offsetRatio, repeatRatio, map) {
        var pathAsPoints = [];
        for(var i=0, l=path.length; i<l; i++) {
            pathAsPoints[i] = map.latLngToLayerPoint(path[i]);
        }
        // project the pattern as pixel points
        var pattern = this.projectPatternOnPointPath(pathAsPoints, offsetRatio, repeatRatio);
        // and convert it to latlngs;
        for(var i=0, l=pattern.length; i<l; i++) {
            pattern[i].latLng = map.layerPointToLatLng(pattern[i].pt);
        }        
        return pattern;
    },
    
    projectPatternOnPointPath: function (pts, offsetRatio, repeatRatio) {
        var positions = [];
        // 1. compute the absolute interval length in pixels
        var repeatIntervalLength = L.GeometryUtil.getPointPathPixelLength(pts) * repeatRatio;
        // 2. find the starting point by using the offsetRatio
        var previous = L.GeometryUtil.interpolateOnPointPath(pts, offsetRatio);
        positions.push(previous);
        if(repeatRatio > 0) {
            // 3. consider only the rest of the path, starting at the previous point
            var remainingPath = pts;
            remainingPath = remainingPath.slice(previous.predecessor);
            remainingPath[0] = previous.pt;
            var remainingLength = L.GeometryUtil.getPointPathPixelLength(remainingPath, map);
            // 4. project as a ratio of the remaining length,
            // and repeat while there is room for another point of the pattern
            while(repeatIntervalLength <= remainingLength) {
                previous = L.GeometryUtil.interpolateOnPointPath(remainingPath, repeatIntervalLength/remainingLength);
                positions.push(previous);
                remainingPath = remainingPath.slice(previous.predecessor);
                remainingPath[0] = previous.pt;
                remainingLength = L.GeometryUtil.getPointPathPixelLength(remainingPath, map);
            }
        }
        return positions;
    },

    /**
    * pts: array of L.Point
    * ratio: the ratio of the total length where the point should be computed
    * Returns null if ll has less than 2 LatLng, or an object with the following properties:
    *    latLng: the LatLng of the interpolated point
    *    predecessor: the index of the previous vertex on the path
    *    heading: the heading of the path at this point, in degrees
    */
    interpolateOnPointPath: function (pts, ratio) {
        var nbVertices = pts.length;

        if (nbVertices < 2) {
            return null;
{'fraction_non_alphanumeric': 0.09710661910424098, 'fraction_numerical': 0.007134363852556481, 'mean_word_length': 2.186026936026936, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 4, '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': '6573920', 'n_tokens_mistral': 2228, 'n_tokens_neox': 2176, 'n_words': 653}