Пример #1
0
function resolveValue(value, map) {
  // matches `name[, fallback]`, captures 'name' and 'fallback'
  var RE_VAR = /([\w-]+)(?:\s*,\s*)?(.*)?/;
  var balancedParens = balanced('(', ')', value);
  var varStartIndex = value.indexOf('var(');
  var varRef = balanced('(', ')', value.substring(varStartIndex)).body;

  if (!balancedParens) throw new Error('rework-vars: missing closing ")" in the value "' + value + '"');
  if (varRef === '') throw new Error('rework-vars: var() must contain a non-whitespace string');

  var varFunc = VAR_FUNC_IDENTIFIER + '(' + varRef + ')';

  var varResult = varRef.replace(RE_VAR, function (_, name, fallback) {
    var replacement = map[name];
    if (!replacement && !fallback) throw new Error('rework-vars: variable "' + name + '" is undefined');
    if (!replacement && fallback) return fallback;
    return replacement;
  });


  // resolve the variable
  value = value.split(varFunc).join(varResult);

  // recursively resolve any remaining variables in the value
  if (value.indexOf(VAR_FUNC_IDENTIFIER) !== -1) {
    value = resolveValue(value, map);
  }

  return value;
}
Пример #2
0
function parse(str) {
  var ret = '<H1>' + balanced('<B>', '</B>', str).body + '</H1>\n';
  ret += str.substr(str.indexOf('<H2>'));

  var tpl = balanced('{{', '}}', read('../assets/template.mustache'));
  return tpl.pre + ret + tpl.post;
}
Пример #3
0
function filterOptimiser(rule) {
    var match = balancedMatch('(', ')', rule.value);
    if (match) {
        var filterFunc = list.comma(match.body).join(',');
        rule.value = match.pre + '(' + filterFunc + ')' + match.post;
    }
}
Пример #4
0
 function balanced(a, b, str) {
   var bal = 0;
   var m = {};
   var ended = false;
   for (var i = 0; i < str.length; i++) {
     if (a == str.substr(i, a.length)) {
       if (!('start' in m))
         m.start = i;
       bal++;
     } else if (b == str.substr(i, b.length) && 'start' in m) {
       ended = true;
       bal--;
       if (!bal) {
         m.end = i;
         m.pre = str.substr(0, m.start);
         m.body = (m.end - m.start > 1) ? str.substring(m.start + a.length, m.end) : '';
         m.post = str.slice(m.end + b.length);
         return m;
       }
     }
   }
   if (bal && ended) {
     var start = m.start + a.length;
     m = balanced(a, b, str.substr(start));
     if (m) {
       m.start += start;
       m.end += start;
       m.pre = str.slice(0, start) + m.pre;
     }
     return m;
   }
 }
Пример #5
0
  /**
   * Evaluates nested expressions
   *
   * @param {String} expression
   * @returns {String}
   */
  function evaluateNestedExpression(expression, call) {
    // Remove the calc part from nested expressions to ensure
    // better browser compatibility
    expression = expression.replace(/((?:\-[a-z]+\-)?calc)/g, "")
    var evaluatedPart = ""
    var nonEvaluatedPart = expression
    var matches
    while ((matches = NESTED_CALC_RE.exec(nonEvaluatedPart))) {
      if (matches[0].index > 0) {
        evaluatedPart += nonEvaluatedPart.substring(0, matches[0].index)
      }

      var balancedExpr = balanced("(", ")", nonEvaluatedPart.substring([0].index))
      if (balancedExpr.body === "") {
        throw new Error("'" + expression + "' must contain a non-whitespace string")
      }

      var evaluated = evaluateExpression(balancedExpr.body, "", call)

      evaluatedPart += balancedExpr.pre + evaluated
      nonEvaluatedPart = balancedExpr.post
    }

    return evaluatedPart + nonEvaluatedPart
  }
