text:
package org.apache.spark.sql.util

import scala.collection.mutable.ArrayBuffer

import org.apache.spark._
import org.apache.spark.sql.{functions, AnalysisException, QueryTest}
import org.apache.spark.sql.catalyst.analysis.UnresolvedRelation
import org.apache.spark.sql.catalyst.plans.logical.{Aggregate, InsertIntoTable, LogicalPlan, Project}
import org.apache.spark.sql.execution.{QueryExecution, WholeStageCodegenExec}
import org.apache.spark.sql.execution.datasources.{CreateTable, InsertIntoHadoopFsRelationCommand}
import org.apache.spark.sql.execution.datasources.json.JsonFileFormat
import org.apache.spark.sql.test.SharedSQLContext

class DataFrameCallbackSuite extends QueryTest with SharedSQLContext {
  import testImplicits._
  import functions._

  test("execute callback functions when a DataFrame action finished successfully") {
    val metrics = ArrayBuffer.empty[(String, QueryExecution, Long)]
    val listener = new QueryExecutionListener {
      // Only test successful case here, so no need to implement `onFailure`
      override def onFailure(funcName: String, qe: QueryExecution, exception: Exception): Unit = {}

      override def onSuccess(funcName: String, qe: QueryExecution, duration: Long): Unit = {
        metrics += ((funcName, qe, duration))
      }
    }
    spark.listenerManager.register(listener)

    val df = Seq(1 -> "a").toDF("i", "j")
    df.select("i").collect()
    df.filter($"i" > 0).count()

    sparkContext.listenerBus.waitUntilEmpty(1000)
    assert(metrics.length == 2)

    assert(metrics(0)._1 == "collect")
    assert(metrics(0)._2.analyzed.isInstanceOf[Project])
    assert(metrics(0)._3 > 0)

    assert(metrics(1)._1 == "count")
    assert(metrics(1)._2.analyzed.isInstanceOf[Aggregate])
    assert(metrics(1)._3 > 0)

    spark.listenerManager.unregister(listener)
  }

  testQuietly("execute callback functions when a DataFrame action failed") {
    val metrics = ArrayBuffer.empty[(String, QueryExecution, Exception)]
    val listener = new QueryExecutionListener {
      override def onFailure(funcName: String, qe: QueryExecution, exception: Exception): Unit = {
        metrics += ((funcName, qe, exception))
      }

      // Only test failed case here, so no need to implement `onSuccess`
      override def onSuccess(funcName: String, qe: QueryExecution, duration: Long): Unit = {}
    }
    spark.listenerManager.register(listener)

    val errorUdf = udf[Int, Int] { _ => throw new RuntimeException("udf error") }
    val df = sparkContext.makeRDD(Seq(1 -> "a")).toDF("i", "j")

    val e = intercept[SparkException](df.select(errorUdf($"i")).collect())

    sparkContext.listenerBus.waitUntilEmpty(1000)
    assert(metrics.length == 1)
    assert(metrics(0)._1 == "collect")
    assert(metrics(0)._2.analyzed.isInstanceOf[Project])
    assert(metrics(0)._3.getMessage == e.getMessage)

    spark.listenerManager.unregister(listener)
  }

  test("get numRows metrics by callback") {
    val metrics = ArrayBuffer.empty[Long]
    val listener = new QueryExecutionListener {
      // Only test successful case here, so no need to implement `onFailure`
      override def onFailure(funcName: String, qe: QueryExecution, exception: Exception): Unit = {}

      override def onSuccess(funcName: String, qe: QueryExecution, duration: Long): Unit = {
        val metric = qe.executedPlan match {
          case w: WholeStageCodegenExec => w.child.longMetric("numOutputRows")
          case other => other.longMetric("numOutputRows")
        }
        metrics += metric.value
      }
    }
    spark.listenerManager.register(listener)

    val df = Seq(1 -> "a").toDF("i", "j").groupBy("i").count()

    df.collect()
    // Wait for the first `collect` to be caught by our listener. Otherwise the next `collect` will
    // reset the plan metrics.
    sparkContext.listenerBus.waitUntilEmpty(1000)
    df.collect()

    Seq(1 -> "a", 2 -> "a").toDF("i", "j").groupBy("i").count().collect()

    sparkContext.listenerBus.waitUntilEmpty(1000)
    assert(metrics.length == 3)
    assert(metrics(0) === 1)
    assert(metrics(1) === 1)
    assert(metrics(2) === 2)

    spark.listenerManager.unregister(listener)
  }

  // TODO: Currently some LongSQLMetric use -1 as initial value, so if the accumulator is never
  // updated, we can filter it out later.  However, when we aggregate(sum) accumulator values at
  // driver side for SQL physical operators, these -1 values will make our result smaller.
  // A easy fix is to create a new SQLMetric(including new MetricValue, MetricParam, etc.), but we
  // can do it later because the impact is just too small (1048576 tasks for 1 MB).
  ignore("get size metrics by callback") {
    val metrics = ArrayBuffer.empty[Long]
    val listener = new QueryExecutionListener {
      // Only test successful case here, so no need to implement `onFailure`
      override def onFailure(funcName: String, qe: QueryExecution, exception: Exception): Unit = {}

      override def onSuccess(funcName: String, qe: QueryExecution, duration: Long): Unit = {
        metrics += qe.executedPlan.longMetric("dataSize").value
        val bottomAgg = qe.executedPlan.children(0).children(0)
        metrics += bottomAgg.longMetric("dataSize").value
      }
    }
    spark.listenerManager.register(listener)

    val sparkListener = new SaveInfoListener
    spark.sparkContext.addSparkListener(sparkListener)

    val df = (1 to 100).map(i => i -> i.toString).toDF("i", "j")
    df.groupBy("i").count().collect()

    def getPeakExecutionMemory(stageId: Int): Long = {
      val peakMemoryAccumulator = sparkListener.getCompletedStageInfos(stageId).accumulables
        .filter(_._2.name == Some(InternalAccumulator.PEAK_EXECUTION_MEMORY))

      assert(peakMemoryAccumulator.size == 1)
      peakMemoryAccumulator.head._2.value.get.asInstanceOf[Long]
    }

    assert(sparkListener.getCompletedStageInfos.length == 2)
    val bottomAggDataSize = getPeakExecutionMemory(0)
    val topAggDataSize = getPeakExecutionMemory(1)

    // For this simple case, the peakExecutionMemory of a stage should be the data size of the
    // aggregate operator, as we only have one memory consuming operator per stage.
    sparkContext.listenerBus.waitUntilEmpty(1000)
    assert(metrics.length == 2)
    assert(metrics(0) == topAggDataSize)
    assert(metrics(1) == bottomAggDataSize)

    spark.listenerManager.unregister(listener)
  }

