text:
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/core/layout/ng/table/ng_table_borders.h"

#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/layout/ng/ng_block_node.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space.h"
#include "third_party/blink/renderer/core/layout/ng/ng_constraint_space_builder.h"
#include "third_party/blink/renderer/core/layout/ng/ng_length_utils.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table.h"
#include "third_party/blink/renderer/core/layout/ng/table/layout_ng_table_column_visitor.h"
#include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_helpers.h"
#include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_types.h"
#include "third_party/blink/renderer/core/layout/ng/table/ng_table_layout_algorithm_utils.h"
#include "third_party/blink/renderer/core/style/computed_style.h"

namespace blink {

namespace {

// https://www.w3.org/TR/css-tables-3/#conflict-resolution-for-collapsed-borders
bool IsSourceMoreSpecificThanEdge(EBorderStyle source_style,
                                  LayoutUnit source_width,
                                  const NGTableBorders::Edge& edge) {
  if (edge.edge_side == NGTableBorders::EdgeSide::kDoNotFill)
    return false;

  if (!edge.style || source_style == EBorderStyle::kHidden)
    return true;

  EBorderStyle edge_border_style =
      NGTableBorders::BorderStyle(edge.style.get(), edge.edge_side);
  if (edge_border_style == EBorderStyle::kHidden)
    return false;

  LayoutUnit edge_width =
      NGTableBorders::BorderWidth(edge.style.get(), edge.edge_side);
  if (source_width < edge_width)
    return false;
  if (source_width > edge_width)
    return true;
  return source_style > edge_border_style;
}

class ColBordersMarker {
  STACK_ALLOCATED();

 public:
  void VisitCol(const NGLayoutInputNode& column,
                wtf_size_t start_column_index,
                wtf_size_t span) {
    for (wtf_size_t i = 0; i < span; ++i) {
      wtf_size_t current_column_index = start_column_index + i;
      borders.MergeBorders(0, current_column_index, table_row_count, 1,
                           column.Style(), NGTableBorders::EdgeSource::kColumn,
                           box_order, table_writing_direction);
    }
  }
  void EnterColgroup(const NGLayoutInputNode& colgroup,
                     wtf_size_t start_column_index) {}
  void LeaveColgroup(const NGLayoutInputNode& colgroup,
                     wtf_size_t start_column_index,
                     wtf_size_t span,
                     bool has_children) {}
  ColBordersMarker(wtf_size_t table_row_count,
                   wtf_size_t box_order,
                   WritingDirectionMode table_writing_direction,
                   NGTableBorders& borders)
      : table_row_count(table_row_count),
        box_order(box_order),
        table_writing_direction(table_writing_direction),
        borders(borders) {}
  const wtf_size_t table_row_count;
  const wtf_size_t box_order;
  const WritingDirectionMode table_writing_direction;
  NGTableBorders& borders;
};

class ColgroupBordersMarker {
  STACK_ALLOCATED();