Пример #6
0
// Basically just str.split(","), but handling cases
// where we have nested braced sections, which should be
// treated as individual members, like {a,{b,c},d}
function parseCommaParts(str) {
  if (!str)
    return [''];

  var parts = [];
  var m = balanced('{', '}', str);

  if (!m)
    return str.split(',');

  var pre = m.pre;
  var body = m.body;
  var post = m.post;
  var p = pre.split(',');

  p[p.length-1] += '{' + body + '}';
  var postParts = parseCommaParts(post);
  if (post.length) {
    p[p.length-1] += postParts.shift();
    p.push.apply(p, postParts);
  }

  parts.push.apply(parts, p);

  return parts;
}
Пример #7
0
    return _.reduce(bracketPairs, function (accum, pair) {
        var name = '';
        var credits = accum.artistCredit;
        var remainder = accum.name;
        var b, m;

        while (true) {
            b = balanced(pair[0], pair[1], remainder);
            if (b) {
                m = extractFeatCredits(b.body, artists, isProbablyClassical, true);
                name += b.pre;

                if (m.name) {
                    // Check if the remaining text in the brackets is also an artist name.
                    var expandedCredits = expandCredit(m.name, artists, isProbablyClassical);

                    if (_.any(expandedCredits, c => c.similarity >= MB.constants.MIN_NAME_SIMILARITY)) {
                        credits = credits.concat(expandedCredits);
                    } else {
                        name += pair[0] + m.name + pair[1];
                    }
                }

                credits = credits.concat(m.artistCredit);
                remainder = b.post;
            } else {
                name += remainder;
                break;
            }
        }

        return {name: _str.clean(name), artistCredit: credits};
    }, {name: str, artistCredit: []});
Пример #8
0
function extractBlocks(src: string): TestBlock[] {
  let blocks: Array<TestBlock | null> = []
  let matchBlock: any
  while (matchBlock = balanced('{', '}', src)) {
    blocks.push(extractBlock(matchBlock.pre, matchBlock.body))
    src = matchBlock.post
  }
  let droppedNulls: TestBlock[] = _.compact(blocks)
  return droppedNulls
}
Пример #9
0
function convert (string) {
  var index = string.indexOf('color(');
  if (index == -1) return string;

  string = string.slice(index);
  string = balanced('(', ')', string);
  if (!string) throw new SyntaxError('Missing closing parentheses');
  var ast = parse('color(' + string.body + ')');
  return toRGB(ast) + convert(string.post);
}
Пример #10
0
function convert(string){
  var index = string.indexOf('color(');
  if (index == -1) return string;

  var fn = string.slice(index);
  var ret = balanced('(', ')', fn);
  if (!ret) throw new SyntaxError('Missing closing parentheses');
  fn = 'color(' + ret.body + ')';

  return string.slice(0, index) + color.convert(fn) + convert(ret.post);
}
Пример #11
0
const transformColor = (string, source) => {
  if (string.indexOf('mix(') === -1) {
    return string;
  }

  const value = balanced('(', ')', string).body;

  if (!value) { throw new Error(`Missing closing parentheses in "${string}"`, source); }

  return mix.apply(null, value.split(/,\s*(?![^()]*\))/));
};
Пример #12
0
const transformColor = (string, source) => {
  if (string.indexOf('shades(') === -1) {
    return string;
  }

  const shadeContent = balanced('shades(', ')', string);
  const value = shadeContent.body;

  if (!value) { throw new Error(`Missing closing parentheses in "${string}"`, source); }

  return shadeContent.pre + shades.apply(null, value.split(/,\s*(?![^()]*\))/)) + shadeContent.post;
};
Пример #13
0
 child.stderr.on('data', function(buf) {
   var str = String(buf);
   // mp3 starts with frame
   // flac, opus, wav with size
   if (str.substr(0, 6) == 'frame=' || str.substr(0, 5) == 'size=') {
     if (data != '') {
       var time = balanced('time=', ' ', data);
       if (time && time.body) percent(time.body, duration);
     }
     data = str;
   }
   else data += str;
 });
Пример #14
0
    match => {
      if (source[match.endIndex] !== "(") {
        return;
      }

      const parensMatch = balancedMatch(
        "(",
        ")",
        source.substr(match.startIndex)
      );

      callback(parensMatch.body, match.endIndex + 1);
    }