  test("execute callback functions for DataFrameWriter") {
    val commands = ArrayBuffer.empty[(String, LogicalPlan)]
    val exceptions = ArrayBuffer.empty[(String, Exception)]
    val listener = new QueryExecutionListener {
      override def onFailure(funcName: String, qe: QueryExecution, exception: Exception): Unit = {
        exceptions += funcName -> exception
      }

      override def onSuccess(funcName: String, qe: QueryExecution, duration: Long): Unit = {
        commands += funcName -> qe.logical
      }
    }
    spark.listenerManager.register(listener)

    withTempPath { path =>
      spark.range(10).write.format("json").save(path.getCanonicalPath)
      sparkContext.listenerBus.waitUntilEmpty(1000)
      assert(commands.length == 1)
      assert(commands.head._1 == "save")
      assert(commands.head._2.isInstanceOf[InsertIntoHadoopFsRelationCommand])
      assert(commands.head._2.asInstanceOf[InsertIntoHadoopFsRelationCommand]
        .fileFormat.isInstanceOf[JsonFileFormat])
    }

    withTable("tab") {
      sql("CREATE TABLE tab(i long) using parquet") // adds commands(1) via onSuccess
      spark.range(10).write.insertInto("tab")
      sparkContext.listenerBus.waitUntilEmpty(1000)
      assert(commands.length == 3)
      assert(commands(2)._1 == "insertInto")
      assert(commands(2)._2.isInstanceOf[InsertIntoTable])
      assert(commands(2)._2.asInstanceOf[InsertIntoTable].table
        .asInstanceOf[UnresolvedRelation].multipartIdentifier == Seq("tab"))
    }
    // exiting withTable adds commands(3) via onSuccess (drops tab)

    withTable("tab") {
      spark.range(10).select($"id", $"id" % 5 as "p").write.partitionBy("p").saveAsTable("tab")
      sparkContext.listenerBus.waitUntilEmpty(1000)
      assert(commands.length == 5)
      assert(commands(4)._1 == "saveAsTable")
      assert(commands(4)._2.isInstanceOf[CreateTable])
      assert(commands(4)._2.asInstanceOf[CreateTable].tableDesc.partitionColumnNames == Seq("p"))
    }

    withTable("tab") {
      sql("CREATE TABLE tab(i long) using parquet")
      val e = intercept[AnalysisException] {
        spark.range(10).select($"id", $"id").write.insertInto("tab")
      }
      sparkContext.listenerBus.waitUntilEmpty(1000)
      assert(exceptions.length == 1)
      assert(exceptions.head._1 == "insertInto")
      assert(exceptions.head._2 == e)
    }
  }
}


text:
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