 public:
  void VisitCol(const NGLayoutInputNode& column,
                wtf_size_t start_column_index,
                wtf_size_t span) {}
  void EnterColgroup(const NGLayoutInputNode& colgroup,
                     wtf_size_t start_column_index) {}
  void LeaveColgroup(const NGLayoutInputNode& colgroup,
                     wtf_size_t start_column_index,
                     wtf_size_t span,
                     bool has_children) {
    borders.MergeBorders(0, start_column_index, table_row_count, span,
                         colgroup.Style(), NGTableBorders::EdgeSource::kColumn,
                         box_order, table_writing_direction);
  }
  ColgroupBordersMarker(wtf_size_t table_row_count,
                        wtf_size_t box_order,
                        WritingDirectionMode table_writing_direction,
                        NGTableBorders& borders)
      : table_row_count(table_row_count),
        box_order(box_order),
        table_writing_direction(table_writing_direction),
        borders(borders) {}
  const wtf_size_t table_row_count;
  const wtf_size_t box_order;
  const WritingDirectionMode table_writing_direction;
  NGTableBorders& borders;
};

}  // namespace

scoped_refptr<NGTableBorders> NGTableBorders::ComputeTableBorders(
    const NGBlockNode& table) {
  const ComputedStyle& table_style = table.Style();
  NGBoxStrut intrinsic_borders(LayoutUnit(table_style.BorderStartWidth()),
                               LayoutUnit(table_style.BorderEndWidth()),
                               LayoutUnit(table_style.BorderBeforeWidth()),
                               LayoutUnit(table_style.BorderAfterWidth()));
  scoped_refptr<NGTableBorders> table_borders =
      base::MakeRefCounted<NGTableBorders>(table_style, intrinsic_borders);

  if (table_style.BorderCollapse() != EBorderCollapse::kCollapse)
    return table_borders;

  NGTableGroupedChildren grouped_children(table);
  WritingDirectionMode table_writing_direction =
      table.Style().GetWritingDirection();

  wtf_size_t box_order = 0;
  wtf_size_t table_column_count =
      NGTableAlgorithmUtils::ComputeMaximumNonMergeableColumnCount(
          grouped_children.columns, table.Style().IsFixedTableLayout());
  wtf_size_t table_row_index = 0;
  // Mark cell borders.
  bool found_multispan_cells = false;
  for (const NGBlockNode section : grouped_children) {
    wtf_size_t section_start_row = table_row_index;
    NGColspanCellTabulator tabulator;
    for (NGBlockNode row = To<NGBlockNode>(section.FirstChild()); row;
         row = To<NGBlockNode>(row.NextSibling())) {
      tabulator.StartRow();
      for (NGBlockNode cell = To<NGBlockNode>(row.FirstChild()); cell;
           cell = To<NGBlockNode>(cell.NextSibling())) {
        tabulator.FindNextFreeColumn();
        wtf_size_t cell_colspan = cell.TableCellColspan();
        found_multispan_cells |=
            cell.TableCellRowspan() > 1 || cell_colspan > 1;
        // Rowspan has to be limited by section size. Since we do not know
        // section size, we have to rerun cell distribution with limited
        // rowspans.
        table_column_count = std::max(
            table_column_count, NGTableAlgorithmHelpers::ComputeMaxColumn(
                                    tabulator.CurrentColumn(), cell_colspan,
                                    table.Style().IsFixedTableLayout()));
        if (!found_multispan_cells) {
          table_borders->MergeBorders(
              table_row_index, tabulator.CurrentColumn(),
              cell.TableCellRowspan(), cell_colspan, cell.Style(),
              NGTableBorders::EdgeSource::kCell, ++box_order,
              table_writing_direction);
        }
        tabulator.ProcessCell(cell);
      }
      tabulator.EndRow();
      ++table_row_index;
    }
    table_borders->AddSection(section_start_row,
                              table_row_index - section_start_row);
  }

  table_borders->SetLastColumnIndex(table_column_count);
  wtf_size_t table_row_count = table_row_index;
  table_row_index = 0;

  // Mark cell borders again with limited rowspan.
  // If any cells have rowspan, need to redistribute cell borders.
  if (found_multispan_cells) {
    wtf_size_t section_index = 0;
    for (NGBlockNode section : grouped_children) {
      NGColspanCellTabulator tabulator;
      for (NGBlockNode row = To<NGBlockNode>(section.FirstChild()); row;
           row = To<NGBlockNode>(row.NextSibling())) {
        tabulator.StartRow();
        for (NGBlockNode cell = To<NGBlockNode>(row.FirstChild()); cell;
             cell = To<NGBlockNode>(cell.NextSibling())) {
          tabulator.FindNextFreeColumn();
          table_borders->MergeBorders(
              table_row_index, tabulator.CurrentColumn(),
              cell.TableCellRowspan(), cell.TableCellColspan(), cell.Style(),
              NGTableBorders::EdgeSource::kCell, ++box_order,
              table_writing_direction, section_index);
          tabulator.ProcessCell(cell);
        }
        tabulator.EndRow();
        ++table_row_index;
      }
      ++section_index;
    }
  }

  // Mark row borders.
  table_row_index = 0;
  for (NGBlockNode section : grouped_children) {
    for (NGBlockNode row = To<NGBlockNode>(section.FirstChild()); row;
         row = To<NGBlockNode>(row.NextSibling())) {
      table_borders->MergeBorders(table_row_index, 0, 1, table_column_count,
                                  row.Style(), NGTableBorders::EdgeSource::kRow,
                                  ++box_order, table_writing_direction);
      ++table_row_index;
    }
  }

  // Mark section borders.
  // It is tempting to traverse sections at the same time as rows,
  // but it would cause precedence errors.
  wtf_size_t section_index = 0;
  for (NGBlockNode section : grouped_children) {
    NGTableBorders::Section section_info =
        table_borders->GetSection(section_index);
    table_borders->MergeBorders(
        section_info.start_row, 0, section_info.row_count, table_column_count,
        section.Style(), NGTableBorders::EdgeSource::kSection, ++box_order,
        table_writing_direction);
    ++section_index;
  }

  // Mark column borders.
  // COL borders have precedence over COLGROUP borders.
  // We have to traverse COL first, then COLGROUP.
  ColBordersMarker col_borders_marker(table_row_count, ++box_order,
                                      table_writing_direction,
                                      *table_borders.get());
  VisitLayoutNGTableColumn(
      const_cast<Vector<NGBlockNode>&>(grouped_children.columns),
      table_column_count, &col_borders_marker);
  ColgroupBordersMarker colgroup_borders_marker(table_row_count, ++box_order,
                                                table_writing_direction,
                                                *table_borders.get());
  VisitLayoutNGTableColumn(
      const_cast<Vector<NGBlockNode>&>(grouped_children.columns),
      table_column_count, &colgroup_borders_marker);

  // Mark table borders.
  table_borders->MergeBorders(0, 0, table_row_count, table_column_count,
                              table_style, NGTableBorders::EdgeSource::kTable,
                              ++box_order, table_writing_direction);

  table_borders->ComputeCollapsedTableBorderPadding(table_row_count,
                                                    table_column_count);

  // https://github.com/w3c/csswg-drafts/issues/6230
  if (table_borders->collapsed_visual_inline_start_ !=
          table_borders->cached_table_border_->inline_start ||
      table_borders->collapsed_visual_inline_end_ !=
          table_borders->cached_table_border_->inline_end) {
    UseCounter::Count(table.GetDocument(),
                      WebFeature::kTableCollapsedBorderDifferentToVisual);
  }

  return table_borders;
}

NGTableBorders::NGTableBorders(const ComputedStyle& table_style,
                               const NGBoxStrut& table_border)
    : is_collapsed_(table_style.BorderCollapse() ==
                    EBorderCollapse::kCollapse) {
  if (!is_collapsed_) {
    cached_table_border_ = table_border;
  }
}

#if DCHECK_IS_ON()
String NGTableBorders::DumpEdges() {
  if (edges_per_row_ == 0)
    return "No edges";

  StringBuilder edge_string;
  wtf_size_t row_count = edges_.size() / edges_per_row_;
  for (wtf_size_t row = 0; row < row_count; ++row) {
    for (wtf_size_t i = 0; i < edges_per_row_; ++i) {
      const auto& edge = edges_[edges_per_row_ * row + i];
      if (edge.style) {
        switch (edge.edge_side) {
          case EdgeSide::kTop:
            edge_string.Append('-');
            break;
          case EdgeSide::kBottom:
            edge_string.Append('_');
            break;
          case EdgeSide::kLeft:
            edge_string.Append('[');
            break;
          case EdgeSide::kRight:
            edge_string.Append(']');
            break;
          case EdgeSide::kDoNotFill:
            edge_string.Append('?');
            break;
        }
      } else {  // no style.
        if (edge.edge_side == EdgeSide::kDoNotFill)
          edge_string.Append('X');
        else
          edge_string.Append('.');
      }
      if (i & 1)  // i is odd.
        edge_string.Append(' ');
    }
    edge_string.Append('\n');
  }
  return edge_string.ToString();
}

void NGTableBorders::ShowEdges() {
  LOG(INFO) << "\n" << DumpEdges().Utf8();
}

bool NGTableBorders::operator==(const NGTableBorders& other) const {
  // Compare by traversal, because we must call edge comparsion function.
  if (edges_.size() != other.edges_.size())
    return false;
  for (unsigned i = 0; i < edges_.size(); i++) {
    if (edges_[i].edge_side != other.edges_[i].edge_side)
      return false;
    if (edges_[i].box_order != other.edges_[i].box_order)
      return false;
  }
  return sections_ == other.sections_ &&
         edges_per_row_ == other.edges_per_row_ &&
         cached_table_border_ == other.cached_table_border_ &&
         collapsed_visual_inline_start_ ==
             other.collapsed_visual_inline_start_ &&
         collapsed_visual_inline_end_ == other.collapsed_visual_inline_end_ &&
         last_column_index_ == other.last_column_index_ &&
         is_collapsed_ == other.is_collapsed_;
}

#endif

NGBoxStrut NGTableBorders::GetCellBorders(wtf_size_t row,
                                          wtf_size_t column,
                                          wtf_size_t rowspan,
                                          wtf_size_t colspan) const {
  NGBoxStrut border_strut;
  if (edges_per_row_ == 0)
    return border_strut;
  DCHECK_EQ(edges_.size() % edges_per_row_, 0u);
  if (column * 2 >= edges_per_row_ || row >= edges_.size() / edges_per_row_)
    return border_strut;

  // Compute inline border widths.
  wtf_size_t first_inline_start_edge = row * edges_per_row_ + column * 2;
  wtf_size_t first_inline_end_edge = first_inline_start_edge + colspan * 2;
  for (wtf_size_t i = 0; i < rowspan; ++i) {
    wtf_size_t start_edge_index = first_inline_start_edge + i * edges_per_row_;
    border_strut.inline_start =
        std::max(border_strut.inline_start, CanPaint(start_edge_index)
                                                ? BorderWidth(start_edge_index)
                                                : LayoutUnit());
    if (start_edge_index >= edges_.size())
      break;
    wtf_size_t end_edge_index = first_inline_end_edge + i * edges_per_row_;
    border_strut.inline_end = std::max(
        border_strut.inline_end,
        CanPaint(end_edge_index) ? BorderWidth(end_edge_index) : LayoutUnit());
  }
  // Compute block border widths.
  wtf_size_t start_edge_column_index = column * 2 + 1;
  for (wtf_size_t i = 0; i < colspan; ++i) {
    wtf_size_t current_column_index = start_edge_column_index + i * 2;
    if (current_column_index >= edges_per_row_)
      break;
    wtf_size_t start_edge_index = row * edges_per_row_ + current_column_index;
    border_strut.block_start =
        std::max(border_strut.block_start, CanPaint(start_edge_index)
                                               ? BorderWidth(start_edge_index)
                                               : LayoutUnit());
    wtf_size_t end_edge_index = start_edge_index + rowspan * edges_per_row_;
    border_strut.block_end = std::max(
        border_strut.block_end,
        CanPaint(end_edge_index) ? BorderWidth(end_edge_index) : LayoutUnit());
  }
  DCHECK(is_collapsed_);
  // If borders are not divisible by 2, two half borders will not add up
  // to original border size (off by 1/64px). This is ok, because
  // pixel snapping will round to physical pixels.
  border_strut.block_start /= 2;
  border_strut.block_end /= 2;
  border_strut.inline_start /= 2;
  border_strut.inline_end /= 2;
  return border_strut;
}

void NGTableBorders::ComputeCollapsedTableBorderPadding(
    wtf_size_t table_row_count,
    wtf_size_t table_column_count) {
  DCHECK(is_collapsed_);
  // https://www.w3.org/TR/CSS2/tables.html#collapsing-borders
  // block[start|end] borders are computed by traversing all the edges.
  // inline[start|end] borders are computed by looking at first/last edge.
  if (edges_per_row_ == 0) {
    cached_table_border_ = NGBoxStrut();
    return;
  }
  DCHECK_GE((table_column_count + 1) * 2, edges_per_row_);
  // We still need visual border rect.
  NGBoxStrut borders =
      GetCellBorders(0, 0, table_row_count, table_column_count);
  collapsed_visual_inline_start_ = borders.inline_start;
  collapsed_visual_inline_end_ = borders.inline_end;
  wtf_size_t inline_start_edge = 0;
  wtf_size_t inline_end_edge = 2 * table_column_count;
  borders.inline_start = CanPaint(inline_start_edge)
                             ? BorderWidth(inline_start_edge) / 2
                             : LayoutUnit();
  borders.inline_end = CanPaint(inline_end_edge)
                           ? BorderWidth(inline_end_edge) / 2
                           : LayoutUnit();
  cached_table_border_ = borders;
}

NGBoxStrut NGTableBorders::GetCollapsedBorderVisualSizeDiff() const {
  if (!is_collapsed_)
    return NGBoxStrut();
  // Inline sizes expand by difference between visual and
  // layout border width.
  NGBoxStrut visual_diff;
  visual_diff.inline_start =
      collapsed_visual_inline_start_ - cached_table_border_->inline_start;
  visual_diff.inline_end =
      collapsed_visual_inline_end_ - cached_table_border_->inline_end;
  return visual_diff;
}

NGBoxStrut NGTableBorders::CellBorder(
    const NGBlockNode& cell,
    wtf_size_t row,
    wtf_size_t column,
    wtf_size_t section,
    WritingDirectionMode table_writing_direction) const {
  if (is_collapsed_) {
    return GetCellBorders(row, column,
                          ClampRowspan(section, row, cell.TableCellRowspan()),
                          ClampColspan(column, cell.TableCellColspan()));
  }
  return ComputeBorders(
      NGConstraintSpaceBuilder(table_writing_direction.GetWritingMode(),
                               table_writing_direction, /* is_new_fc */ false)
          .ToConstraintSpace(),
      cell);
}

// As we are determining the intrinsic size of the table at this stage,
// %-padding resolves against an indefinite size.
NGBoxStrut NGTableBorders::CellPaddingForMeasure(
    const ComputedStyle& cell_style,
    WritingDirectionMode table_writing_direction) const {
  if (!cell_style.MayHavePadding())
    return NGBoxStrut();
  return ComputePadding(
      NGConstraintSpaceBuilder(table_writing_direction.GetWritingMode(),
                               table_writing_direction,
                               /* is_new_fc */ false)
          .ToConstraintSpace(),
      cell_style);
}

void NGTableBorders::MergeBorders(wtf_size_t cell_start_row,
                                  wtf_size_t cell_start_column,
                                  wtf_size_t rowspan,
                                  wtf_size_t colspan,
                                  const ComputedStyle& source_style,
                                  EdgeSource source,
                                  const wtf_size_t box_order,
                                  WritingDirectionMode table_writing_direction,
                                  wtf_size_t section_index) {
  DCHECK(is_collapsed_);
  // Can be 0 in empty table parts.
  if (rowspan == 0 || colspan == 0)
    return;

  wtf_size_t clamped_colspan = ClampColspan(cell_start_column, colspan);
  wtf_size_t clamped_rowspan =
      source == EdgeSource::kCell
          ? ClampRowspan(section_index, cell_start_row, rowspan)
          : rowspan;
  bool mark_inner_borders = source == EdgeSource::kCell &&
                            (clamped_rowspan > 1 || clamped_colspan > 1);

  if (mark_inner_borders) {
    EnsureCellColumnFits(cell_start_column + clamped_colspan - 1);
    EnsureCellRowFits(cell_start_row + clamped_rowspan - 1);
  } else {
    PhysicalToLogical<EBorderStyle> border_style(
        table_writing_direction, source_style.BorderTopStyle(),
        source_style.BorderRightStyle(), source_style.BorderBottomStyle(),
        source_style.BorderLeftStyle());
    if (border_style.InlineStart() == EBorderStyle::kNone &&
        border_style.InlineEnd() == EBorderStyle::kNone &&
        border_style.BlockStart() == EBorderStyle::kNone &&
        border_style.BlockEnd() == EBorderStyle::kNone) {
      return;
    }
    // Only need to ensure edges that will be assigned exist.
    if (border_style.InlineEnd() == EBorderStyle::kNone &&
        border_style.BlockStart() == EBorderStyle::kNone &&
        border_style.BlockEnd() == EBorderStyle::kNone) {
      EnsureCellColumnFits(cell_start_column);
    } else {
      EnsureCellColumnFits(cell_start_column + clamped_colspan - 1);
    }
    if (border_style.InlineStart() == EBorderStyle::kNone &&
        border_style.InlineEnd() == EBorderStyle::kNone &&
        border_style.BlockEnd() == EBorderStyle::kNone) {
      EnsureCellRowFits(cell_start_row);
    } else {
      EnsureCellRowFits(cell_start_row + clamped_rowspan - 1);
    }
  }

  PhysicalToLogical<EdgeSide> edge_side(table_writing_direction, EdgeSide::kTop,
                                        EdgeSide::kRight, EdgeSide::kBottom,
                                        EdgeSide::kLeft);
  MergeRowAxisBorder(cell_start_row, cell_start_column, clamped_colspan,
                     source_style, box_order, edge_side.BlockStart());
  MergeRowAxisBorder(cell_start_row + clamped_rowspan, cell_start_column,
                     clamped_colspan, source_style, box_order,
                     edge_side.BlockEnd());
  MergeColumnAxisBorder(cell_start_row, cell_start_column, clamped_rowspan,
                        source_style, box_order, edge_side.InlineStart());
  MergeColumnAxisBorder(cell_start_row, cell_start_column + clamped_colspan,
                        clamped_rowspan, source_style, box_order,
                        edge_side.InlineEnd());
  if (mark_inner_borders) {
    MarkInnerBordersAsDoNotFill(cell_start_row, cell_start_column,
                                clamped_rowspan, clamped_colspan);
  }
}

void NGTableBorders::MergeRowAxisBorder(wtf_size_t start_row,
                                        wtf_size_t start_column,
                                        wtf_size_t colspan,
                                        const ComputedStyle& source_style,
                                        const wtf_size_t box_order,
                                        EdgeSide physical_side) {
  EBorderStyle source_border_style = BorderStyle(&source_style, physical_side);
  if (source_border_style == EBorderStyle::kNone)
    return;
  LayoutUnit source_border_width = BorderWidth(&source_style, physical_side);
  wtf_size_t start_edge = edges_per_row_ * start_row + start_column * 2 + 1;
  wtf_size_t end_edge = start_edge + colspan * 2;
  for (wtf_size_t current_edge = start_edge; current_edge < end_edge;
       current_edge += 2) {
    // https://www.w3.org/TR/css-tables-3/#border-specificity
    if (IsSourceMoreSpecificThanEdge(source_border_style, source_border_width,
                                     edges_[current_edge])) {
      edges_[current_edge].style = &source_style;
      edges_[current_edge].edge_side = physical_side;
      edges_[current_edge].box_order = box_order;
    }
  }
}

void NGTableBorders::MergeColumnAxisBorder(wtf_size_t start_row,
                                           wtf_size_t start_column,
                                           wtf_size_t rowspan,
                                           const ComputedStyle& source_style,
                                           const wtf_size_t box_order,
                                           EdgeSide physical_side) {
  EBorderStyle source_border_style = BorderStyle(&source_style, physical_side);
  if (source_border_style == EBorderStyle::kNone)
    return;
  LayoutUnit source_border_width = BorderWidth(&source_style, physical_side);
  wtf_size_t start_edge = edges_per_row_ * start_row + start_column * 2;
  wtf_size_t end_edge = start_edge + (rowspan * edges_per_row_);
  for (wtf_size_t current_edge = start_edge; current_edge < end_edge;
       current_edge += edges_per_row_) {
    // https://www.w3.org/TR/css-tables-3/#border-specificity
    if (IsSourceMoreSpecificThanEdge(source_border_style, source_border_width,
                                     edges_[current_edge])) {
      edges_[current_edge].style = &source_style;
      edges_[current_edge].edge_side = physical_side;
      edges_[current_edge].box_order = box_order;
    }
  }
}

// Rowspanned/colspanned cells need to mark inner edges as do-not-fill to
// prevent tables parts from drawing into them.
void NGTableBorders::MarkInnerBordersAsDoNotFill(wtf_size_t start_row,
                                                 wtf_size_t start_column,
                                                 wtf_size_t rowspan,
                                                 wtf_size_t colspan) {
  // Mark block axis edges.
  wtf_size_t start_edge = (start_column * 2) + 2;
  wtf_size_t end_edge = start_edge + (colspan - 1) * 2;
  for (wtf_size_t row = start_row;
       row < start_row + rowspan && start_edge != end_edge; ++row) {
    wtf_size_t row_offset = row * edges_per_row_;
    for (wtf_size_t edge = row_offset + start_edge;
         edge < row_offset + end_edge; edge += 2) {
      // DCHECK(!edges_[edge].style) is true in most tables. But,
      // when two cells overlap each other, (really an error)
      // style might already be assigned.
      if (!edges_[edge].style)
        edges_[edge].edge_side = EdgeSide::kDoNotFill;
    }
  }
  // Mark inline axis edges.
  start_edge = start_column * 2 + 1;
  end_edge = start_edge + colspan * 2;
  for (wtf_size_t row = start_row + 1; row < start_row + rowspan; ++row) {
    wtf_size_t row_offset = row * edges_per_row_;
    for (wtf_size_t edge = row_offset + start_edge;
         edge < row_offset + end_edge; edge += 2) {
      if (!edges_[edge].style)
        edges_[edge].edge_side = EdgeSide::kDoNotFill;
    }
  }
}

// Inline edges are edges between columns.
void NGTableBorders::EnsureCellColumnFits(wtf_size_t cell_column) {
  wtf_size_t desired_edges_per_row = (cell_column + 2) * 2;
  if (desired_edges_per_row <= edges_per_row_)
    return;

  // When number of columns changes, all rows have to be resized.
  // Edges must be copied to new positions. This can be expensive.
  // Most tables do not change number of columns after the 1st row.
  wtf_size_t row_count =
      edges_per_row_ == 0 ? 1 : edges_.size() / edges_per_row_;
  edges_.resize(row_count * desired_edges_per_row);
  for (wtf_size_t row_index = row_count - 1; row_index > 0; --row_index) {
    wtf_size_t new_edge = desired_edges_per_row - 1;
    bool done = false;
    // while loop is necessary to count down with unsigned.
    do {
      wtf_size_t new_edge_index = row_index * desired_edges_per_row + new_edge;
      if (new_edge < edges_per_row_) {
        wtf_size_t old_edge_index = row_index * edges_per_row_ + new_edge;
        DCHECK_LT(row_index * edges_per_row_ + new_edge, edges_.size());
        edges_[new_edge_index] = edges_[old_edge_index];
      } else {
        edges_[new_edge_index].style = nullptr;
        edges_[new_edge_index].edge_side = EdgeSide::kTop;
      }
      done = new_edge-- == 0;
    } while (!done);
  }
  // Previous loop does not clear out new cells in the first row.
  for (wtf_size_t edge_index = edges_per_row_;
       edge_index < desired_edges_per_row; ++edge_index) {
    edges_[edge_index].style = nullptr;
    edges_[edge_index].edge_side = EdgeSide::kTop;
  }
  edges_per_row_ = desired_edges_per_row;
}

// Block edges are edges between rows.
void NGTableBorders::EnsureCellRowFits(wtf_size_t cell_row) {
  DCHECK_NE(edges_per_row_, 0u);
  wtf_size_t current_block_edges = edges_.size() / edges_per_row_;
  wtf_size_t desired_block_edges = cell_row + 2;
  if (desired_block_edges <= current_block_edges)
    return;
  edges_.resize(desired_block_edges * edges_per_row_);
}

}  // namespace blink