Пример #15
0
module.exports = function(content, opts) {
  var result = '';
  var reStart = new RegExp(opts.prefix + '[ ]*' + opts.name + '\\(');
  var reEnd = new RegExp('^[ ]*' + opts.suffix);
  var matchStart;
  var matchArg;
  var matchEnd;
  var safeStart;
  var before;
  var replacement;

  while (matchStart = reStart.exec(content)) {
    safeStart = matchStart.index + matchStart[0].length - 1;

    matchArg = balanced('(', ')', content.slice(safeStart));

    if (matchArg && matchArg.start === 0) {
      if (opts.suffix) {
        matchEnd = reEnd.exec(matchArg.post);
      }

      matchEnd = matchEnd ? matchEnd.index + matchEnd[0].length : 0;

      if (!opts.suffix || matchEnd) {
        before = content.slice(0, matchStart.index);
        replacement = opts.handler({
          before: before,
          args: matchArg.body,
        });

        if (replacement !== undefined) {
          result += before + replacement.toString();
          content = content.slice(safeStart + matchArg.end + 1 + matchEnd);
          continue;
        }
      }
    }

    result += content.slice(0, safeStart);
    content = content.slice(safeStart);
  }

  result += content;

  return result;
};
    selectorPart.forEach(part => {
      const position = part.indexOf(pseudoClass)
      const pre = part.slice(0, position)
      const body = part.slice(position)
      const matches = balancedMatch("(", ")", body)

      const bodySelectors = matches && matches.body ?
        list
          .comma(matches.body)
          .reduce((acc, s) => [
            ...acc,
            ...explodeSelector(s, options),
          ], [])
        : [body]

      const postSelectors = matches && matches.post
        ? explodeSelector(matches.post, options)
        : []

      let newParts
      if (postSelectors.length === 0) {
        // the test below is a poor way to try we are facing a piece of a
        // selector...
        if (position === -1 || pre.indexOf(" ") > -1) {
          newParts = bodySelectors.map((s) => preWhitespace + pre + s)
        }
        else {
          newParts = bodySelectors.map((s) => (
            normalizeSelector(s, preWhitespace, pre)
          ))
        }
      }
      else {
        newParts = []
        postSelectors.forEach(postS => {
          bodySelectors.forEach(s => {
            newParts.push(preWhitespace + pre + s + postS)
          })
        })
      }
      newSelectors = [
        ...newSelectors,
        ...newParts,
      ]
    })
Пример #17
0
/**
 * Transform color() to rgb()
 *
 * @param  {String} string declaration value
 * @return {String}        converted declaration value to rgba()
 */
function transformColor(string, source) {
  var index = string.search(/(^|[^\w\-])color\(/)

  if (index === -1) {
    return string
  }

  // NOTE: regexp search beginning of line of non char symbol before `color(`.
  //       Offset used for second case.
  index = index === 0 ? index : index + 1

  var fn = string.slice(index)
  var balancedMatches = balanced("(", ")", fn)
  if (!balancedMatches) {
    throw new Error("Missing closing parentheses in '" + string + "'", source)
  }

  return string.slice(0, index) + colorFn.convert("color(" + balancedMatches.body + ")") + transformColor(balancedMatches.post)
}
function parse(content, data, opts) {
  var regexpStart = new RegExp(opts.prefix + '[ ]*' + opts.name + '([^{}]*)\\{');
  var regexpEnd = opts.suffix ? new RegExp('^\\s*' + opts.suffix) : false;
  var replacement;
  var result = '';
  var matchStart;
  var matchBody;
  var matchEnd;
  var startEnd;
  var before;

  while (matchStart = regexpStart.exec(content)) {
    startEnd = matchStart.index + matchStart[0].length;
    matchBody = balanced('{', '}', content.slice(startEnd - 1));

    if (matchBody && matchBody.start === 0) {
      matchEnd = regexpEnd ? regexpEnd.exec(matchBody.post) : true;

      if (matchEnd) {
        before = content.slice(0, matchStart.index);
        matchEnd = regexpEnd ? matchEnd[0].length : 0;
        replacement = handler({
          before: before,
          args: matchStart[1],
          body: matchBody.body
        }, data);

        if (replacement !== undefined) {
          result += before + parse(replacement.toString(), data, opts);
          content = content.slice(startEnd + matchBody.end + matchEnd);
          continue;
        }
      }
    }

    result += content.slice(0, startEnd);
    content = content.slice(startEnd);
  }

  result += content;

  return result;
}
    return list.map(value, function (value, type) {
        var name,
            match,
            index;

        if (type === null) {
            return callback(value);
        }

        if (type === 'func') {
            index = value.indexOf('(');
            name = value.substring(0, index);
            if (~name.indexOf('calc')) {
                match = balanced('(', ')', value);
                if (match) {
                    return name + '(' + eachValue(match.body, callback) + ')';
                }
            }
        }
    });
Пример #20
0
    controller: function(ctrlName, inputArray) {
        var scope = {};
        if (depType == "") {
            depType = "controller";
        }
        if (typeof inputArray != 'undefined') {

            //dependecy not annotated
            if (typeof inputArray == 'function') {
                depfuncontent = inputArray;
                var bfind = balanced("(", ")", depfuncontent.toString().match(/function\s*\([^\)]*\s*\)/g)[0]);
                depArray = bfind.body.split(",");
            } else {
                //Last parameter is the function content
                depfuncontent = inputArray[inputArray.length - 1];
                //reduce the length by 1 to remove the last function parameter
                inputArray.length = inputArray.length - 1;
                depArray = inputArray;
            }
        }
    },