use App\Http\Requests;
//Utilizamos la classe Config para poder acceder a la configuracion del sistema y pedir el idioma predeterminado ahora mismo
use Config;
use App\Repositories\CharacterRepository;
// Necesitamos la clase Response para crear la respuesta especial con la cabecera de localización en el método Store()
use Response;
//Necesitamos la classe response para utilizar el metodo de cache
use Cache;
// import the Intervention Image Manager Class
use Intervention\Image\ImageManagerStatic as Image;
class characterController extends Controller
{
  protected $character;
  /**
  * Contructor que contienee el respositorio de personajes
  * @param CharacterRepository $characters Clase que se encarga de contactar con el modelo y este a la base de datos
  */
  function __construct(CharacterRepository $characters){
    $this->character = $characters;
    $this->middleware('tokenauth',['only'=>['store','update','destroy']]);
    $this->middleware('locale');
  }
  /**
  * Devuelve todo el contenido de la base de personajes transformado en json
  * @param  Request $request Contenido que nos pasa el usuario
  * @return json devuelve un json para pasarselo al cliente
  */
  public function index(Request $request)
  {

    $characters = null;

    if (Config::get('app.locale') == 'es')
    {
      $characters = Cache::remember('characters',20/60, function()
      {
        return $this->character->All();
      });
    }else{
      $characters =  $this->character->AllLAN(Config::get('app.locale'));
    }

    // Si no existe ese fabricante devolvemos un error.
    if (count($characters)==0)
    {
      // Se devuelve un array errors con los errores encontrados y cabecera HTTP 404.
      // En code podríamos indicar un código de error personalizado de nuestra aplicación si lo deseamos.
      return response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra el usuario a la base de datos.'])],404);
    }
    return response()->json(['status'=>'ok','data'=>$characters],200);
  }
  /**
   * Metodo que se encarga de buscar por identificador y delvolver un json con el resultado
   * @param  int $character identificador de recurso a buscar
   * @return json            Devuelve json con el contenido del fichero
   **/
  public function show($character)
  {
    //
    // return "Se muestra Fabricante con id: $id";
    // Buscamos un fabricante por el id.
    $characters=null;
    if (Config::get('app.locale') == 'es')
    {
      $characters=$this->character->show($character);
    }else{
      $characters=$this->character->showLAN($character,Config::get('app.locale'));
    }

    // Si no existe ese fabricante devolvemos un error.
    if ($characters ==null)
    {
      // Se devuelve un array errors con los errores encontrados y cabecera HTTP 404.
      // En code podríamos indicar un código de error personalizado de nuestra aplicación si lo deseamos.
      return response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra el usuario a la base de datos.'])],404);
    }

    return response()->json(['status'=>'ok','data'=>$characters],200);

}
/**
 * Metodo que se encarga de processar la peticion y guardar un objeto en bd
 * @param  Request $request Contenido que envia el cliente
 * @return [type]           Devuelve el contenido creado en el momento como confirmacion
 */
public function store(Request $request){
  //`id``facname``facdescription``facshortdescription`
  // Primero comprobaremos si estamos recibiendo todos los campos.
  //`id``charclass``charname``charbio``charbirthdate``charportrait``charstylecombat``faction_id``charfacechar``charerased`
  if (!$request->input('charclass') || !$request->input('charname') || !$request->input('charbio') || !$request->input('charbirthdate')|| !$request->file('charportrait')|| !$request->file('charfacechar'))
  {
    // Se devuelve un array errors con los errores encontrados y cabecera HTTP 422 Unprocessable Entity – [Entidad improcesable] Utilizada para errores de validación.
    // En code podríamos indicar u  n código de error personalizado de nuestra aplicación si lo deseamos.
    return response()->json(['errors'=>array(['code'=>422,'message'=>'Faltan datos necesarios para el proceso de alta.'])],422);
  }
  //echo $request::json()->all();

  // Insertamos una fila en Fabricante con create pasándole todos los datos recibidos.
  // En $request->all() tendremos todos los campos del formulario recibidos.
  $newcharacter=$this->character->create($request);

  // Más información sobre respuestas en http://jsonapi.org/format/
  // Devolvemos el código HTTP 201 Created – [Creada] Respuesta a un character que resulta en una creación. Debería ser combinado con un encabezado Location, apuntando a la ubicación del nuevo recurso.

  $response = Response::make(json_encode(['data'=>$newcharacter]), 201)->header('Location', 'http://www.dominio.local/fabricantes/'.$newcharacter->id)->header('Content-Type', 'application/json');
  return $response;
}
/**
* Update the specified resource in storage.
*
* @param  int  $id
* @return Response
*/
public function update(Request $request, $id)
{
  //
  // return "Se muestra Fabricante con id: $id";
  // Buscamos un fabricante por el id.
  ////`if (!$request->input('facname') || !$request->input('facdescription')|| !$request->input('facshortdescription') )

  $characters=$this->character->show($id);
  //if (!$request->input('user_id') || !$request->input('characteritle') || !$request->input('poscontent') || !$request->input('posdescription') || !$request->input('posphoto') || !$request->input('category_id') || !$request->input('posshortdesc'))

  if($characters == null){
    return response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra un avión con ese código asociado al usuario.'])],404);
  }
  // Listado de campos recibidos teóricamente.
  //if (!$request->input('facname') || !$request->input('facdescription')|| !$request->input('facshortdescription') )
  ////`id``charclass``charname``charbio``charbirthdate``charportrait``charstylecombat``faction_id``charfacechar``charerased`

  $charclass=$request->input('charclass');
  $charname=$request->input('charname');
  $charbio=$request->input('charbio');
  $charbirthdate=$request->input('charbirthdate');
  $charportrait=$request->file('charportrait');
  $charstylecombat=$request->input('charstylecombat');
  $faction_id=$request->input('faction_id');
  $charfacechar=$request->file('charfacechar');

  // El método de la petición se sabe a través de $request->method();
  /*	Modelo		Longitud		Capacidad		Velocidad		Alcance */
  if ($request->method() === 'PATCH')
  {
    // Creamos una bandera para controlar si se ha modificado algún dato en el método PATCH.
    $bandera = false;

    // Actualización parcial de campos.
    if ($charclass)
    {
      $characters->charclass = $charclass;
      $bandera=true;
    }
    // Actualización parcial de campos.
    if ($charname)
    {
      $characters->charname = $charname;
      $bandera=true;
    }
    // Actualización parcial de campos.
    if ($charbio)
    {
      $characters->charbio = $charbio;
      $bandera=true;
    }
    // Actualización parcial de campos.
    if ($charbirthdate)
    {
      $characters->charbirthdate = $charbirthdate;
      $bandera=true;
    }
    // Actualización parcial de campos.
    if ($charportrait)
    {
      $characters->charportrait = $charportrait;
      $bandera=true;
    }
    // Actualización parcial de campos.
    if ($charstylecombat)
    {
      $characters->charstylecombat = $charstylecombat;
      $bandera=true;
    }
    // Actualización parcial de campos.
    if ($faction_id)
    {
      $characters->faction_id = $faction_id;
      $bandera=true;
    }
    // Actualización parcial de campos.
    if ($charfacechar)
    {
      $characters->charfacechar = $charfacechar;
      $bandera=true;
    }

    if ($bandera)
    {
      // Almacenamos en la base de datos el registro.
      $characters->save();
      return response()->json(['status'=>'ok','data'=>$characters], 200);
    }
    else
    {
      // Se devuelve un array errors con los errores encontrados y cabecera HTTP 304 Not Modified – [No Modificada] Usado cuando el cacheo de encabezados HTTP está activo
      // Este código 304 no devuelve ningún body, así que si quisiéramos que se mostrara el mensaje usaríamos un código 200 en su lugar.
      return response()->json(['errors'=>array(['code'=>304,'message'=>'No se ha modificado ningún dato del avión.'])],304);
    }
  }
  /*
  *
  $charclass=$request->input('charclass');
  $charname=$request->input('charname');
  $charbio=$request->input('charbio');
  $charbirthdate=$request->input('charbirthdate');
  $charportrait=$request->input('charportrait');
  $charstylecombat=$request->input('charstylecombat');
  $faction_id=$request->input('faction_id');
  $charfacechar=$request->input('charfacechar');
  */
  // Si el método no es PATCH entonces es PUT y tendremos que actualizar todos los datos.
  if (!$charclass || !$charname  || !$charbio|| !$charbirthdate|| !$charportrait|| !$charstylecombat|| !$faction_id|| !$charfacechar)
  {
    // Se devuelve un array errors con los errores encontrados y cabecera HTTP 422 Unprocessable Entity – [Entidad improcesable] Utilizada para errores de validación.
    return response()->json(['errors'=>array(['code'=>422,'message'=>'Faltan valores para completar el procesamiento.'])],422);
  }
  $characters->charclass = $charclass;
  $characters->charname = $charname;
  $characters->charbirthdate = $charbirthdate;
  $characters->charportrait = $charportrait;
  $characters->charstylecombat = $charstylecombat;
  $characters->faction_id = $faction_id;
  $characters->charfacechar = $charfacechar;
  // Almacenamos en la base de datos el registro.
  $characters->save();
  return response()->json(['status'=>'ok','data'=>$characters], 200);

}

/**
* Borrar contenido especifico.
*
* @param  int  $id
* @return Response
*/
public function destroy($id)
{
  // Primero eliminaremos todos los aviones de un fabricante y luego el fabricante en si mismo.
  // Comprobamos si el fabricante que nos están pasando existe o no.

  $characters=$this->character->show($id);

  // Si no existe ese fabricante devolvemos un error.
  if ($characters ==null)
  {
    // Se devuelve un array errors con los errores encontrados y cabecera HTTP 404.
    // En code podríamos indicar un código de error personalizado de nuestra aplicación si lo deseamos.
    return response()->json(['errors'=>array(['code'=>404,'message'=>'No se encuentra un fabricante con ese código.'])],404);
  }

  // El fabricante existe entonces buscamos todos los aviones asociados a ese fabricante.
  //	$aviones = $fabricante->aviones; // Sin paréntesis obtenemos el array de todos los aviones.

  // Comprobamos si tiene aviones ese fabricante.

  // Procedemos por lo tanto a eliminar el fabricante.
  $characters[0]->charerased = true;
  $characters[0]->save();
  // Se usa el código 204 No Content – [Sin Contenido] Respuesta a una petición exitosa que no devuelve un body (como una petición DELETE)
  // Este código 204 no devuelve body así que si queremos que se vea el mensaje tendríamos que usar un código de respuesta HTTP 200.
  return response()->json(['code'=>204,'message'=>'Se ha eliminado el usuario correctamente.'],204);

}
}