text:
namespace base {
namespace test {

namespace {

bool g_add_gtest_failure_on_timeout = false;

std::string TimeoutMessage(const RepeatingCallback<std::string()>& get_log) {
  std::string message = "RunLoop::Run() timed out.";
  if (get_log)
    StrAppend(&message, {"\n", get_log.Run()});
  return message;
}

}  // namespace

ScopedRunLoopTimeout::ScopedRunLoopTimeout(const Location& from_here,
                                           TimeDelta timeout)
    : ScopedRunLoopTimeout(from_here, timeout, NullCallback()) {}

ScopedRunLoopTimeout::~ScopedRunLoopTimeout() {
  RunLoop::SetTimeoutForCurrentThread(nested_timeout_);
}

ScopedRunLoopTimeout::ScopedRunLoopTimeout(
    const Location& from_here,
    TimeDelta timeout,
    RepeatingCallback<std::string()> on_timeout_log)
    : nested_timeout_(RunLoop::GetTimeoutForCurrentThread()) {
  DCHECK_GT(timeout, TimeDelta());
  run_timeout_.timeout = timeout;

  if (g_add_gtest_failure_on_timeout) {
    run_timeout_.on_timeout = BindRepeating(
        [](const Location& from_here,
           RepeatingCallback<std::string()> on_timeout_log) {
          GTEST_FAIL_AT(from_here.file_name(), from_here.line_number())
              << TimeoutMessage(on_timeout_log);
        },
        from_here, std::move(on_timeout_log));
  } else {
    run_timeout_.on_timeout = BindRepeating(
        [](const Location& from_here,
           RepeatingCallback<std::string()> on_timeout_log) {
          std::string message = TimeoutMessage(on_timeout_log);
          logging::LogMessage(from_here.file_name(), from_here.line_number(),
                              message.data());
        },
        from_here, std::move(on_timeout_log));
  }

  RunLoop::SetTimeoutForCurrentThread(&run_timeout_);
}

// static
bool ScopedRunLoopTimeout::ExistsForCurrentThread() {
  return RunLoop::GetTimeoutForCurrentThread() != nullptr;
}

// static
void ScopedRunLoopTimeout::SetAddGTestFailureOnTimeout() {
  g_add_gtest_failure_on_timeout = true;
}

// static
const RunLoop::RunLoopTimeout*
ScopedRunLoopTimeout::GetTimeoutForCurrentThread() {
  return RunLoop::GetTimeoutForCurrentThread();
}

ScopedDisableRunLoopTimeout::ScopedDisableRunLoopTimeout()
    : nested_timeout_(RunLoop::GetTimeoutForCurrentThread()) {
  RunLoop::SetTimeoutForCurrentThread(nullptr);
}

ScopedDisableRunLoopTimeout::~ScopedDisableRunLoopTimeout() {
  RunLoop::SetTimeoutForCurrentThread(nested_timeout_);
}

}  // namespace test
}  // namespace base

