| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 | var defaults = require('./defaults.js');var underscore = require('./underscore.js');require('./templateSettings.js');// When customizing `_.templateSettings`, if you don't want to define an// interpolation, evaluation or escaping regex, we need one that is// guaranteed not to match.var noMatch = /(.)^/;// Certain characters need to be escaped so that they can be put into a// string literal.var escapes = {  "'": "'",  '\\': '\\',  '\r': 'r',  '\n': 'n',  '\u2028': 'u2028',  '\u2029': 'u2029'};var escapeRegExp = /\\|'|\r|\n|\u2028|\u2029/g;function escapeChar(match) {  return '\\' + escapes[match];}// In order to prevent third-party code injection through// `_.templateSettings.variable`, we test it against the following regular// expression. It is intentionally a bit more liberal than just matching valid// identifiers, but still prevents possible loopholes through defaults or// destructuring assignment.var bareIdentifier = /^\s*(\w|\$)+\s*$/;// JavaScript micro-templating, similar to John Resig's implementation.// Underscore templating handles arbitrary delimiters, preserves whitespace,// and correctly escapes quotes within interpolated code.// NB: `oldSettings` only exists for backwards compatibility.function template(text, settings, oldSettings) {  if (!settings && oldSettings) settings = oldSettings;  settings = defaults({}, settings, underscore.templateSettings);  // Combine delimiters into one regular expression via alternation.  var matcher = RegExp([    (settings.escape || noMatch).source,    (settings.interpolate || noMatch).source,    (settings.evaluate || noMatch).source  ].join('|') + '|$', 'g');  // Compile the template source, escaping string literals appropriately.  var index = 0;  var source = "__p+='";  text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {    source += text.slice(index, offset).replace(escapeRegExp, escapeChar);    index = offset + match.length;    if (escape) {      source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";    } else if (interpolate) {      source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";    } else if (evaluate) {      source += "';\n" + evaluate + "\n__p+='";    }    // Adobe VMs need the match returned to produce the correct offset.    return match;  });  source += "';\n";  var argument = settings.variable;  if (argument) {    // Insure against third-party code injection. (CVE-2021-23358)    if (!bareIdentifier.test(argument)) throw new Error(      'variable is not a bare identifier: ' + argument    );  } else {    // If a variable is not specified, place data values in local scope.    source = 'with(obj||{}){\n' + source + '}\n';    argument = 'obj';  }  source = "var __t,__p='',__j=Array.prototype.join," +    "print=function(){__p+=__j.call(arguments,'');};\n" +    source + 'return __p;\n';  var render;  try {    render = new Function(argument, '_', source);  } catch (e) {    e.source = source;    throw e;  }  var template = function(data) {    return render.call(this, data, underscore);  };  // Provide the compiled source as a convenience for precompilation.  template.source = 'function(' + argument + '){\n' + source + '}';  return template;}module.exports = template;
 |