redpajama_set_name: RedPajamaGithub


text:
bool operator <(IndexPath const &left, IndexPath const &right) {
    return left.row < right.row || (left.row == right.row
                                    && left.col < right.col);
}

bool operator ==(IndexPath const &left, IndexPath const &right) {
    return left.row == right.row && left.col == right.col;
}

Cell::Cell() {
    this->background = FMAW::Background(0);
}

void Cell::setCenter(FMAW::Point newCenter) {
    this->center = newCenter;
}

CellBackgroundType Cell::getBackgroundType() {
    return this->backgroundType;
}

void Cell::setBackgroundType(CellBackgroundType type) {
    this->backgroundType = type;
}

FMAW::Point Cell::getCenter() {
    return this->center;
}

bool Cell::isOccupied() {
    return this->characterInCell != nullptr;
}

Unit *Cell::getCharacter() {
    return this->characterInCell;
}

Unit *Cell::setCharacter(Unit *newCharacter) {
    Unit *prev = this->characterInCell;
    this->characterInCell = newCharacter;
    if (newCharacter != nullptr) {
        newCharacter->decreaseAvailableActions();
        newCharacter->setPosition(this->center);
    }
    return prev;
}

int Cell::movementCost() {
    switch (this->backgroundType) {
        case CellBGBase:
            return COST_MOVE_CELL_BASE;
        case CellBGBridge:
        case CellBGBridgeH:
            return COST_MOVE_CELL_BRIDGE;
        case CellBGForest:
            return COST_MOVE_CELL_FOREST;
        case CellBGGrass:
            return COST_MOVE_CELL_GRASS;
        case CellBGMountain:
            return COST_MOVE_CELL_MOUNTAIN;
        case CellBGRiver:
        case CellBGRiverH:
            return COST_MOVE_CELL_RIVER;
        case CellBGCastle:
            return COST_MOVE_CELL_CASTLE;
        default:
            return COST_CELL_INFINITY;
    }
}

int Cell::sightCost() {
    switch (this->backgroundType) {
        case CellBGBase:
            return COST_SEE_CELL_BASE;
        case CellBGBridge:
        case CellBGBridgeH:
            return COST_SEE_CELL_BRIDGE;
        case CellBGForest:
            return COST_SEE_CELL_FOREST;
        case CellBGGrass:
            return COST_SEE_CELL_GRASS;
        case CellBGMountain:
            return COST_SEE_CELL_MOUNTAIN;
        case CellBGRiver:
        case CellBGRiverH:
            return COST_SEE_CELL_RIVER;
        case CellBGCastle:
            return COST_SEE_CELL_CASTLE;
        default:
            return COST_CELL_INFINITY;
    }
}

int Cell::terrainDefense() {
    switch (this->backgroundType) {
        case CellBGBase:
            return DEFENSE_CELL_BASE;
        case CellBGBridge:
        case CellBGBridgeH:
            return DEFENSE_CELL_BRIDGE;
        case CellBGForest:
            return DEFENSE_CELL_FOREST;
        case CellBGGrass:
            return DEFENSE_CELL_GRASS;
        case CellBGMountain:
            return DEFENSE_CELL_MOUNTAIN;
        case CellBGRiver:
        case CellBGRiverH:
            return DEFENSE_CELL_RIVER;
        default:
            return DEFAULT_DEFENSE;
    }
}

void Cell::renderBackground() {
    switch (this->backgroundType) {
        case CellBGBase:
        case CellBGBridge:
        case CellBGBridgeH:
        case CellBGForest:
        case CellBGGrass:
        case CellBGMountain:
        case CellBGRiver:
        case CellBGRiverH:
        case CellBGCastle:
            this->background.setScreenBaseBlock(2);
            for (int i = 0; i < this->tiles.size(); ++i) {
                this->background.setTile(
                    this->tiles[i],
                    FMAW::Tile(this->backgroundType).imgMemory + i);
                this->background.setPalette(
                    this->tiles[i],
                    FMAW::Tile(this->backgroundType).palMemory);
            }
            break;
        default:
            break;
    }
}

void Cell::renderFoggyBackground() {
    switch (this->backgroundType) {
        case CellBGBase:
        case CellBGBridge:
        case CellBGBridgeH:
        case CellBGForest:
        case CellBGGrass:
        case CellBGMountain:
        case CellBGRiver:
        case CellBGRiverH:
        case CellBGCastle:
            this->background.setScreenBaseBlock(2);
            for (int i = 0; i < this->tiles.size(); ++i) {
                this->background.setTile(
                    this->tiles[i],
                    FMAW::Tile(this->backgroundType +
                               NUM_BACKGROUNDS).imgMemory + i);
                this->background.setPalette(
                    this->tiles[i],
                    FMAW::Tile(this->backgroundType +
                               NUM_BACKGROUNDS).palMemory);
            }
            break;
        default:
            break;
    }
}

void Cell::renderCharacter() {
    if (this->characterInCell != nullptr) {
        this->characterInCell->render();
    }
}


text:
package com.jmace.MaceDrone.msp;

import com.pi4j.io.serial.Baud;
import com.pi4j.io.serial.DataBits;
import com.pi4j.io.serial.FlowControl;
import com.pi4j.io.serial.Parity;
import com.pi4j.io.serial.Serial;
import com.pi4j.io.serial.SerialConfig;
import com.pi4j.io.serial.SerialFactory;
import com.pi4j.io.serial.StopBits;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.Map;