redpajama_set_name: RedPajamaGithub


text:
<!DOCTYPE html>

<title>Lab Guide :: Serverless Data Processing on AWS</title>
<meta charset='utf-8'>
<meta content='width=device-width, initial-scale=1, shrink-to-fit=no' name='viewport'>
<link href='https://a0.awsstatic.com/main/images/site/fav/favicon.ico' rel='icon' type='image/ico'>
<link crossorigin='anonymous' href='https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css' integrity='sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M' rel='stylesheet'>
<link href='css/styles.css' rel='stylesheet'>
<link href='css/syntax.css' rel='stylesheet'>

Lab Guide
Unicorn Dashboard

Serverless Data Processing on AWS

Streaming Aggregation

In this module, you'll create an Amazon Kinesis Data Analytics application to aggregate sensor data from the unicorn fleet in real-time. The application will read from the Amazon Kinesis stream, calculate the total distance traveled and minimum and maximum health and magic points for each unicorn currently on a Wild Ryde and output these aggregated statistics to an Amazon Kinesis stream every minute.

Overview

The architecture for this module involves an Amazon Kinesis Data Analytics application, source and destination Amazon Kinesis streams, and the producer and consumer command-line clients.

The Amazon Kinesis Data Analytics application processes data from the source Amazon Kinesis stream that we created in the previous module and aggregates it on a per-minute basis. Each minute, the application will emit data including the total distance traveled in the last minute as well as the minimum and maximum readings from health and magic points for each unicorn in our fleet. These data points will be sent to a destination Amazon Kinesis stream for processing by other components in our system.

Implementation

1. Create an Amazon Kinesis stream

Use the Amazon Kinesis Data Streams console to create a new stream named wildrydes-summary with 1 shard.

✅ Step-by-step Instructions

Go to the AWS Management Console, click Services then select Kinesis under Analytics.

Click Get started if prompted with an introductory screen.

Click Create data stream.

Enter wildrydes-summary into Kinesis stream name and 1 into Number of shards, then click Create Kinesis stream.

Within 60 seconds, your Kinesis stream will be ACTIVE and ready to store real-time streaming data.

2. Create an Amazon Kinesis Data Analytics application

Build an Amazon Kinesis Data Analytics application which reads from the wildrydes stream built in the previous module and emits a JSON object with the following attributes each minute:

Name
Unicorn name

StatusTime
ROWTIME provided by Amazon Kinesis Data Analytics

Distance
The sum of distance traveled by the unicorn

MinMagicPoints
The minimum data point of the MagicPoints attribute

MaxMagicPoints
The maximum data point of the MagicPoints attribute

MinHealthPoints
The minimum data point of the HealthPoints attribute

MaxHealthPoints
The maximum data point of the HealthPoints attribute

Set the destination stream of the application to wildrydes-summary.

✅ Step-by-step directions

Switch to the tab where you have your Cloud9 environment opened.

Run the producer to start emiting sensor data to the stream.

./producer

<button class="btn btn-outline-primary copy">
Copy to Clipboard
</button>

Activately producing sensor data while we're building our application will allow Amazon Kinesis Data Analytics to auto-detect our schema.

Go to the AWS Management Console, click Services then select Kinesis under Analytics.

Click Create analytics application.

Enter wildrydes into Application name and then click Create application.

Click Connect streaming data.

Select wildrydes from Kinesis stream.