Пример #21
0
var getDependencies = function(funObject, callback) {

    var dtStamp = new Date().getTime().toString();
    var foldername = path.join(__dirname, "../AngularSrc");
    dtStamp = "";
    //Add datetimestamp to invalidate cache
    var fname = path.join(foldername, funObject.filename).replace(".js", dtStamp + ".js");

    //Remove the commented lines
    funObject.fileContent = funObject.fileContent.replace(/\/\/.*/g, "");
    funObject.fileContent = funObject.fileContent.replace(/\/\*(.|[\r\n])*?\*\//g, ""); //multiline comments
    //Check whether it is amd module or commonJs
    if (!funObject.fileContent.match(/define\s*\(/)) {
        isAMD = false;
        var start = funObject.fileContent.search(/.(controller|factory|service|provider|directive|config)\s*\(/g);
        var angContent = funObject.fileContent.substring(start);
        var bfind = balanced("(", ")", angContent);
        if (bfind) {
            var atemplate = fs.readFileSync(amdTemplateFile).toString();
            var fullCode = bfind.pre + "(" + bfind.body + ")";
            funObject.fileContent = atemplate.replace("{actualcode}", fullCode);
        }
    }

    fs.writeFileSync(fname, funObject.fileContent);
    depArray = "";
    depfuncontent = "";
    //require will call for a method define which in turn 
    //will call mycontroller to return the dependencies
    if (require.resolve(fname)) {
        delete require.cache[require.resolve(fname)];
    }
    var fcontent = require(fname);
    //wait for the file to be read
    var depMethods = getallFunctions(depfuncontent);
    var dirObject = getDirectiveObject(depfuncontent, directiveName)
    createTestSpec(fname.replace(dtStamp, ""), depArray, depMethods, dirObject);
    //return depArray;
    callback(depArray); //callback once completed
}
Пример #22
0
  /**
   * Evaluates nested expressions
   *
   * @param {String} expression
   * @returns {String}
   */
  function evaluateNestedExpression(expression, call) {
    var evaluatedPart = ""
    var nonEvaluatedPart = expression
    var matches
    while ((matches = NESTED_CALC_RE.exec(nonEvaluatedPart))) {
      if (matches[0].index > 0) {
        evaluatedPart += nonEvaluatedPart.substring(0, matches[0].index)
      }

      var balancedExpr = balanced("(", ")", nonEvaluatedPart.substring([0].index))
      if (balancedExpr.body === "") {
        throw new Error("'" + expression + "' must contain a non-whitespace string")
      }

      var evaluated = evaluateExpression(balancedExpr.body, "", call)

      evaluatedPart += balancedExpr.pre + evaluated
      nonEvaluatedPart = balancedExpr.post
    }

    return evaluatedPart + nonEvaluatedPart
  }
Пример #23
0
      valueParser(decl.value).walk(node => {
        if (node.type !== "function" || node.value !== "calc") { return }

        const parensMatch = balancedMatch("(", ")", valueParser.stringify(node))
        const rawExpression = parensMatch.body
        const expressionIndex = decl.source.start.column
          + decl.prop.length
          + decl.raws.between.length
          + node.sourceIndex
        const expression = blurVariables(rawExpression)

        checkSymbol("+")
        checkSymbol("-")
        checkSymbol("*")
        checkSymbol("/")

        function checkSymbol(symbol) {
          styleSearch({ source: expression, target: symbol, outsideFunctionalNotation: true }, match => {
            const index = match.startIndex

            // Deal with signs.
            // (@ and $ are considered "digits" here to allow for variable syntaxes
            // that permit signs in front of variables, e.g. `-$number`)
            if ((symbol === "+" || symbol === "-") && /[\d@\$]/.test(expression[index + 1])) {
              const expressionBeforeSign = expression.substr(0, index)
              // Ignore signs at the beginning of the expression
              if (/^\s*$/.test(expressionBeforeSign)) { return }

              // Otherwise, ensure that there is a real operator preceeding them
              if (/[\*/+-]\s*$/.test(expressionBeforeSign)) { return }

              report({
                message: messages.expectedOperatorBeforeSign(symbol),
                node: decl,
                index: expressionIndex + index,
                result,
                ruleName,
              })

              return
            }

            checker.after({
              index,
              source: expression,
              err: m => {
                report({
                  message: m,
                  node: decl,
                  index: expressionIndex + index,
                  result,
                  ruleName,
                })
              },
            })
            checker.before({
              index,
              source: expression,
              err: m => {
                report({
                  message: m,
                  node: decl,
                  index: expressionIndex + index,
                  result,
                  ruleName,
                })
              },
            })
          })
        }
      })
Пример #24
0
function expand(str, isTop) {
  var expansions = [];

  var m = balanced('{', '}', str);
  if (!m || /\$$/.test(m.pre)) return [str];

  var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
  var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
  var isSequence = isNumericSequence || isAlphaSequence;
  var isOptions = /^(.*,)+(.+)?$/.test(m.body);
  if (!isSequence && !isOptions) {
    // {a},b}
    if (m.post.match(/,.*\}/)) {
      str = m.pre + '{' + m.body + escClose + m.post;
      return expand(str);
    }
    return [str];
  }

  var n;
  if (isSequence) {
    n = m.body.split(/\.\./);
  } else {
    n = parseCommaParts(m.body);
    if (n.length === 1) {
      // x{{a,b}}y ==> x{a}y x{b}y
      n = expand(n[0], false).map(embrace);
      if (n.length === 1) {
        var post = m.post.length
          ? expand(m.post, false)
          : [''];
        return post.map(function(p) {
          return m.pre + n[0] + p;
        });
      }
    }
  }

  // at this point, n is the parts, and we know it's not a comma set
  // with a single entry.

  // no need to expand pre, since it is guaranteed to be free of brace-sets
  var pre = m.pre;
  var post = m.post.length
    ? expand(m.post, false)
    : [''];

  var N;

  if (isSequence) {
    var x = numeric(n[0]);
    var y = numeric(n[1]);
    var width = Math.max(n[0].length, n[1].length)
    var incr = n.length == 3
      ? Math.abs(numeric(n[2]))
      : 1;
    var test = lte;
    var reverse = y < x;
    if (reverse) {
      incr *= -1;
      test = gte;
    }
    var pad = n.some(isPadded);

    N = [];

    for (var i = x; test(i, y); i += incr) {
      var c;
      if (isAlphaSequence) {
        c = String.fromCharCode(i);
        if (c === '\\')
          c = '';
      } else {
        c = String(i);
        if (pad) {
          var need = width - c.length;
          if (need > 0) {
            var z = new Array(need + 1).join('0');
            if (i < 0)
              c = '-' + z + c.slice(1);
            else
              c = z + c;
          }
        }
      }
      N.push(c);
    }
  } else {
    N = concatMap(n, function(el) { return expand(el, false) });
  }

  for (var j = 0; j < N.length; j++) {
    for (var k = 0; k < post.length; k++) {
      var expansion = pre + N[j] + post[k];
      if (!isTop || isSequence || expansion)
        expansions.push(expansion);
    }
  }

  return expansions;
}
Пример #25
0
      valueParser(decl.value).walk(node => {
        if (node.type !== "function" || node.value.toLowerCase() !== "calc") {
          return
        }

        const parensMatch = balancedMatch("(", ")", valueParser.stringify(node))
        const rawExpression = parensMatch.body
        const expressionIndex = decl.source.start.column + decl.prop.length + (decl.raws.between || "").length + node.sourceIndex
        const expression = blurVariables(rawExpression)

        checkSymbol("+")
        checkSymbol("-")
        checkSymbol("*")
        checkSymbol("/")

        function checkSymbol(symbol) {
          const styleSearchOptions = {
            source: expression,
            target: symbol,
            functionArguments: "skip",
          }

          styleSearch(styleSearchOptions, match => {
            const index = match.startIndex

            // Deal with signs.
            // (@ and $ are considered "digits" here to allow for variable syntaxes
            // that permit signs in front of variables, e.g. `-$number`)
            // As is "." to deal with fractional numbers without a leading zero
            if ((symbol === "+" || symbol === "-") && /[\d@\$.]/.test(expression[index + 1])) {
              const expressionBeforeSign = expression.substr(0, index)

              // Ignore signs that directly follow a opening bracket
              if (expressionBeforeSign[expressionBeforeSign.length - 1] === "(") {
                return
              }

              // Ignore signs at the beginning of the expression
              if (/^\s*$/.test(expressionBeforeSign)) {
                return
              }

              // Otherwise, ensure that there is a real operator preceeding them
              if (/[\*/+-]\s*$/.test(expressionBeforeSign)) {
                return
              }

              // And if not, complain
              complain(messages.expectedOperatorBeforeSign(symbol), decl, expressionIndex + index)
              return
            }

            const beforeOk = expression[index - 1] === " " && !isWhitespace(expression[index - 2]) || newlineBefore(expression, index - 1)
            if (!beforeOk) {
              complain(messages.expectedBefore(symbol), decl, expressionIndex + index)
            }

            const afterOk = expression[index + 1] === " " && !isWhitespace(expression[index + 2]) || expression[index + 1] === "\n" || expression.substr(index + 1, 2) === "\r\n"

            if (!afterOk) {
              complain(messages.expectedAfter(symbol), decl, expressionIndex + index)
            }
          })
        }
      })
Пример #26
0
 function expand(str) {
   var expansions = [];
   var m = balanced('{', '}', str);
   if (!m || /\$$/.test(m.pre))
     return [str];
   var isNumericSequence = /^-?\d+\.\.-?\d+(?:\.\.-?\d+)?$/.test(m.body);
   var isAlphaSequence = /^[a-zA-Z]\.\.[a-zA-Z](?:\.\.-?\d+)?$/.test(m.body);
   var isSequence = isNumericSequence || isAlphaSequence;
   var isOptions = /^(.*,)+(.+)?$/.test(m.body);
   if (!isSequence && !isOptions) {
     if (m.post.match(/,.*}/)) {
       str = m.pre + '{' + m.body + escClose + m.post;
       return expand(str);
     }
     return [str];
   }
   var n;
   if (isSequence) {
     n = m.body.split(/\.\./);
   } else {
     n = parseCommaParts(m.body);
     if (n.length === 1) {
       n = expand(n[0]).map(embrace);
       if (n.length === 1) {
         var post = m.post.length ? expand(m.post) : [''];
         return post.map(function(p) {
           return m.pre + n[0] + p;
         });
       }
     }
   }
   var pre = m.pre;
   var post = m.post.length ? expand(m.post) : [''];
   var N;
   if (isSequence) {
     var x = numeric(n[0]);
     var y = numeric(n[1]);
     var width = Math.max(n[0].length, n[1].length);
     var incr = n.length == 3 ? Math.abs(numeric(n[2])) : 1;
     var test = lte;
     var reverse = y < x;
     if (reverse) {
       incr *= -1;
       test = gte;
     }
     var pad = n.some(isPadded);
     N = [];
     for (var i = x; test(i, y); i += incr) {
       var c;
       if (isAlphaSequence) {
         c = String.fromCharCode(i);
         if (c === '\\')
           c = '';
       } else {
         c = String(i);
         if (pad) {
           var need = width - c.length;
           if (need > 0) {
             var z = new Array(need + 1).join('0');
             if (i < 0)
               c = '-' + z + c.slice(1);
             else
               c = z + c;
           }
         }
       }
       N.push(c);
     }
   } else {
     N = concatMap(n, function(el) {
       return expand(el);
     });
   }
   for (var j = 0; j < N.length; j++) {
     for (var k = 0; k < post.length; k++) {
       expansions.push([pre, N[j], post[k]].join(''));
     }
   }
   return expansions;
 }
Пример #27
0
 getParamValue(param) {
   return /^\(/.test(param) ? balanced('(', ')', param).body : param;
 }