/**************************************************************************************************
 *
 *
This class controls communication with the MultiWii via the MultiWii serial protocol (MSP).
 * The low level handling of the serial communication is handled by the pi4j library, while the
 * protocol is handled in this class.

 *
 *
The MSP format, including a list of valid commands, is defined
 * here

 *
 *
 *
Message format is as follows:

 *

 * +--------+---------+----+-------+----+---+
 * |preamble|direction|size|command|data|crc|
 * +--------+---------+----+-------+----+---+
 *

 *
 *
 *

 *  Preamble (2 bytes):
 *      Marks the start of a new message; always "$M"
 *

 *  Direction (1 byte):
 *      Either '<' for a command going to the MultiWii or '>' for information being coming back
 *      from the MultiWii
 *

 * Size (1 byte):
 *      The number of bytes in the payload
 *

 * Command (1 byte):
 *      The message ID of the command, as defined in the protocol 100's for requesting data, and
 *      200's for requesting an action
 *

 * Data (variable bytes):
 *      The data to pass along with the command
 *

 * CRC (1 byte):
 *      Calculated with an XOR of the size, command, and each byte of data
 *

 **************************************************************************************************/
public class MultiWiiClient {

    private Serial serial;
    private BufferedInputStream inStream;

    //The preamble and direction byte of messages are both defined by the protocol.
    //Every message must begin with the characters $M, and message going to the MultiWii must have the direction <
    private static final String OUTGOING_PREAMBLE_WITH_DIRECTION = "$M<";
    //Every response must begin with the characters $M, and message coming from the MultiWii must have the direction >
    private static final String INCOMING_PREAMBLE_WITH_DIRECTION = "$M>";

    /**
     * Creates a new instance of the client
     *
     * @param   port    The path to the port to send and receive data (such as "/dev/ttyUSB0")
     */
    public MultiWiiClient(String port) {
        try {
            //Set up the serial port connection
            SerialConfig config = new SerialConfig();
            config.device(port)
                  .baud(Baud._115200)
                  .dataBits(DataBits._8)
                  .parity(Parity.NONE)
                  .stopBits(StopBits._1)
                  .flowControl(FlowControl.NONE);
            this.serial = SerialFactory.createInstance();
            this.serial.open(config);

            //Create the input stream
            this.inStream = new BufferedInputStream(this.serial.getInputStream());
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    /**
     * Requests information from the MultiWii
     *
     * @param   request The specific MSP command for the data being requested
     *
     * @return  A key value pair; this varies, depending on the data being asked for. See /parsers.
     *
     * @throws  IllegalStateException   thrown if the connection is not open
     * @throws  IOException             thrown if the streams fail
     * @throws  Exception               thrown if the data coming back is incorrect (for example, the checksum does not match)
     */
    public Map<String, Object> sendRequest(MultiWiiRequest request) throws IllegalStateException, IOException, Exception {
        String message = createMessage(request.getId(), null);
        byte[] response = sendMessage(message);
        return request.parse(response);
    }

    /**
     * Sends a command to the MultiWii
     *
     * @param   command   The specific MSP command the MultiWii will execute
     * @param   payload   The data to be sent to the MultiWii along with the command
     *
     * @return  A key value pair; this varies, depending on the data being asked for. See /parsers.
     *
     * @throws  IllegalStateException   thrown if the connection is not open
     * @throws  IOException             thrown if the streams fail
     * @throws  Exception               thrown if the data coming back is incorrect (for example, the checksum does not match)
     */
    public Map<String, Object> sendCommand(MultiWiiCommand command, byte[] payload) throws IllegalStateException, IOException, Exception {
        String message = createMessage(command.getId(), payload);
        byte[] response = sendMessage(message);
        return command.parse(response);
    }

    /**
     * This method creates the message that will be sent to the MultiWii
     *
     * @param   mutliWiiCommandnumber   The MSP command number
     * @param   payload                 Data
     *
     * @return  The MSP message that can be passed to the MultiWii
     */
    private String createMessage(int mutliWiiCommandnumber, byte[] payload) {
        StringBuilder message = new StringBuilder(OUTGOING_PREAMBLE_WITH_DIRECTION);
        byte checksum=0;

        int datalength = (payload != null) ? payload.length : 0;

        message.append((char) datalength);
        checksum ^= datalength;

        message.append((char) mutliWiiCommandnumber);
        checksum ^= ((int) mutliWiiCommandnumber);

        if (payload != null) {
            for (byte b : payload){
                message.append(b);
                checksum ^= (int) b;
            }
        }

        message.append((char) checksum);
        return message.toString();
    }

    /**
     * This method sends the request to the MultiWii, receives the response, and insures that is is correct.
     *
     * @param   message The MSP formatted message to send to the MultiWii
     *
     * @return  The raw data sent back from the MultiWii, not including the preamble, direction, or CRC
     *
     * @throws  Exception   thrown if the data that comes back is invalid
     */
    private synchronized byte[] sendMessage(String message) throws Exception {
        //Clear out any old responses or requests that were not handled
        serial.discardAll();
        inStream.skip(inStream.available());

        //Send the request
        serial.write(message.getBytes());
        serial.flush();

        //Wait for the response to come back
        //(Note that, in the event of an error, inStream.available() == -1 and will skip both loops)
        int count = 0;
        while (inStream.available() == 0) {
            //After 1.5 seconds, give up on the response
            if (count++ > 150) {
                break;
            }
            try{
                Thread.sleep(10);
            } catch (Exception e) {}
        }

        //Get the response
        StringBuilder responseHeader = new StringBuilder();
        for (int i = 0; i < 3 && inStream.available() > 0; i++) {
            responseHeader.append((char) inStream.read());
        }

        if (!responseHeader.toString().equals(INCOMING_PREAMBLE_WITH_DIRECTION) || inStream.available() <= 1)
        {
            throw new Exception("Invalid header: " + responseHeader.toString());
        }

        int length = inStream.read();
        int computedChecksum = length ^ inStream.read(); //command
        byte[] response = new byte[length];

        for (int i = 0; i < length && inStream.available() > 0; i++) {
            int value =  inStream.read();
            response[i] = (byte) value;
            computedChecksum ^= value;
        }

        int checksum = inStream.read();

        if (computedChecksum != checksum) {
            throw new Exception("Invalid checksum");
        }

        //Return the response
        return response;
    }

}


text:
package com.qlfg.miningcircle.loan.activity;

import android.app.Activity;
import android.app.ActivityGroup;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.widget.ImageView;
import android.widget.LinearLayout;

import com.example.miningcircle.R;
import com.qlfg.miningcircle.application.MiningCircleApplication;
import com.qlfg.miningcircle.home.LoginActivity;
import com.qlfg.miningcircle.tabbar.TabbarData;
import com.qlfg.miningcircle.tabbar.TabbarManager;
import com.qlfg.miningcircle.tabbar.TabbarManager.BottomBarListener;
import com.qlfg.miningcircle.util.CkxTrans;
import com.qlfg.miningcircle.util.Contant;
import com.qlfg.miningcircle.util.ShareUtil;

import java.util.ArrayList;
import java.util.List;

@SuppressWarnings("deprecation")
public class LoanHomeActivity extends ActivityGroup implements OnClickListener {
    private ImageView logo_ceshi;
    private ImageView logo_left;
    private ImageView logo_right;
    private boolean isrote = true;//中间加号判断是弹出还是缩回
    private ImageView bantouming1;

    @Override
    protected void onNewIntent(Intent intent) {
        turnTargetView(0);
        mBottomBarManager.selectMenu(0);
        super.onNewIntent(intent);
    }

    private ViewGroup main_bottombar;
    private LinearLayout main_content_container_ly;
    public TabbarManager mBottomBarManager;
    private int mLastedIndex = 0;
    Activity mActivity;
    boolean mIsChildBack;
    private LinearLayout gmf_menu_container_share;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.activity_miningcircle_logn_home);
        mActivity = LoanHomeActivity.this;
        Contant.createContext();
        initUI();
    }