Scroll down and click Discover schema, wait a moment, and ensure the schema was properly auto-discovered.

Ensure that the auto-discovered schema includes:

Column
Data Type

Distance
DOUBLE

HealthPoints
INTEGER

Latitude
DOUBLE

Longitude
DOUBLE

MagicPoints
INTEGER

Name
VARCHAR(16)

StatusTime
TIMESTAMP

Click Save and continue.

Click Go to SQL editor. This will open up an interactive query session where we can build a query on top of our real-time Amazon Kinesis stream.

Click Yes, start application. It will take 30 - 90 seconds for your application to start.

Copy and paste the following SQL query into the SQL editor:

CREATE OR REPLACE STREAM "DESTINATION_SQL_STREAM" (
  "Name"                VARCHAR(16),
  "StatusTime"          TIMESTAMP,
  "Distance"            SMALLINT,
  "MinMagicPoints"      SMALLINT,
  "MaxMagicPoints"      SMALLINT,
  "MinHealthPoints"     SMALLINT,
  "MaxHealthPoints"     SMALLINT
);

CREATE OR REPLACE PUMP "STREAM_PUMP" AS
  INSERT INTO "DESTINATION_SQL_STREAM"
    SELECT STREAM "Name", "ROWTIME", SUM("Distance"), MIN("MagicPoints"),
                  MAX("MagicPoints"), MIN("HealthPoints"), MAX("HealthPoints")
    FROM "SOURCE_SQL_STREAM_001"
    GROUP BY FLOOR("SOURCE_SQL_STREAM_001"."ROWTIME" TO MINUTE), "Name";

<button class="btn btn-outline-primary copy">
Copy to Clipboard
</button>

Click Save and run SQL. Each minute, you will see rows arrive containing the aggregated data. Wait for the rows to arrive.

Click the Close link.

Click Connect to a destination.

Select wildrydes-summary from Kinesis stream.

Select DESTINATION_SQL_STREAM from In-application stream name.

Click Save and continue.

3. Read messages from the stream

Use the command line consumer to view messages from the Kinesis stream to see the aggregated data being sent every minute.

✅ Step-by-step directions

Switch to the tab where you have your Cloud9 environment opened.

Run the consumer to start reading sensor data from the stream.

./consumer -stream wildrydes-summary

<button class="btn btn-outline-primary copy">
Copy to Clipboard
</button>

The consumer will print the messages being sent by the Kinesis Data Analytics application every minute:

{
  "Name": "Shadowfax",
  "StatusTime": "2018-03-18 03:20:00.000",
  "Distance": 362,
  "MinMagicPoints": 170,
  "MaxMagicPoints": 172,
  "MinHealthPoints": 146,
  "MaxHealthPoints": 149
}

4. Experiment with the producer

Stop and start the producer while watching the dashboard and the consumer. Start multiple producers with different unicorn names.

✅ Step-by-step directions

Switch to the tab where you have your Cloud9 environment opened.

Stop the producer by pressing Control + C and notice the messages stop.

Start the producer again and notice the messages resume.

Hit the (+) button and click New Terminal to open a new terminal tab.

Start another instance of the producer in the new tab. Provide a specific unicorn name and notice data points for both unicorns in consumer's output:

./producer -name Bucephalus

<button class="btn btn-outline-primary copy">
Copy to Clipboard
</button>

Verify you see multiple unicorns in the output:

{
    "Name": "Shadowfax",
    "StatusTime": "2018-03-18 03:20:00.000",
    "Distance": 362,
    "MinMagicPoints": 170,
    "MaxMagicPoints": 172,
    "MinHealthPoints": 146,
    "MaxHealthPoints": 149
}
{
    "Name": "Bucephalus",
    "StatusTime": "2018-03-18 03:20:00.000",
    "Distance": 1773,
    "MinMagicPoints": 140,
    "MaxMagicPoints": 148,
    "MinHealthPoints": 132,
    "MaxHealthPoints": 138
}

⭐ Recap

🔑 Amazon Kinesis Data Analytics enables you to query streaming data or build entire streaming applications using SQL, so that you can gain actionable insights and respond to your business and customer needs promptly.

🔧 In this module, you've created a Kinesis Data Analytics application that reads from the Kinesis stream of unicorn data and emits a summary row each minute.

Next

✅ Proceed to the next module, Stream Processing, wherein you'll store the summary data from the Kinesis Data Analytics application in an Amazon DynamoDB table.

Contents

Welcome

Setup

Modules

Real-time Data Streaming

Stream Aggregation

Stream Processing

Data Lake

Extra Credit

Clean Up

<textarea id='buffer'></textarea>


text:
<!DOCTYPE html>

		<title>three.js webgl - materials - EXR texture loader</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">

			three.js - webgl EXR texture loader example


text:
package io.indexr.segment;

import java.io.IOException;

import io.indexr.segment.storage.ColumnNode;

/**
 * An info segment contains basic info of a real segment.
 */
public interface InfoSegment {

    int version();

    SegmentMode mode();

    /**
     * Name of the segment. Unique in the whole system.
     */
    String name();

    /**
     * Schema of the segment.
     */
    SegmentSchema schema();

    /**
     * Row count.
     */
    long rowCount();

    /**
     * Get the pack count of this segment, return 0 if {@link #isColumned()} is false.
     */
    default int packCount() {
        return 0;
    }

    /**
     * Indicate whether this segment is column based or not.
     */
    default boolean isColumned() {
        return false;
    }

    /**
     * Get the basic predicate info of one column.
     */
    default ColumnNode columnNode(int colId) throws IOException {
        return null;
    }

    /**
     * It is a realtime segment or not.
     */
    default boolean isRealtime() {
        return false;
    }
}


text:
package com.google.gdata.data.media.mediarss;

import com.google.gdata.data.AttributeGenerator;
import com.google.gdata.data.AttributeHelper;
import com.google.gdata.data.ExtensionDescription;
import com.google.gdata.util.ParseException;

/**
 * {@code <media:copyright>}.
 *
 * See description on
 * http://search.yahoo.com/mrss.
 *
 *
 */
@ExtensionDescription.Default(
    nsAlias = MediaRssNamespace.PREFIX,
    nsUri = MediaRssNamespace.URI,
    localName = "copyright")
public class MediaCopyright extends AbstractElementWithContent {
  private String url;

  public String getUrl() {
    return url;
  }

  public void setUrl(String url) {
    this.url = url;
  }

  @Override
  protected void putAttributes(AttributeGenerator generator) {
    super.putAttributes(generator);
    generator.put("url", url);
  }

  @Override
  protected void consumeAttributes(AttributeHelper attrsHelper)
      throws ParseException {
    super.consumeAttributes(attrsHelper);
    url = attrsHelper.consume("url", false);
  }
}


text:
package cc.kenai.meicall;

import org.json.JSONException;
import org.json.JSONObject;

import com.kenai.function.message.XLog;

import android.app.Fragment;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import cc.kenai.common.sharedpreferences.SharedPreferencesHelper;
import cc.kenai.meicall.call.config.Configs_SharedPreference;
import cc.kenai.meicall.call.config.VoipApi;
import cc.kenai.meicall.call.utils.HttpHelper;
import cc.kenai.meicall.call.utils.UserInfoUtil;
import cc.kenai.meicall.call.utils.YuntongxunRegistUtil;

