function buildPolylines(lines, style, vertex_data, vertex_template, vindex, closed_polygon, remove_tile_edges, tile_edge_tolerance) {
  var cap_type = style.cap ? CAP_TYPE[style.cap] : CAP_TYPE.butt;
  var join_type = style.join ? JOIN_TYPE[style.join] : JOIN_TYPE.miter;

  // Configure miter limit
  if (join_type === JOIN_TYPE.miter) {
    var miter_limit = style.miter_limit || DEFAULT_MITER_LIMIT; // default miter limit
    var miter_len_sq = miter_limit * miter_limit;
  }

  // Texture Variables
  var v_scale;
  if (vindex.a_texcoord) {
    v_scale = 1 / (style.texcoord_width * V_SCALE_ADJUST); // scales line texture as a ratio of the line's width
  }

  // Values that are constant for each line and are passed to helper functions
  var context = {
    closed_polygon: closed_polygon,
    remove_tile_edges: remove_tile_edges,
    tile_edge_tolerance: tile_edge_tolerance,
    miter_len_sq: miter_len_sq,
    join_type: join_type,
    cap_type: cap_type,
    vertex_data: vertex_data,
    vertex_template: vertex_template,
    half_width: style.width / 2,
    extrude_index: vindex.a_extrude,
    offset_index: vindex.a_offset,
    v_scale: v_scale,
    texcoord_index: vindex.a_texcoord,
    texcoord_width: style.texcoord_width,
    offset: style.offset,
    geom_count: 0
  };

  // Process lines
  for (var i = 0; i < lines.length; i++) {
    buildPolyline(lines[i], context);
  }

  // Process extra lines (which are created above if lines need to be mutated for easier processing)
  if (context.extra_lines) {
    for (var _i = 0; _i < context.extra_lines.length; _i++) {
      buildPolyline(context.extra_lines[_i], context);
    }
  }
  return context.geom_count;
}
A "template" that sets constant attibutes for each vertex, which is then modified per vertex or per feature.
A plain JS array matching the order of the vertex layout.