    /**
     * 设置是否子项返回
     *
     * @param isChild
     */
    public void isChildGebBack(boolean isChild) {
        mIsChildBack = isChild;
    }

    /**
     * 初始化UI
     */
    private void initUI() {
        logo_ceshi = (ImageView) findViewById(R.id.logo_zhongj);
        logo_ceshi.setOnClickListener(this);
        logo_left = (ImageView) findViewById(R.id.logo_left);
        logo_left.setOnClickListener(this);
        logo_right = (ImageView) findViewById(R.id.logo_right);
        logo_right.setOnClickListener(this);
        main_content_container_ly = (LinearLayout) this.findViewById(R.id.main_content_container_ly);
        gmf_menu_container_share = (LinearLayout) this.findViewById(R.id.gmf_menu_container_share);
        gmf_menu_container_share.setOnClickListener(this);
        bantouming1 = (ImageView) findViewById(R.id.bantouming1);
        bantouming1.setOnClickListener(null);
        initBottomBar();
    }

    /**
     * 初始化底部导航
     */
    private void initBottomBar() {
        main_bottombar = (ViewGroup) this.findViewById(R.id.main_bottombar);
        initBottomManager();
        turnTargetView(mLastedIndex);
    }

    /**
     * 初始化底部控制器
     */
    private void initBottomManager() {
        mBottomBarManager = TabbarManager.newInstance(main_bottombar);
        mBottomBarManager.registerListener();
        mBottomBarManager.selectMenu(0);
        mBottomBarManager.setListener(new BottomBarListener() {
            @Override
            public void onClick(int position) {
                if (mLastedIndex != position) {
                    if (position != 2) {
                        turnTargetView(position);
                    }
                }
            }

        });
    }

    /**
     * 跳转到目标界面
     */
    public void turnTargetView(int position) {
        mLastedIndex = position;
        try {
            Intent intent = new Intent();
            TabbarData data = TabbarData.getInstance();
            if (data.getBottomMenuData() != null) {
                intent.setClass(getApplicationContext(), data
                        .getBottomMenuData().get(position).getActivityClass());
            } else {
            }
            intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);// 不清除activityGroup之前的activity,而是放到包含子activity的map中
            showView(getLocalActivityManager().startActivity(position + "", intent).getDecorView());
        } catch (ActivityNotFoundException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (!isrote) {
            CkxTrans.playWithAftered(logo_ceshi);
            CkxTrans.playWithAfterlefted(logo_left);
            CkxTrans.playWithAfterrighedt(logo_right);
            gmf_menu_container_share.setSelected(isrote);
            bantouming1.setVisibility(View.GONE);
            isrote = true;
        }
    }

    /**************
     * 手势监听
     ********************/
    /* 跳转 */
    // 用于保存打开的view
    private List<View> views = new ArrayList<View>();

    /**
     * 用于显示view到主界面的方法
     */
    private void showView(View view) {
        boolean flag = false;// 判断view是否存在
        // 遍历内存中的view列表,与当前view不同则设置为不显示,否则显示
        for (int i = 0; i < views.size(); i++) {
            if (views.get(i) != null && !views.get(i).equals(view)) {
                views.get(i).setVisibility(View.GONE);
            } else if (views.get(i) != null && views.get(i).equals(view)) {
                views.get(i).setVisibility(View.VISIBLE);
                flag = true;
            }
        }
        // 如果内存和界面都不存在此view则添加
        if (!flag) {
            main_content_container_ly.addView(view, LayoutParams.FILL_PARENT,
                    LayoutParams.FILL_PARENT);
            views.add(view);
        }
    }

