<commit_before>// TODO: trim support
var QWeb2 = {
    expressions_cache: {},
    reserved_words: 'true,false,NaN,null,undefined,debugger,in,instanceof,new,function,return,this,typeof,eval,Math,RegExp,Array,Object'.split(','),
    actions_precedence: 'foreach,if,call,set,esc,escf,raw,rawf,js,debug,log'.split(','),
    word_replacement: {
        'and': '&&',
        'or': '||',
        'gt': '>',
        'gte': '>=',
        'lt': '<',
        'lte': '<='
    },
    tools: {
        exception: function(message, context) {
            context = context || {};
            var prefix = 'QWeb2';
            if (context.template) {
                prefix += " - template['" + context.template + "']";
            }
            throw prefix + ": " + message;
        },
        js_escape: function(s, noquotes) {
            return (noquotes ? '' : "'") + s.replace(/\r?\n/g, "\\n").replace(/'/g, "\\'") + (noquotes ? '' : "'");
        },
        html_escape: function(s, attribute) {
            if (s === null || s === undefined) {
                return '';
            }
            s = (new String(s)).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
            if (attribute) {
                s = s.replace(/"/g, '&quot;');
            }
            return s;
        },
        gen_attribute: function(o) {
            if (o !== null && o !== undefined) {
                if (o.constructor === Array) {
                    if (o[1] !== null && o[1] !== undefined) {
                        return ' ' + o[0] + '="' + this.html_escape(o[1]) + '"';
                    }
                } else if (typeof o === 'object') {
                    var r = '';
                    for (var k in o) {
                        if (o.hasOwnProperty(k)) {
                            r += this.gen_attribute([k, o[k]]);
                        }
                    }
                    return r;
                }
            }
            return '';
        },
        extend: function(dst, src, exclude) {
            for (var p in src) {
                if (src.hasOwnProperty(p) && !(exclude && this.arrayIndexOf(exclude, p) !== -1)) {
                    dst[p] = src[p];
                }
            }
            return dst;
        },
        arrayIndexOf : function(array, item) {
            for (var i = 0, ilen = array.length; i < ilen; i++) {
                if (array[i] === item) {
                    return i;
                }
            }
            return -1;
        },
        call: function(context, template, old_dict, _import, callback) {
            var new_dict = this.extend({}, old_dict);
            new_dict['__caller__'] = old_dict['__template__'];
            if (callback) {
                new_dict[0] = callback(context, new_dict);
            }
            var r = context.engine._render(template, new_dict);
            if (_import) {
                if (_import === '*') {
                    this.extend(old_dict, new_dict, ['__caller__', '__template__']);
                } else {
                    _import = _import.split(',');
                    for (var i = 0, ilen = _import.length; i < ilen; i++) {
                        var v = _import[i];
                        old_dict[v] = new_dict[v];
                    }
                }
            }
            return r;
        },
        foreach: function(context, enu, as, old_dict, callback) {
            if (enu != null) {
                var size, new_dict = this.extend({}, old_dict);
                new_dict[as + "_all"] = enu;
                var as_value = as + "_value",
                    as_index = as + "_index",
                    as_first = as + "_first",
                    as_last = as + "_last",
                    as_parity = as + "_parity";
                if (size = enu.length) {
                    new_dict[as + "_size"] = size;
                    for (var j = 0, jlen = enu.length; j < jlen; j++) {
                        var cur = enu[j];
                        new_dict[as_value] = cur;
                        new_dict[as_index] = j;
                        new_dict[as_first] = j === 0;
                        new_dict[as_last] = j + 1 === size;
                        new_dict[as_parity] = (j % 2 == 1 ? 'odd' : 'even');
                        if (cur.constructor === Object) {
                            this.extend(new_dict, cur);
                        }
                        new_dict[as] = cur;
                        callback(context, new_dict);
                    }
                } else if (enu.constructor == Number) {
                    var _enu = [];
                    for (var i = 0; i < enu; i++) {
                        _enu.push(i);
                    }
                    this.foreach(context, enu, as, old_dict, callback);
                } else {
                    var index = 0;
                    for (var k in enu) {
                        if (enu.hasOwnProperty(k)) {
                            var v = enu[k];
                            new_dict[as_value] = v;
                            new_dict[as_index] = index;
                            new_dict[as_first] = index === 0;
                            new_dict[as_parity] = (j % 2 == 1 ? 'odd' : 'even');
                            new_dict[as] = k;
                            callback(context, new_dict);
                            index += 1;
                        }
                      }
                }
            } else {
                this.exception("No enumerator given to foreach", context);
            }
        }
    }
};

QWeb2.Engine = (function() {
    function Engine() {
        // TODO: handle prefix at template level : t-prefix="x"
        this.prefix = 't';
        this.debug = false;
        this.templates_resources = []; // TODO: implement this.reload()
        this.templates = {};
        this.compiled_templates = {};
        this.dict = {};
        this.tools = QWeb2.tools;
        for (var i = 0; i < arguments.length; i++) {
            this.add_template(arguments[i]);
        }
    }

    QWeb2.tools.extend(Engine.prototype, {
        add_template : function(template) {
            this.templates_resources.push(template);
            if (template.constructor === String) {
                template = this.load_xml(template);
            }
            var ec = (template.documentElement && template.documentElement.childNodes) || template.childNodes || [];
            for (var i = 0; i < ec.length; i++) {
                var node = ec[i];
                if (node.nodeType === 1) {
                    if (node.nodeName == 'parsererror') {
                        return this.tools.exception(node.innerText);
                    }
                    var name = node.getAttribute(this.prefix + '-name');
                    if (name) {
                        this.templates[name] = node;
                    }
                }
            }
            return true;
        },
        load_xml : function(s) {
            s = s.replace(/^\s*|\s*$/g, '');
            if (s[0] === '<?xml') {
                return this.load_xml_string(s);
            } else {
                var req = this.get_xhr();
                if (req) {
                    // TODO: third parameter is async : https://developer.mozilla.org/en/XMLHttpRequest#open()
                    // do an on_ready in QWeb2{} that could be passed to add_template
                    req.open('GET', s, false);
                    req.send(null);
                    if (req.responseXML) {
                        if (req.responseXML.documentElement.nodeName == "parsererror") {
                            return this.tools.exception(req.responseXML.documentElement.childNodes[0].nodeValue);
                        }
                        return req.responseXML;
                    } else {
                        return this.load_xml_string(req.responseText);
                    }
                }
            }
        },
        load_xml_string : function(s) {
            if (window.DOMParser) {
                var dp = new DOMParser();
                var r = dp.parseFromString(s, "text/xml");
                if (r.body && r.body.firstChild && r.body.firstChild.nodeName == 'parsererror') {
                    return this.tools.exception(r.body.innerText);
                }
                return r;
            }
            var xDoc;
            try {
                // new ActiveXObject("Msxml2.DOMDocument.4.0");<commit_msg>[FIX] QWeb2: fix xml string detection<commit_after>// TODO: trim support
var QWeb2 = {
    expressions_cache: {},
    reserved_words: 'true,false,NaN,null,undefined,debugger,in,instanceof,new,function,return,this,typeof,eval,Math,RegExp,Array,Object'.split(','),
    actions_precedence: 'foreach,if,call,set,esc,escf,raw,rawf,js,debug,log'.split(','),
    word_replacement: {
        'and': '&&',
        'or': '||',
        'gt': '>',
        'gte': '>=',
        'lt': '<',
        'lte': '<='
    },
    tools: {
        exception: function(message, context) {
            context = context || {};
            var prefix = 'QWeb2';
            if (context.template) {
                prefix += " - template['" + context.template + "']";
            }
            throw prefix + ": " + message;
        },
        trim: function(s, mode) {
            switch (mode) {
                case "left":
                    return s.replace(/^\s*/, "");
                case "right":
                    return s.replace(/\s*$/, "");
                default:
                    return s.replace(/^\s*|\s*$/g, "");
            }
        },
        js_escape: function(s, noquotes) {
            return (noquotes ? '' : "'") + s.replace(/\r?\n/g, "\\n").replace(/'/g, "\\'") + (noquotes ? '' : "'");
        },
        html_escape: function(s, attribute) {
            if (s === null || s === undefined) {
                return '';
            }
            s = (new String(s)).replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
            if (attribute) {
                s = s.replace(/"/g, '&quot;');
            }
            return s;
        },
        gen_attribute: function(o) {
            if (o !== null && o !== undefined) {
                if (o.constructor === Array) {
                    if (o[1] !== null && o[1] !== undefined) {
                        return ' ' + o[0] + '="' + this.html_escape(o[1]) + '"';
                    }
                } else if (typeof o === 'object') {
                    var r = '';
                    for (var k in o) {
                        if (o.hasOwnProperty(k)) {
                            r += this.gen_attribute([k, o[k]]);
                        }
                    }
                    return r;
                }
            }
            return '';
        },
        extend: function(dst, src, exclude) {
            for (var p in src) {
                if (src.hasOwnProperty(p) && !(exclude && this.arrayIndexOf(exclude, p) !== -1)) {
                    dst[p] = src[p];
                }
            }
            return dst;
        },
        arrayIndexOf : function(array, item) {
            for (var i = 0, ilen = array.length; i < ilen; i++) {
                if (array[i] === item) {
                    return i;
                }
            }
            return -1;
        },
        call: function(context, template, old_dict, _import, callback) {
            var new_dict = this.extend({}, old_dict);
            new_dict['__caller__'] = old_dict['__template__'];
            if (callback) {
                new_dict[0] = callback(context, new_dict);
            }
            var r = context.engine._render(template, new_dict);
            if (_import) {
                if (_import === '*') {
                    this.extend(old_dict, new_dict, ['__caller__', '__template__']);
                } else {
                    _import = _import.split(',');
                    for (var i = 0, ilen = _import.length; i < ilen; i++) {
                        var v = _import[i];
                        old_dict[v] = new_dict[v];
                    }
                }
            }
            return r;
        },
        foreach: function(context, enu, as, old_dict, callback) {
            if (enu != null) {
                var size, new_dict = this.extend({}, old_dict);
                new_dict[as + "_all"] = enu;
                var as_value = as + "_value",
                    as_index = as + "_index",
                    as_first = as + "_first",
                    as_last = as + "_last",
                    as_parity = as + "_parity";
                if (size = enu.length) {
                    new_dict[as + "_size"] = size;
                    for (var j = 0, jlen = enu.length; j < jlen; j++) {
                        var cur = enu[j];
                        new_dict[as_value] = cur;
                        new_dict[as_index] = j;
                        new_dict[as_first] = j === 0;
                        new_dict[as_last] = j + 1 === size;
                        new_dict[as_parity] = (j % 2 == 1 ? 'odd' : 'even');
                        if (cur.constructor === Object) {
                            this.extend(new_dict, cur);
                        }
                        new_dict[as] = cur;
                        callback(context, new_dict);
                    }
                } else if (enu.constructor == Number) {
                    var _enu = [];
                    for (var i = 0; i < enu; i++) {
                        _enu.push(i);
                    }
                    this.foreach(context, enu, as, old_dict, callback);
                } else {
                    var index = 0;
                    for (var k in enu) {
                        if (enu.hasOwnProperty(k)) {
                            var v = enu[k];
                            new_dict[as_value] = v;
                            new_dict[as_index] = index;
                            new_dict[as_first] = index === 0;
                            new_dict[as_parity] = (j % 2 == 1 ? 'odd' : 'even');
                            new_dict[as] = k;
                            callback(context, new_dict);
                            index += 1;
                        }
                      }
                }
            } else {
                this.exception("No enumerator given to foreach", context);
            }
        }
    }
};

QWeb2.Engine = (function() {
    function Engine() {
        // TODO: handle prefix at template level : t-prefix="x"
        this.prefix = 't';
        this.debug = false;
        this.templates_resources = []; // TODO: implement this.reload()
        this.templates = {};
        this.compiled_templates = {};
        this.dict = {};
        this.tools = QWeb2.tools;
        for (var i = 0; i < arguments.length; i++) {
            this.add_template(arguments[i]);
        }
    }

    QWeb2.tools.extend(Engine.prototype, {
        add_template : function(template) {
            this.templates_resources.push(template);
            if (template.constructor === String) {
                template = this.load_xml(template);
            }
            var ec = (template.documentElement && template.documentElement.childNodes) || template.childNodes || [];
            for (var i = 0; i < ec.length; i++) {
                var node = ec[i];
                if (node.nodeType === 1) {
                    if (node.nodeName == 'parsererror') {
                        return this.tools.exception(node.innerText);
                    }
                    var name = node.getAttribute(this.prefix + '-name');
                    if (name) {
                        this.templates[name] = node;
                    }
                }
            }
            return true;
        },
        load_xml : function(s) {
            s = s.replace(/^\s*|\s*$/g, '');
            if (this.tools.trim(s)[0] === '<') {
                return this.load_xml_string(s);
            } else {
                var req = this.get_xhr();
                if (req) {
                    // TODO: third parameter is async : https://developer.mozilla.org/en/XMLHttpRequest#open()
                    // do an on_ready in QWeb2{} that could be passed to add_template
                    req.open('GET', s, false);
                    req.send(null);
                    if (req.responseXML) {
                        if (req.responseXML.documentElement.nodeName == "parsererror") {
                            return this.tools.exception(req.responseXML.documentElement.childNodes[0].nodeValue);
                        }
                        return req.responseXML;
                    } else {
                        return this.load_xml_string(req.responseText);
                    }
                }
            }
        },
        load_xml_string : function(s) {
            if (window.DOMParser) {
                var dp = new DOMParser();
                var r = dp.parseFromString(s, "text/xml");
                if (r.body && r.body.firstChild && r.body.firstChild.nodeName == 'parsererror') {
                    return this.tools.exception(r.body.innerText);
                }
                return r;
            }
            var xDoc;
            try {
                // new ActiveXObject("Msxml2.DOMDocument.4.0");
{'fraction_non_alphanumeric': 0.1382123161764706, 'fraction_numerical': 0.003963694852941176, 'mean_word_length': 1.0894143062890063, 'pattern_counts': {'":': 4, '<': 23, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 16}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2538802', 'n_tokens_mistral': 4896, 'n_tokens_neox': 4646, 'n_words': 965}