<commit_before>function MRS(parentElement, mrsData){
    // Constant pixel sizes used
    const MAXWIDTH = 600;     // width before a list of elements is wrapped 
    const XGAP = 5;           // horizontal gap between elements
    const YGAP = 5;           // vertical gap between 1-line features 
    const YGAPSTRUCT = 10;    // vertical gap between full feature structures
    const BRACKETYPAD = 5;    // distance bracket extents above/below box
    const BRACKETXWIDTH = 5;  // width of right-angle corner thing 
    const ANGLEHEIGHT = 50;   // Height of angle brackets
    const ANGLEWIDTH = XGAP;  // Width of angle brackets
    const FEATNAMEXGAP = 80;

    // Global offset for keeping track of where next thing needs to be drawn on
    // the Y axis.
    var CURRENTY = 0;

    function drawMrs() {
        var svg = SVG(parentElement);
        var mrs = svg.group();
        var container = mrs.group();

        CURRENTY = 0;
        drawFeatStructType(container, '');
        drawFeatValPair(container, 'TOP', mrsData.top);
        drawFeatValPair(container, 'INDEX', mrsData.index);    
        drawFeatValPair(container, 'RELS', mrsData.relations); 
        drawFeatValPair(container, 'HCONS', mrsData.constraints); 
        drawFeatValPair(container, 'ICONS', mrsData.constraints); 
        drawSquareBrackets(mrs, XGAP);
        
        // transform the MRS to take into account the square brackets drawn at
        // negative coordinates
        mrs.transform({x:XGAP+10, y:BRACKETYPAD});
        
        // update the dimensions of the final SVG to match those of the now
        // rendered MRS
        var finalBbox = mrs.tbox();
        svg.size(finalBbox.width+10, finalBbox.height+5);
        return svg.node;
    }

    function drawFeatStructType(parent, name) {
        var text = parent.plain(name).y(CURRENTY).attr({'font-style':'italic'});    
        CURRENTY += text.tbox().height;
        return text;
    }

    function drawFeatValPair(parent, name, value) {
        var group = parent.group();

        if (typeof value === 'string' || value instanceof String) {
            // value is a string 
            var featText = group.plain(name).y(CURRENTY);
            var attrs = {'title': value,
                         'font-style': 'italic'};

            if (name != 'CARG'){
                // If it's not 'CARG' then it's a variable
                attrs['class'] = 'variable';
                attrs['data-var'] = value;
            }

            var featVal = group.plain(value).move(FEATNAMEXGAP, CURRENTY).attr(attrs);
        } else if (Object.prototype.toString.call(value) === '[object Array]'){
            // value is a list
            if (name == 'RELS') {
                var itemFunc = relFeatStruct;
            } else if (name == 'HCONS') {
                // filter out ICONS values from the constraints list
                var value = value.filter(constraint => constraint.high != null);
                var itemFunc = hconsFeatStruct;
            } else if (name == 'ICONS') {
                // filter out HCONS values from the constraints list
                var value = value.filter(constraint => constraint.high == null);
                var itemFunc = iconsFeatStruct;
            }

            if (value.length == 0)
                // no constraints needed to render
                return null;
            
            var featText = group.plain(name);
            var list = drawList(group, value, itemFunc);
            var firstLine = list.select('g').first();
            featText.cy(firstLine.tbox().cy);

            // transform the group to make space <commit_msg>Make detection of HCONS constraints more robust<commit_after>function MRS(parentElement, mrsData){
    // Constant pixel sizes used
    const MAXWIDTH = 600;     // width before a list of elements is wrapped 
    const XGAP = 5;           // horizontal gap between elements
    const YGAP = 5;           // vertical gap between 1-line features 
    const YGAPSTRUCT = 10;    // vertical gap between full feature structures
    const BRACKETYPAD = 5;    // distance bracket extents above/below box
    const BRACKETXWIDTH = 5;  // width of right-angle corner thing 
    const ANGLEHEIGHT = 50;   // Height of angle brackets
    const ANGLEWIDTH = XGAP;  // Width of angle brackets
    const FEATNAMEXGAP = 80;

    // Global offset for keeping track of where next thing needs to be drawn on
    // the Y axis.
    var CURRENTY = 0;

    function drawMrs() {
        var svg = SVG(parentElement);
        var mrs = svg.group();
        var container = mrs.group();

        CURRENTY = 0;
        drawFeatStructType(container, '');
        drawFeatValPair(container, 'TOP', mrsData.top);
        drawFeatValPair(container, 'INDEX', mrsData.index);    
        drawFeatValPair(container, 'RELS', mrsData.relations); 
        drawFeatValPair(container, 'HCONS', mrsData.constraints); 
        drawFeatValPair(container, 'ICONS', mrsData.constraints); 
        drawSquareBrackets(mrs, XGAP);
        
        // transform the MRS to take into account the square brackets drawn at
        // negative coordinates
        mrs.transform({x:XGAP+10, y:BRACKETYPAD});
        
        // update the dimensions of the final SVG to match those of the now
        // rendered MRS
        var finalBbox = mrs.tbox();
        svg.size(finalBbox.width+10, finalBbox.height+5);
        return svg.node;
    }

    function drawFeatStructType(parent, name) {
        var text = parent.plain(name).y(CURRENTY).attr({'font-style':'italic'});    
        CURRENTY += text.tbox().height;
        return text;
    }

    function drawFeatValPair(parent, name, value) {
        var group = parent.group();

        if (typeof value === 'string' || value instanceof String) {
            // value is a string 
            var featText = group.plain(name).y(CURRENTY);
            var attrs = {'title': value,
                         'font-style': 'italic'};

            if (name != 'CARG'){
                // If it's not 'CARG' then it's a variable
                attrs['class'] = 'variable';
                attrs['data-var'] = value;
            }

            var featVal = group.plain(value).move(FEATNAMEXGAP, CURRENTY).attr(attrs);
        } else if (Object.prototype.toString.call(value) === '[object Array]'){
            // value is a list
            if (name == 'RELS') {
                var itemFunc = relFeatStruct;
            } else if (name == 'HCONS') {
                // filter out ICONS values from the constraints list
                var value = value.filter(constraint => constraint.high != null && constraint.high.match(/h(andle)?\d+/));
                var itemFunc = hconsFeatStruct;
            } else if (name == 'ICONS') {
                // filter out HCONS values from the constraints list
                var value = value.filter(constraint => constraint.high == null || !constraint.high.match(/h(andle)?\d+/));
                var itemFunc = iconsFeatStruct;
            }

            if (value.length == 0)
                // no constraints needed to render
                return null;
            
            var featText = group.plain(name);
            var list = drawList(group, value, itemFunc);
            var firstLine = list.select('g').first();
            featText.cy(firstLine.tbox().cy);

            // transform the group to make space 
{'fraction_non_alphanumeric': 0.10748482805124747, 'fraction_numerical': 0.0059339177343223195, 'mean_word_length': 1.9300671671276175, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '3888979', 'n_tokens_mistral': 2195, 'n_tokens_neox': 2024, 'n_words': 614}