    private static long _lastClickTime = 0;

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.gmf_menu_container_share:
                boolean isDo = false;
                long now = System.currentTimeMillis();
                synchronized (this) {
                    if (now - _lastClickTime > 600) {
                        _lastClickTime = System.currentTimeMillis();
                        isDo = true;
                    }
                }
                if (isDo) {
                    if (isrote) {
                        gmf_menu_container_share.setSelected(isrote);
                        isrote = false;
                        Log.e("lkl", "动画start**************");
                        CkxTrans.playWithAfter(logo_ceshi);
                        CkxTrans.playWithAfterleft(logo_left);
                        CkxTrans.playWithAfterright(logo_right);
                        bantouming1.setVisibility(View.VISIBLE);
                    } else {

                        gmf_menu_container_share.setSelected(isrote);
                        isrote = true;
                        Log.e("lkl", "动画缩回**************");
                        CkxTrans.playWithAftered(logo_ceshi);
                        CkxTrans.playWithAfterlefted(logo_left);
                        CkxTrans.playWithAfterrighedt(logo_right);
                        bantouming1.setVisibility(View.GONE);
                    }
                }
                break;
            case R.id.logo_zhongj://我的收益
                if (CkxTrans.isNull(MiningCircleApplication.getInstance().getUserPhone())) {
                    final AlertDialog ad = new AlertDialog(mActivity);
                    ad.setTitle("抱歉,请您先登录。");
                    ad.setLeft("取消");
                    ad.setRight("登录");
                    ad.setPositiveButton("确定", new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            // TODO Auto-generated method stub
                            ad.dismiss();
                            Intent mintent = new Intent(mActivity, LoginActivity.class);
                            startActivity(mintent);
//				      outLogin();
                        }
                    });
                    ad.setNegativeButton("取消", new OnClickListener() {
                        @Override
                        public void onClick(View v) {
                            ad.dismiss();
                        }
                    });
                } else {
                    Intent shouy = new Intent(mActivity, WebViewActiity.class);
                    //			mintent.putExtra("type", Contant.DETAIL);
                    shouy.putExtra("url", Contant.server_url + "app2.do?urfin");
                    shouy.putExtra("type", "detail");
                    shouy.putExtra("titlename", "我的收益");
                    startActivity(shouy);
                }
                CkxTrans.playWithAftered(logo_ceshi);
                CkxTrans.playWithAfterlefted(logo_left);
                CkxTrans.playWithAfterrighedt(logo_right);
                gmf_menu_container_share.setSelected(isrote);
                bantouming1.setVisibility(View.GONE);
                isrote = true;
                break;
            case R.id.logo_left://分享
                String nm;
                if (CkxTrans.isNull(MiningCircleApplication.getInstance().getUserName()))
                    nm = MiningCircleApplication.getInstance().getUserealName();
                else
                    nm = MiningCircleApplication.getInstance().getUserName();

                ShareUtil.getInstance(getApplicationContext(), mActivity).showShareGrid("", "", getString(R.string.share_url_prdlist) + "&fm="
                        + MiningCircleApplication.getInstance().getUserPhone() + "&nm=" + nm, "");
                CkxTrans.playWithAftered(logo_ceshi);
                CkxTrans.playWithAfterlefted(logo_left);
                CkxTrans.playWithAfterrighedt(logo_right);
                gmf_menu_container_share.setSelected(isrote);
                bantouming1.setVisibility(View.GONE);
                isrote = true;
                break;
            case R.id.logo_right://红包
                Intent hongbao = new Intent(mActivity, WebViewActiity.class);
                hongbao.putExtra("url", Contant.server_url + "app2.do?giftcash");
                hongbao.putExtra("type", "detail");
                hongbao.putExtra("titlename", "红包");
                startActivity(hongbao);
                CkxTrans.playWithAftered(logo_ceshi);
                CkxTrans.playWithAfterlefted(logo_left);
                CkxTrans.playWithAfterrighedt(logo_right);
                gmf_menu_container_share.setSelected(isrote);
                bantouming1.setVisibility(View.GONE);
                isrote = true;
            default:
                break;
        }
    }

    //	@Override
//	protected void onPause() {
//		// TODO Auto-generated method stub
//		super.onPause();
//
// 	JPushInterface.onPause(this);
//	}
//	@Override
//	protected void onResume() {
//		super.onResume();
//		JPushInterface.onResume(this);
//	}
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == 1) {//确定
            Intent mintent = new Intent(mActivity, LoginActivity.class);
            startActivity(mintent);
        }
    }
}


text:
require 'ostruct'
require 'albacore/support/openstruct'

module Configuration
  module NChurn
    include Albacore::Configuration

    def nchurn
      @nchurnconfig ||= OpenStruct.new.extend(OpenStructToHash)
      yield(@nchurnconfig) if block_given?
      @nchurnconfig
    end
  end
end


text: sudo apt-get install --only-upgrade libcommons-httpclient-java=3.1-10.2ubuntu0.15.04.1 -y


text:
// This is a CLI tool, using console is OK
/* eslint no-console: 0 */
const {spawn, exec} = require('child_process');
const {isAbsolute, resolve} = require('path');
const {existsSync} = require('fs');
const {version} = require('../app/package');
const pify = require('pify');
const args = require('args');
const chalk = require('chalk');
const opn = require('opn');
const columnify = require('columnify');
const got = require('got');
const ora = require('ora');
const api = require('./api');

const PLUGIN_PREFIX = 'hyper-';

let commandPromise;

const assertPluginName = pluginName => {
  if (!pluginName) {
    console.error(chalk.red('Plugin name is required'));
    process.exit(1);
  }
};

const checkConfig = () => {
  if (api.exists()) {
    return true;
  }
  let msg = chalk.red(`Error! Config file not found: ${api.configPath}\n`);
  msg += 'Please launch Hyper and retry.';
  console.error(msg);
  process.exit(1);
};

args.command(['i', 'install'], 'Install a plugin', (name, args_) => {
  checkConfig();
  const pluginName = args_[0];
  assertPluginName(pluginName);
  commandPromise = api
    .install(pluginName)
    .then(() => console.log(chalk.green(`${pluginName} installed successfully!`)))
    .catch(err => console.error(chalk.red(err)));
});

args.command(['u', 'uninstall', 'rm', 'remove'], 'Uninstall a plugin', (name, args_) => {
  checkConfig();
  const pluginName = args_[0];
  assertPluginName(pluginName);
  commandPromise = api
    .uninstall(pluginName)
    .then(() => console.log(chalk.green(`${pluginName} uninstalled successfully!`)))
    .catch(err => console.log(chalk.red(err)));
});

args.command(['ls', 'list'], 'List installed plugins', () => {
  checkConfig();
  let plugins = api.list();

  if (plugins) {
    console.log(plugins);
  } else {
    console.log(chalk.red(`No plugins installed yet.`));
  }
  process.exit(0);
});

const lsRemote = pattern => {
  // note that no errors are catched by this function
  const URL = `https://api.npms.io/v2/search?q=${(pattern && `${pattern}+`) || ''}keywords:hyper-plugin,hyper-theme`;
  return got(URL)
    .then(response => JSON.parse(response.body).results)
    .then(entries => entries.map(entry => entry.package))
    .then(entries => entries.filter(entry => entry.name.indexOf(PLUGIN_PREFIX) === 0))
    .then(entries =>
      entries.map(({name, description}) => {
        return {name, description};
      })
    )
    .then(entries =>
      entries.map(entry => {
        entry.name = chalk.green(entry.name);
        return entry;
      })
    );
};