public class ExpenseFragment extends Fragment {
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		super.onCreateView(inflater, container, savedInstanceState);
		return inflater.inflate(R.layout.meicall_expense_layout, container,
				false);
	}

	TextView tx1;
	SharedPreferencesHelper shareHelper;

	@Override
	public void onViewCreated(View view, Bundle savedInstanceState) {
		super.onViewCreated(view, savedInstanceState);
		tx1 = (TextView) getView().findViewById(R.id.expense_main);

		shareHelper = new SharedPreferencesHelper(getActivity(),
				Configs_SharedPreference.CACHE) {

			@Override
			public void onSharedPreferenceChanged(
					SharedPreferences sharedPreferences, String key) {
				if (key.equals(UserInfoUtil.Settings_BaiduInfo)) {
					YuntongxunRegistUtil.regist(getActivity());
				}
				updateInformation();
			}
		};
		shareHelper.registerListener(getActivity());

		final Long cache=shareHelper.myShared.getLong("expense_time", 0);
		final Long now =System.currentTimeMillis();
		if((now-cache>24*60*60*1000)){
			XLog.xLog("test","update");
			new Thread(new Runnable() {

				@Override
				public void run() {
					HttpHelper hp=new HttpHelper();
					String response=hp.getHtml(VoipApi.URIHEAD+"expense");
					if(response!=null&&response.length()>5){
						try {
							JSONObject json=new JSONObject(response);
							String p2p=json.getString("p2p");
							String p2l=json.getString("p2l");
							String callback=json.getString("callback");
							response="云呼叫:需要双方安装本软件,需要网络支持。 全国"+ p2p+"分/分钟\n\n" +
				                    "网络呼叫:需要网络支持。 全国"+ p2l+"分/分钟\n\n" +
				                    "回拨呼叫:仅初始化时需要网络支持。 全国"+ callback+"分/分钟";
						} catch (JSONException e) {
							return;
						}

						shareHelper.putLong("expense_time", now);
					    shareHelper.putString("expense_string", response);
					}
				}
			}).start();
		}else{
			XLog.xLog("test","not update");
		}
		final String s=shareHelper.myShared.getString("expense_string", "");
		tx1.setText(s);
		updateInformation();

	}

	@Override
	public void onDestroyView() {
		shareHelper.unregisterListener(getActivity());
		super.onDestroyView();
	}

	private final void updateInformation() {
		getActivity().runOnUiThread(new Runnable() {
			@Override
			public void run() {
				final String s=shareHelper.myShared.getString("expense_string", "");
				tx1.setText(s);
			}
		});
	}

}


text:
package aec.hackathon.munich.forgelivescan.meshbuilder;

import com.google.atap.tango.mesh.TangoMesh;

import android.opengl.GLES20;

/**
 * Tango Mesh Data Representation.
 */
public class MeshSegment {

    // The service will always pass 4 bytes floats.
    private static final int SIZE_OF_FLOAT = 4;
    // The service will always pass 4 bytes integers.
    private static final int SIZE_OF_INT = 4;

    public int vertexBufferId;
    public int indexBufferId;
    public int colorBufferId;
    public int numFaces;

    /**
     * Generates an internal Mesh representation. It also allocates the needed hardware buffers to
     * store the data.
     *
     */
    public MeshSegment() {
        loadBuffers();
    }

    private void loadBuffers() {
        final int buffers[] = new int[3];
        GLES20.glGenBuffers(3, buffers, 0);
        this.vertexBufferId = buffers[0];
        this.indexBufferId = buffers[1];
        this.colorBufferId = buffers[2];
    }

    /**
     * Updates the mesh buffers with the new data.
     *
     * @param tangoMesh
     */
    public void update(TangoMesh tangoMesh) {

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, this.vertexBufferId);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,
                tangoMesh.vertices.capacity() * SIZE_OF_FLOAT,
                tangoMesh.vertices, GLES20.GL_DYNAMIC_DRAW);

        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, this.colorBufferId);
        GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,
                tangoMesh.colors.capacity(),
                tangoMesh.colors, GLES20.GL_DYNAMIC_DRAW);
        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, this.indexBufferId);
        GLES20.glBufferData(GLES20.GL_ELEMENT_ARRAY_BUFFER,
                tangoMesh.faces.capacity() * SIZE_OF_INT,
                tangoMesh.faces, GLES20.GL_DYNAMIC_DRAW);

        GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);
        this.numFaces = tangoMesh.numFaces;
    }
}


text:
import Promise = require('bluebird');

Promise.cast(8).then(x => console.log(x.toExponential()));

function delayer(time: number) {
    var d = Promise.defer<void>();
    setTimeout(_ => d.resolve, time);
    return d.promise;

}

delayer(100).then(function (val) { console.log('Hello, World!') });

Promise.delay(1000).then(_ => Promise.delay(1000));

Promise.delay(Promise.cast(8), 1000).then(x => x.toExponential());
Promise.delay(Promise.cast("asdf"), 1000).then(x => x.length);

var eventualAdd = Promise.method((a?: number, b?: number) => Promise.cast(a + b));

eventualAdd(1, 2).then(x => x.toExponential());

var eventualAdd2 = Promise.method((a?: number, b?: number) => a + b);

eventualAdd2(1, 2).then(x => x.toExponential());

var eventually = function (val:number) {
    //return Promise.cast(val);
    return Promise.delay<number>(1000).then(_ => val);
};

//var x:Promise<number[]> = Promise.all([1, 2, 3].map(eventually));
var x = Promise.all([1, 2, 3].map(eventually));

var y = x.then(a => a.map(x => x.toExponential()));

Promise.all([
    eventually(10),
    eventually(20)
]).spread(function (x, y) {
    console.log(x.toExponential(), y.toExponential());
    return 10;
}).then(function(val) {
    return val.toExponential()
}).done();

var promiseArray = [Promise.cast(1), Promise.cast(2), Promise.cast(3)]

var qPromiseArray = promiseArray.map(p => Promise.cast<number>(p));

var myNums: any[] = [2, 3, Promise.cast(4), 5, Promise.cast(6), Promise.cast(7)];

Promise.all(promiseArray).then(nums => nums.map(num => num.toPrecision(2)).join(','));

Promise.all<number>(myNums).then(nums => nums.map(Math.round));

declare function saveToDisk(): Promise<any>;
declare function saveToCloud(): Promise<any>;

Promise.settle([saveToDisk(), saveToCloud()])
    .spread(function (disk?, cloud?) {
        console.log(
            disk.isFulfilled(),
            disk.isRejected(),
            disk.isPending(),
            disk.value(),
            disk.error());
        return 10;
    }).then(function(a) {
        console.log(a.toExponential());
    }).done();

var xx = new Promise<number>((resolve, reject) => {
    resolve(5);
});
xx.inspect().value().toExponential();


text:
/**
 * live load to edit
 */
test_liveloadToEdit = function() {
    _clearServerData();
    _injectData();
    SlideshowState.prototype.unloadToStore(Slideshow.findOne({})._id);
    SlideshowState.prototype.loadToEdit(Slideshow.findOne({})._id);
    //TODO verifier que les connlecions sont vide et que slideshow est plein
}


text:
using FileHelpers.Detection;
using FileHelpers.Dynamic;
using NUnit.Framework;

namespace FileHelpers.Tests.Detector
{
    [TestFixture]
    public class BasicDetection
    {
        #region "  Asserts  "

        private void AssertDelimitedFormat(string file, string delimiter, int fields, int confidence, int numFormats)
        {
            var detector = new SmartFormatDetector();
            RecordFormatInfo[] formats;

            detector.MaxSampleLines = 10;
            formats = detector.DetectFileFormat(file);
            AssertFormat(formats, delimiter, fields, confidence, numFormats);

            detector.MaxSampleLines = 20;
            formats = detector.DetectFileFormat(file);
            AssertFormat(formats, delimiter, fields, confidence, numFormats);

            detector.MaxSampleLines = 50;
            formats = detector.DetectFileFormat(file);
            AssertFormat(formats, delimiter, fields, confidence, numFormats);

            detector.MaxSampleLines = 100;
            formats = detector.DetectFileFormat(file);
            AssertFormat(formats, delimiter, fields, confidence, numFormats);
        }

        private void AssertFormat(RecordFormatInfo[] formats,
            string delimiter,
            int fields,
            int confidence,
            int numFormats)
        {
            if (numFormats > 0)
                Assert.AreEqual(numFormats, formats.Length);
            else
                Assert.IsTrue(formats.Length > 0);

            if (confidence > 0)
                Assert.IsTrue(formats[0].Confidence >= confidence);

            Assert.IsTrue(formats[0].ClassBuilder is DelimitedClassBuilder);
            Assert.AreEqual(delimiter, ((DelimitedClassBuilder) formats[0].ClassBuilder).Delimiter);
            Assert.AreEqual(fields, formats[0].ClassBuilder.FieldCount);
        }

        #endregion

        [Test]
        public void DelimitedTab()
        {
            AssertDelimitedFormat(FileTest.Detection.CustomersTab.Path, "\t", 7, 100, 1);
        }

        [Test]
        public void DelimitedSemiColon()
        {
            AssertDelimitedFormat(FileTest.Detection.CustomersSemiColon.Path, ";", 7, 100, 1);
        }

        [Test]
        public void DelimitedComma()
        {
            AssertDelimitedFormat(FileTest.Detection.CustomersComma.Path, ",", 7, 100, 1);
        }

        [Test]
        public void DelimitedMedium()
        {
            AssertDelimitedFormat(FileTest.Detection.DelimitedMedium.Path, "\t", 41, -1, 1);
        }