args.command(['s', 'search'], 'Search for plugins on npm', (name, args_) => {
  const spinner = ora('Searching').start();
  const query = args_[0] ? args_[0].toLowerCase() : '';

  commandPromise = lsRemote(query)
    .then(entries => {
      if (entries.length === 0) {
        spinner.fail();
        console.error(chalk.red(`Your search '${query}' did not match any plugins`));
        console.error(`${chalk.red('Try')} ${chalk.green('hyper ls-remote')}`);
        process.exit(1);
      } else {
        let msg = columnify(entries);
        spinner.succeed();
        msg = msg.substring(msg.indexOf('\n') + 1); // remove header
        console.log(msg);
      }
    })
    .catch(err => {
      spinner.fail();
      console.error(chalk.red(err)); // TODO
    });
});

args.command(['lsr', 'list-remote', 'ls-remote'], 'List plugins available on npm', () => {
  const spinner = ora('Searching').start();

  commandPromise = lsRemote()
    .then(entries => {
      let msg = columnify(entries);

      spinner.succeed();
      msg = msg.substring(msg.indexOf('\n') + 1); // remove header
      console.log(msg);
    })
    .catch(err => {
      spinner.fail();
      console.error(chalk.red(err)); // TODO
    });
});

args.command(['d', 'docs', 'h', 'home'], 'Open the npm page of a plugin', (name, args_) => {
  const pluginName = args_[0];
  assertPluginName(pluginName);
  opn(`http://ghub.io/${pluginName}`, {wait: false});
  process.exit(0);
});

args.command(['version'], 'Show the version of hyper', () => {
  console.log(version);
  process.exit(0);
});

args.command(['<default>'], 'Launch Hyper');

args.option(['v', 'verbose'], 'Verbose mode', false);

const main = argv => {
  const flags = args.parse(argv, {
    name: 'hyper',
    version: false,
    mri: {
      boolean: ['v', 'verbose']
    }
  });

  if (commandPromise) {
    return commandPromise;
  }

  const env = Object.assign({}, process.env, {
    // this will signal Hyper that it was spawned from this module
    HYPER_CLI: '1',
    ELECTRON_NO_ATTACH_CONSOLE: '1'
  });

  delete env['ELECTRON_RUN_AS_NODE'];

  if (flags.verbose) {
    env['ELECTRON_ENABLE_LOGGING'] = '1';
  }

  const options = {
    detached: true,
    env
  };

  const args_ = args.sub.map(arg => {
    const cwd = isAbsolute(arg) ? arg : resolve(process.cwd(), arg);
    if (!existsSync(cwd)) {
      console.error(chalk.red(`Error! Directory or file does not exist: ${cwd}`));
      process.exit(1);
    }
    return cwd;
  });

  if (!flags.verbose) {
    options['stdio'] = 'ignore';
    if (process.platform === 'darwin') {
      //Use `open` to prevent multiple Hyper process
      const cmd = `open -b co.zeit.hyper ${args_}`;
      const opts = {
        env
      };
      return pify(exec)(cmd, opts);
    }
  }

  const child = spawn(process.execPath, args_, options);

  if (flags.verbose) {
    child.stdout.on('data', data => console.log(data.toString('utf8')));
    child.stderr.on('data', data => console.error(data.toString('utf8')));
  }
  if (flags.verbose) {
    return new Promise(c => child.once('exit', () => c(null)));
  }
  child.unref();
  return Promise.resolve();
};

function eventuallyExit(code) {
  setTimeout(() => process.exit(code), 100);
}

main(process.argv)
  .then(() => eventuallyExit(0))
  .catch(err => {
    console.error(err.stack ? err.stack : err);
    eventuallyExit(1);
  });


text:
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Function template is_in_range</title>
<link rel="stylesheet" href="../../../../../../../doc/src/boostbook.css" type="text/css">
<meta name="generator" content="DocBook XSL Stylesheets V1.78.1">
<link rel="home" href="../../../index.html" title="Chapter 1. Boost.Log v2">
<link rel="up" href="../../../expressions.html#header.boost.log.expressions.predicates.is_in_range_hpp" title="Header <boost/log/expressions/predicates/is_in_range.hpp>">
<link rel="prev" href="is_in_range_idp43487872.html" title="Function template is_in_range">
<link rel="next" href="attribute_matches.html" title="Class template attribute_matches">

Function template is_in_range

boost::log::expressions::is_in_range

Synopsis

// In header: <boost/log/expressions/predicates/is_in_range.hpp>

template<typename T, typename BoundaryT>
  unspecified is_in_range(attribute_name const & name,
                          BoundaryT const & least, BoundaryT const & most);

Description

The function generates a terminal node in a template expression. The node will check if the attribute value is in the specified range. The range must be half-open, that is the predicate will be equivalent to least <= attr < most.

Copyright © 2007-2015 Andrey
      Semashev

        Distributed under the Boost Software License, Version 1.0. (See accompanying
        file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt).


text:
Computes the convex hull of a collection of points in general position by incremental insertion.  No attempt is made to handle degeneracies.

This module is meant to be used internally by other modules for calculating convex hulls and Delaunay triangulations.  You probably shouldn't call it directly unless you know what you are doing.  Instead, there will (eventually) be a wrapper over this module that handles all the special cases and correctly generates a convex hull.

[![testling badge](https://ci.testling.com/mikolalysenko/incremental-convex-hull.png)](https://ci.testling.com/mikolalysenko/incremental-convex-hull)

[![build status](https://secure.travis-ci.org/mikolalysenko/incremental-convex-hull.png)](http://travis-ci.org/mikolalysenko/incremental-convex-hull)

# Example

```javascript
var ch = require("incremental-convex-hull")
var points = [
  [0, 0, 0],
  [0, 0, 1],
  [0, 1, 0],
  [1, 0, 0],
  [1, 1, 1]
]
console.log(ch(points))
```

Output:

```javascript
[ [ 0, 2, 3 ],
  [ 1, 0, 3 ],
  [ 0, 1, 2 ],
  [ 2, 4, 3 ],
  [ 4, 1, 3 ],
  [ 1, 4, 2 ] ]
```

# Install

```
npm install incremental-convex-hull
```

# API

#### `require("incremental-convex-hull")(points[, randomInsert])`
Constructs a triangulation of the convex hull of `points` by incremental insertion.

* `points` is a list of points
* `randomInsert` is a flag, which if set uses a randomized jump and walk instead of walking from the last inserted facet.

**Returns** A list of the boundary cells of the convex hull of the point cloud.

**Notes** This module works in any dimension greater than 2, though becomes pretty slow after 5d.

# License

(c) 2014 Mikola Lysenko. MIT License