        [Test]
        public void FixedLength()
        {
            var detector = new SmartFormatDetector();
            var formats = detector.DetectFileFormat(FileTest.Detection.CustomersFixed.Path);

            Assert.AreEqual(1, formats.Length);
            Assert.IsTrue(formats[0].ClassBuilder is FixedLengthClassBuilder);
            Assert.AreEqual(100, formats[0].Confidence);
            Assert.AreEqual(7, formats[0].ClassBuilder.FieldCount);

            var builder = formats[0].ClassBuilder as FixedLengthClassBuilder;
            Assert.AreEqual(11, builder.Fields[0].FieldLength);
            Assert.AreEqual(38, builder.Fields[1].FieldLength);
            Assert.AreEqual(22, builder.Fields[2].FieldLength);
            Assert.AreEqual(38, builder.Fields[3].FieldLength);
            Assert.AreEqual(41, builder.Fields[4].FieldLength);
            Assert.AreEqual(18, builder.Fields[5].FieldLength);
            Assert.AreEqual(15, builder.Fields[6].FieldLength);
        }

        [Test]
        public void OneColumnFixed()
        {
            var detector = new SmartFormatDetector();
            var formats = detector.DetectFileFormat(FileTest.Detection.OnColumnFixed.Path);

            Assert.AreEqual(1, formats.Length);
            Assert.IsTrue(formats[0].ClassBuilder is FixedLengthClassBuilder);
            Assert.AreEqual(100, formats[0].Confidence);
            Assert.AreEqual(1, formats[0].ClassBuilder.FieldCount);

            var builder = (FixedLengthClassBuilder) formats[0].ClassBuilder;
            Assert.AreEqual(10, builder.Fields[0].FieldLength);
        }

        [Test]
        public void OneColumnNonFixed()
        {
            var detector = new SmartFormatDetector();
            RecordFormatInfo[] formats = detector.DetectFileFormat(FileTest.Detection.OnColumnNonFixed.Path);

            Assert.AreEqual(0, formats.Length);
        }

        [Test]
        public void Cities()
        {
            AssertDelimitedFormat(FileTest.Detection.Cities.Path, ",", 5, 100, 0);

            AssertDelimitedFormat(FileTest.Detection.Cities2.Path, ",", 12, 100, 0);

            AssertDelimitedFormat(FileTest.Detection.Locations.Path, ",", 7, 90, 0);
        }

        [Test]
        public void TestDataUrlEtc()
        {
            AssertDelimitedFormat(FileTest.Detection.SampleData.Path, ",", 26, 100, 0);
        }

        [Test]
        public void Quoted()
        {
            AssertDelimitedFormat(FileTest.Detection.SuperQuoted.Path, ",", 11, 100, 0);
        }

        //[Test]
        //public void QuotedMore()
        //{
        //    AssertDelimitedFormat(FileTest.Detection.SuperQuoted2.Path, ",", 12, 90, 0);
        //}
    }
}


text:
package eu.matejkormuth.jge.rendering.gl.enums;

public enum Capability {
    BLEND(0xBE2), // GL11.GL_BLEND
    CULL_FACE(0xB44), // GL11.GL_CULL_FACE
    DEPTH_CLAMP(0x864F), // GL32.GL_DEPTH_CLAMP
    DEPTH_TEST(0xB71), // GL11.GL_DEPTH_TEST
    STENCIL_TEST(0xB90), // GL11.GL_STENCIL_TEST
    SCISSOR_TEST(0xC11); // GL11.GL_SCISSOR_TEST

    private final int glConstant;

    Capability(int glConstant) {
        this.glConstant = glConstant;
    }

    /**
     * Returns the OpenGL constant associated to the capability.
     *
     * @return The OpenGL constant
     */
    public int getGLConstant() {
        return glConstant;
    }
}


text:
package com.vmware.action.review;

import com.vmware.action.base.BaseCommitWithReviewAction;
import com.vmware.config.ActionDescription;
import com.vmware.config.WorkflowConfig;
import com.vmware.util.SystemUtils;
import com.vmware.util.UrlUtils;

@ActionDescription("Opens the review diff page in the default web browser.")
public class OpenReviewDiff extends BaseCommitWithReviewAction {

    public OpenReviewDiff(WorkflowConfig config) {
        super(config);
    }

    @Override
    public void process() {
        String reviewUrl = UrlUtils.addRelativePaths(commitConfig.getReviewboardUrl(), "r", draft.id, "diff");
        SystemUtils.openUrl(reviewUrl);
    }
}


text:
import PropTypes from 'prop-types'
import themeable from '../../themeable'
import { Component } from 'react'

describe('.contextTypes', () => {
  const INITIAL_CONTEXT_TYPES = {
    a: PropTypes.string,
    b: PropTypes.number,
    c: PropTypes.object
  }

  class SomeComponentA extends Component {}
  class SomeComponentB extends Component {
    static contextTypes = INITIAL_CONTEXT_TYPES
  }

  it('adds the "theme" property to the expected context types', () => {
    expect(SomeComponentA.contextTypes).toBeFalsy()
    expect(SomeComponentB.contextTypes).toEqual(INITIAL_CONTEXT_TYPES)

    themeable(SomeComponentA)
    themeable(SomeComponentB)

    expect(SomeComponentA.contextTypes)
      .toEqual({ theme: PropTypes.object })

    expect(SomeComponentB.contextTypes)
      .toEqual({ ...INITIAL_CONTEXT_TYPES, theme: PropTypes.object })
  })
})


text:
package preview

import uk.gov.hmrc.hmrcemailrenderer.controllers.model.RenderResult
import uk.gov.hmrc.hmrcemailrenderer.domain.{ErrorMessage, MissingTemplateId, TemplateRenderFailure}
import uk.gov.hmrc.hmrcemailrenderer.services.TemplateRenderer

trait Preview {
  type RenderedResult = Either[ErrorMessage, RenderResult]

  def renderer: TemplateRenderer

  def html(templateId: String, parameters: Map[String, String]): String =
    extractHtml.orElse(handleErrors).apply(renderer.render(templateId, parameters))

  def plain(templateId: String, parameters: Map[String, String]): String =
    extractPlainText.orElse(handleErrors)(renderer.render(templateId, parameters))

  private val extractHtml: PartialFunction[RenderedResult, String] =
    { case Right(RenderResult(_, html, _, _, _, _)) => html }

  private val extractPlainText: PartialFunction[RenderedResult, String] =
    { case Right(RenderResult(plain, _, _, _, _, _)) => plain }

  private val handleErrors: PartialFunction[RenderedResult, String] = {
    case Left(MissingTemplateId(templateId)) =>
      s"failed to rendered template with id == $templateId"
    case Left(TemplateRenderFailure(reason)) => reason
  }

}

object Preview extends Preview {
  def renderer = TemplateRenderer
}


text:
<?php declare(strict_types=1);
/**
 * This file is part of morpho-os/framework
 * It is distributed under the 'Apache License Version 2.0' license.
 * See the https://github.com/morpho-os/framework/blob/master/LICENSE for the full license text.
 */
namespace Morpho\Compiler\Frontend;

use Morpho\Compiler\ILang;

// In formal language theory, a context-free language (CFL) is a language generated by a context-free grammar (CFG).
interface IContextFreeLang extends ILang {

}


text:
<?php

namespace Bazinga\Bundle\HateoasBundle\Tests;

abstract class TestCase extends \PHPUnit_Framework_TestCase
{
}


text:
module StructCore
	module TypeHelpers
		def typed_default(obj, type, default)
			return default unless obj.is_a? type
			obj
		end
	end
end


text:
package net.glowstone.util.loot;

import net.glowstone.entity.GlowLivingEntity;
import net.glowstone.util.ReflectionProcessor;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.LivingEntity;

import java.util.Objects;
import java.util.concurrent.ThreadLocalRandom;

public class LootingUtil {

    public static boolean is(Object a, Object b) {
        return Objects.equals(a, b);
    }

    public static boolean and(boolean a, boolean b) {
        return a && b;
    }

    public static boolean or(boolean a, boolean b) {
        return a || b;
    }

    public static boolean not(boolean b) {
        return !b;
    }

    public static boolean isNot(Object a, Object b) {
        return !is(a, b);
    }

    /**
     * Evaluates a condition for an entity.
     *
     * @param entity    the entity
     * @param condition the condition string to evaluate
     * @return true if the condition is satisfied; false otherwise
     */
    public static boolean conditionValue(GlowLivingEntity entity, String condition) {
        if (condition.equals("ENTITY_ONFIRE")) {
            return entity.getFireTicks() > 0;
        }
        if (condition.startsWith("ENTITY_KILLER_")) {
            EntityType type = EntityType.valueOf(condition.substring("ENTITY_KILLER_".length()));
            return entity.getLastDamager() != null && entity.getLastDamager().getType() == type;
        }
        if (condition.contains(".")) {
            return (boolean) process(entity, condition);
        }
        // todo: more conditions, reflection
        return false;
    }

    public static Object process(LivingEntity entity, String line) {
        return new ReflectionProcessor(line, entity).process();
    }

    public static long randomFishType() {
        return ThreadLocalRandom.current().nextInt(4);
    }
}


text:
layout: page
title: Love Family Reunion
date: 2016-05-24
author: Roger Potter
tags: weekly links, java
status: published
summary: Quisque ac sapien condimentum, viverra enim ac.
banner: images/banner/leisure-05.jpg
booking:
  startDate: 09/08/2017
  endDate: 09/10/2017
  ctyhocn: GAFSCHX
  groupCode: LFR
published: true
---
Suspendisse ac fermentum dolor. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed bibendum id nisi vel efficitur. Nam egestas ante sed tellus tempus fringilla. Proin porttitor, est porta hendrerit hendrerit, enim nisi pulvinar enim, nec porta elit velit eget turpis. Duis vel odio scelerisque, vehicula libero ac, mollis enim. Sed condimentum condimentum quam, non viverra quam venenatis id. Etiam nisl felis, accumsan in lacus sed, placerat tincidunt enim. Aliquam sit amet nisi et mauris feugiat rhoncus.

* Vestibulum vitae justo in ligula viverra maximus
* Praesent vel libero a felis lobortis finibus at sit amet orci
* Nam vel felis dignissim, ultrices mi ac, auctor est.

Maecenas sed scelerisque erat. Morbi tellus nisi, commodo ut porttitor id, scelerisque sagittis turpis. Aliquam erat volutpat. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Ut cursus cursus nulla. Suspendisse eget cursus nulla. Nullam euismod id nisi ut sollicitudin.
Mauris tempus felis quis laoreet bibendum. Sed lobortis iaculis neque, tincidunt sagittis massa cursus a. Integer leo leo, maximus eget risus non, sodales lobortis orci. Vestibulum iaculis tortor malesuada auctor facilisis. Ut sagittis consequat consequat. Aenean sed facilisis dolor, quis faucibus diam. Morbi sed dolor at quam sagittis bibendum. Donec turpis sapien, finibus ac imperdiet non, feugiat vitae elit. Nullam nec mi magna. Suspendisse elementum tortor et sem egestas, ut tincidunt arcu finibus. Donec gravida vehicula interdum. Proin tempus, magna at aliquet consectetur, libero enim condimentum urna, eget posuere sapien purus venenatis ex. Aenean cursus, ante ac hendrerit convallis, est metus cursus massa, vel laoreet ante erat viverra ante. Mauris lacinia lorem metus, ut pellentesque libero vestibulum non. Morbi fringilla tempor elementum. Sed vehicula quis leo id rutrum.


text:
import logging
from django.conf import settings
from django.contrib import admin

from .helpers import User
from .models import ImpersonationLog

logger = logging.getLogger(__name__)

def friendly_name(user):
    '''Return proper name if exists, else username.'''
    name = None
    if hasattr(user, 'get_full_name'):
        name = user.get_full_name()
    return name or user.username

class SessionStateFilter(admin.SimpleListFilter):
    ''' Custom admin filter based on the session state.

        Provides two filter values - 'complete' and 'incomplete'.
        A session that has no session_ended_at timestamp is
        considered incomplete. This field is set from the
        session_end signal receiver.
    '''
    title = 'session state'
    parameter_name = 'session'

    def lookups(self, request, model_admin):
        return (
            ('incomplete', 'Incomplete'),
            ('complete', 'Complete'),
        )

    def queryset(self, request, queryset):
        if self.value() == 'incomplete':
            return queryset.filter(session_ended_at__isnull=True)
        if self.value() == 'complete':
            return queryset.filter(session_ended_at__isnull=False)
        else:
            return queryset

class ImpersonatorFilter(admin.SimpleListFilter):
    ''' Custom admin filter based on the impersonator.

        Provides a set of users who have impersonated at some point.
        It is assumed that this is a small list of users - a subset
        of staff and superusers. There is no corresponding filter
        for users who have been impersonated, as this could be a
        very large set of users.

        If the number of unique impersonators exceeds MAX_FILTER_SIZE,
        then the filter is removed (shows only 'All').
    '''
    title = 'impersonator'
    parameter_name = 'impersonator'

    def lookups(self, request, model_admin):
        ''' Return list of unique users who have been an impersonator.
        '''
        # the queryset containing the ImpersonationLog objects
        MAX_FILTER_SIZE = getattr(settings, 'IMPERSONATE_MAX_FILTER_SIZE', 100)
        try:
            # Evaluate here to raise exception if needed
            ids = list(
                model_admin.get_queryset(
                    request,
                ).order_by().values_list(
                    'impersonator_id',
                    flat=True,
                ).distinct('impersonator_id')
            )
        except NotImplementedError:
            # Unit tests use sqlite db backend which doesn't support distinct.
            qs = model_admin.get_queryset(request).only('impersonator_id')
            ids = set([x.impersonator_id for x in qs])

        if len(ids) > MAX_FILTER_SIZE:
            logger.debug(
                ('Hiding admin list filter as number of impersonators [{0}] '
                 'exceeds MAX_FILTER_SIZE [{1}]').format(
                     len(ids),
                     MAX_FILTER_SIZE,
                 )
            )
            return

        impersonators = \
            User.objects.filter(id__in=ids).order_by(User.USERNAME_FIELD)
        for i in impersonators:
            yield (i.id, friendly_name(i))

    def queryset(self, request, queryset):
        if self.value() in (None, ''):
            return queryset
        else:
            return queryset.filter(impersonator_id=self.value())

class ImpersonationLogAdmin(admin.ModelAdmin):
    icon = '<i class="material-icons">history</i>'

    list_display = (
        'impersonator',
        'impersonating',
        'session_key',
        'session_started_at',
        'duration'
    )
    readonly_fields = (
        'impersonator',
        'impersonating',
        'session_key',
        'session_started_at',
        'session_ended_at',
    )
    list_filter = (
        SessionStateFilter,
        ImpersonatorFilter,
        'session_started_at',
    )

    @staticmethod
    def impersonator(obj):
        return friendly_name(obj.impersonator)

    @staticmethod
    def impersonating(obj):
        return friendly_name(obj.impersonating)

admin.site.register(ImpersonationLog, ImpersonationLogAdmin)


text:
<?php $foto = '';
foreach ($member as $m) {
  $foto = $m->foto;
} ?>

        <a href="<?php echo base_url(); ?>" class="logo">

          C

          Carterin
          <img src="<?php echo base_url(); ?>style/images/logo ico.png">

            Toggle navigation

              <button data-toggle="modal" href="#tambahUnit" type="button" class="btn btn-block btn-danger">TAMBAH UNIT</button>

                  <img src="<?php echo base_url()."images/member/".$foto ?>" class="user-image" alt="User Image">
                  <?php echo $this->session->userdata('username'); ?>

                    <img src="<?php echo base_url()."images/member/".$foto ?>" class="img-circle" alt="User Image">

                      <?php echo $this->session->userdata('username'); ?>
                      Member

                      <a data-toggle="modal" href="<?php echo base_url()."Member/editAkun" ?>" class="btn btn-primary btn-flat">Edit Akun

                      <a href="<?php echo base_url(); ?>/User/logout" class="btn btn-danger btn-flat">Sign out

Edit Akun

            <form role="form">

                  Email address
                  <input type="email" class="form-control" id="Email" placeholder="Email">

                  Username
                  <input type="text" class="form-control" id="username" placeholder="Username">

                  Password
                  <input type="password" class="form-control" id="password" placeholder="Password">

                  konfirmasi Password
                  <input type="password" class="form-control" id="conf" placeholder="konfirmasi Password">

                  Nama
                  <input type="text" class="form-control" id="nama" placeholder="Nama">

                  Alamat
                  <input type="text" class="form-control" id="alamat" placeholder="Alamat">

                  Kota
                  <input type="text" class="form-control" id="kota" placeholder="Kota">

                  Nomot Telepon
                  <input type="text" class="form-control" id="notelp" placeholder="No Telp">

                  Nomor KTP
                  <input type="text" class="form-control" id="noktp" placeholder="noktp">

                  File input
                  <input type="file" id="exampleInputFile">

ukuran gambar maks 2 MB

                <button type="submit" class="btn btn-primary">Submit</button>

            </form>