text:
/***
 * \file InversePerspectiveMapping.cc
 * \author Mohamed Aly <malaa@caltech.edu>
 * \date 11/29/2006
 */

#include "InversePerspectiveMapping.hh"

#include "CameraInfoOpt.h"

#include <iostream>
#include <math.h>
#include <assert.h>
#include <list>

using namespace std;
#include <cv.h>
#include <highgui.h>

namespace LaneDetector
{

#define VP_PORTION 0.05

/*
 We are assuming the world coordinate frame center is at the camera,
 the ground plane is at height -h, the X-axis is going right,
 the Y-axis is going forward, the Z-axis is going up. The
 camera is looking forward with optical axis in direction of
 Y-axis, with possible pitch angle (above or below the Y-axis)
 and yaw angle (left or right).
 The camera coordinates have the same center as the world, but the Xc-axis goes right,
 the  Yc-axis goes down, and the Zc-axis (optical cxis) goes forward. The
 uv-plane of the image is such that u is horizontal going right, v is
 vertical going down.
 The image coordinates uv are such that the pixels are at half coordinates
 i.e. first pixel is (.5,.5) ...etc where the top-left point is (0,0) i.e.
 the tip of the first pixel is (0,0)
*/

/**
 * This function returns the Inverse Perspective Mapping
 * of the input image, assuming a flat ground plane, and
 * given the camera parameters.
 *
 * \param inImage the input image
 * \param outImage the output image in IPM
 * \param ipmInfo the returned IPM info for the transformation
 * \param focalLength focal length (in x and y direction)
 * \param cameraInfo the camera parameters
 * \param outPoints indices of points outside the image
 */
void mcvGetIPM(const CvMat* inImage, CvMat* outImage,
               IPMInfo *ipmInfo, const CameraInfo *cameraInfo,
               list<CvPoint> *outPoints)
{
  //check input images types
  //CvMat inMat, outMat;
  //cvGetMat(inImage, &inMat);
  //cvGetMat(outImage, &outMat);
  //cout << CV_MAT_TYPE(inImage->type) << " " << CV_MAT_TYPE(FLOAT_MAT_TYPE) <<  " " << CV_MAT_TYPE(INT_MAT_TYPE)<<"\n";
  if (!(CV_ARE_TYPES_EQ(inImage, outImage) &&
      (CV_MAT_TYPE(inImage->type)==CV_MAT_TYPE(FLOAT_MAT_TYPE) ||
      (CV_MAT_TYPE(inImage->type)==CV_MAT_TYPE(INT_MAT_TYPE)))))
  {
    cerr << "Unsupported image types in mcvGetIPM";
    exit(1);
  }

  //get size of input image
  FLOAT u, v;
  v = inImage->height;
  u = inImage->width;

  //get the vanishing point
  FLOAT_POINT2D vp;
  vp = mcvGetVanishingPoint(cameraInfo);
  vp.y = MAX(0, vp.y);
  //vp.y = 30;

  //get extent of the image in the xfyf plane
  FLOAT_MAT_ELEM_TYPE eps = ipmInfo->vpPortion * v;//VP_PORTION*v;
  ipmInfo->ipmLeft = MAX(0, ipmInfo->ipmLeft);
  ipmInfo->ipmRight = MIN(u-1, ipmInfo->ipmRight);
  ipmInfo->ipmTop = MAX(vp.y+eps, ipmInfo->ipmTop);
  ipmInfo->ipmBottom = MIN(v-1, ipmInfo->ipmBottom);
  FLOAT_MAT_ELEM_TYPE uvLimitsp[] = {vp.x,
    ipmInfo->ipmRight, ipmInfo->ipmLeft, vp.x,
    ipmInfo->ipmTop, ipmInfo->ipmTop,   ipmInfo->ipmTop,  ipmInfo->ipmBottom};
	//{vp.x, u, 0, vp.x,
	//vp.y+eps, vp.y+eps, vp.y+eps, v};
  CvMat uvLimits = cvMat(2, 4, FLOAT_MAT_TYPE, uvLimitsp);

/*
  // **** Debug *****
  // print camera info
  printf("\nCamera info\n");
  printf("Yaw: %f\n",cameraInfo->yaw);
  printf("Pitch: %f\n",cameraInfo->pitch);
  printf("Focal Length x: %f\n",cameraInfo->focalLength.x);
  printf("Focal Length y: %f\n",cameraInfo->focalLength.y);
  printf("Optical Center x: %f\n",cameraInfo->opticalCenter.x);
  printf("Optical Center y: %f\n",cameraInfo->opticalCenter.y);
  printf("Camera Heigth: %f\n",cameraInfo->cameraHeight);
  printf("Vanishing point x: %f\n",vp.x);
  printf("Vanishing point y: %f\n",vp.y);

  // **** Debug *****
  // print IPM info
  printf("\nIPM info\n");
  printf("VP Portion: %f\n",ipmInfo->vpPortion);
  printf("IPM Left: %f\n",ipmInfo->ipmLeft);
  printf("IPM Right: %f\n",ipmInfo->ipmRight);
  printf("IPM Top: %f\n",ipmInfo->ipmTop);
  printf("IPM Bottom: %f\n",ipmInfo->ipmBottom);

  //printf("\nImage Frame: uvLimits\n");
  //printf("%f\t%f\t%f\t%f\t\n",uvLimitsp[0],uvLimitsp[1],uvLimitsp[2],uvLimitsp[3]);
  //printf("%f\t%f\t%f\t%f\t\n",uvLimitsp[4],uvLimitsp[5],uvLimitsp[6],uvLimitsp[7]);

  SHOW_MAT(&uvLimits, "uvLImits");

  CvMat* debugDisp = cvCloneMat(inImage);

  CvPoint test = CvPoint(int(vp.x),int(ipmInfo->ipmRight));
  //cvCircle(debugDisp, CvPoint(int(vp.x),int(ipmInfo->ipmTop)), 3, CV_RGB(255,255,0), 1,8,0);
  cvCircle(debugDisp, CvPoint(int(ipmInfo->ipmRight),int(ipmInfo->ipmTop)), 3, CV_RGB(255,255,0), 1,8,0);
  cvCircle(debugDisp, CvPoint(int(ipmInfo->ipmLeft),int(ipmInfo->ipmTop)), 3, CV_RGB(255,255,0), 1,8,0);
  cvCircle(debugDisp, CvPoint(int(vp.x),int(ipmInfo->ipmBottom)), 3, CV_RGB(255,255,0), 1,8,0);
  //cvCircle(debugDisp, CvPoint(int(vp.x),int(vp.y)), 3, CV_RGB(255,255,0), 1,8,0);

  SHOW_IMAGE(debugDisp,"uvLimits",10);

 char key = cvWaitKey(0);
*/

  //get these points on the ground plane
  CvMat * xyLimitsp = cvCreateMat(2, 4, FLOAT_MAT_TYPE);
  CvMat xyLimits = *xyLimitsp;
  mcvTransformImage2Ground(&uvLimits, &xyLimits,cameraInfo);
  //SHOW_MAT(xyLimitsp, "xyLImits");

  //get extent on the ground plane
  CvMat row1, row2;
  cvGetRow(&xyLimits, &row1, 0);
  cvGetRow(&xyLimits, &row2, 1);
  double xfMax, xfMin, yfMax, yfMin;
  cvMinMaxLoc(&row1, (double*)&xfMin, (double*)&xfMax, 0, 0, 0);
  cvMinMaxLoc(&row2, (double*)&yfMin, (double*)&yfMax, 0, 0, 0);

  INT outRow = outImage->height;
  INT outCol = outImage->width;

  FLOAT_MAT_ELEM_TYPE stepRow = (yfMax-yfMin)/outRow;
  FLOAT_MAT_ELEM_TYPE stepCol = (xfMax-xfMin)/outCol;

  //construct the grid to sample
  CvMat *xyGrid = cvCreateMat(2, outRow*outCol, FLOAT_MAT_TYPE);
  INT i, j;
  FLOAT_MAT_ELEM_TYPE x, y;
  //fill it with x-y values on the ground plane in world frame
  for (i=0, y=yfMax-.5*stepRow; i<outRow; i++, y-=stepRow)
    for (j=0, x=xfMin+.5*stepCol; j<outCol; j++, x+=stepCol)
    {
      CV_MAT_ELEM(*xyGrid, FLOAT_MAT_ELEM_TYPE, 0, i*outCol+j) = x;
      CV_MAT_ELEM(*xyGrid, FLOAT_MAT_ELEM_TYPE, 1, i*outCol+j) = y;
    }
  //get their pixel values in image frame
  CvMat *uvGrid = cvCreateMat(2, outRow*outCol, FLOAT_MAT_TYPE);
  mcvTransformGround2Image(xyGrid, uvGrid, cameraInfo);
  //now loop and find the nearest pixel value for each position
  //that's inside the image, otherwise put it zero
  FLOAT_MAT_ELEM_TYPE ui, vi;
  //get mean of the input image
  CvScalar means = cvAvg(inImage);
  double mean = means.val[0];
  //generic loop to work for both float and int matrix types
  #define MCV_GET_IPM(type) \
  for (i=0; i<outRow; i++) \
      for (j=0; j<outCol; j++) \
      { \
          /*get pixel coordiantes*/ \
          ui = CV_MAT_ELEM(*uvGrid, FLOAT_MAT_ELEM_TYPE, 0, i*outCol+j); \
          vi = CV_MAT_ELEM(*uvGrid, FLOAT_MAT_ELEM_TYPE, 1, i*outCol+j); \
          /*check if out-of-bounds*/ \
          /*if (ui<0 || ui>u-1 || vi<0 || vi>v-1) \*/ \
          if (ui<ipmInfo->ipmLeft || ui>ipmInfo->ipmRight || \
              vi<ipmInfo->ipmTop || vi>ipmInfo->ipmBottom) \
          { \
              CV_MAT_ELEM(*outImage, type, i, j) = (type)mean; \
          } \
          /*not out of bounds, then get nearest neighbor*/ \
          else \
          { \
              /*Bilinear interpolation*/ \
              if (ipmInfo->ipmInterpolation == 0) \
              { \
                  int x1 = int(ui), x2 = int(ui+1); \
                  int y1 = int(vi), y2 = int(vi+1); \
                  float x = ui - x1, y = vi - y1;   \
                  float val = CV_MAT_ELEM(*inImage, type, y1, x1) * (1-x) * (1-y) + \
                      CV_MAT_ELEM(*inImage, type, y1, x2) * x * (1-y) + \
                      CV_MAT_ELEM(*inImage, type, y2, x1) * (1-x) * y + \
                      CV_MAT_ELEM(*inImage, type, y2, x2) * x * y;   \
                  CV_MAT_ELEM(*outImage, type, i, j) =  (type)val; \
  } \
              /*nearest-neighbor interpolation*/ \
              else \
                  CV_MAT_ELEM(*outImage, type, i, j) = \
                      CV_MAT_ELEM(*inImage, type, int(vi+.5), int(ui+.5)); \
          } \
          if (outPoints && \
              (ui<ipmInfo->ipmLeft+10 || ui>ipmInfo->ipmRight-10 || \
              vi<ipmInfo->ipmTop || vi>ipmInfo->ipmBottom-2) )\
              outPoints->push_back(cvPoint(j, i)); \
      }
  if (CV_MAT_TYPE(inImage->type)==FLOAT_MAT_TYPE)
  {
      MCV_GET_IPM(FLOAT_MAT_ELEM_TYPE)
  }
  else
  {
      MCV_GET_IPM(INT_MAT_ELEM_TYPE)
  }
  //return the ipm info
  ipmInfo->xLimits[0] = CV_MAT_ELEM(*xyGrid, FLOAT_MAT_ELEM_TYPE, 0, 0);
  ipmInfo->xLimits[1] =
    CV_MAT_ELEM(*xyGrid, FLOAT_MAT_ELEM_TYPE, 0, (outRow-1)*outCol+outCol-1);
  ipmInfo->yLimits[1] = CV_MAT_ELEM(*xyGrid, FLOAT_MAT_ELEM_TYPE, 1, 0);
  ipmInfo->yLimits[0] =
    CV_MAT_ELEM(*xyGrid, FLOAT_MAT_ELEM_TYPE, 1, (outRow-1)*outCol+outCol-1);
  ipmInfo->xScale = 1/stepCol;
  ipmInfo->yScale = 1/stepRow;
  ipmInfo->width = outCol;
  ipmInfo->height = outRow;

  //clean
  cvReleaseMat(&xyLimitsp);
  cvReleaseMat(&xyGrid);
  cvReleaseMat(&uvGrid);
}

/**
 * Transforms points from the image frame (uv-coordinates)
 * into the real world frame on the ground plane (z=-height)
 *
 * \param inPoints input points in the image frame
 * \param outPoints output points in the world frame on the ground
 *          (z=-height)
 * \param cemaraInfo the input camera parameters
 *
 */
void mcvTransformImage2Ground(const CvMat *inPoints,
                              CvMat *outPoints, const CameraInfo *cameraInfo)
{

  //add two rows to the input points
  CvMat *inPoints4 = cvCreateMat(inPoints->rows+2, inPoints->cols,
      cvGetElemType(inPoints));

  //copy inPoints to first two rows
  CvMat inPoints2, inPoints3, inPointsr4, inPointsr3;
  cvGetRows(inPoints4, &inPoints2, 0, 2);
  cvGetRows(inPoints4, &inPoints3, 0, 3);
  cvGetRow(inPoints4, &inPointsr3, 2);
  cvGetRow(inPoints4, &inPointsr4, 3);
  cvSet(&inPointsr3, cvRealScalar(1));
  cvCopy(inPoints, &inPoints2);
  //create the transformation matrix
  float c1 = cos(cameraInfo->pitch);
  float s1 = sin(cameraInfo->pitch);
  float c2 = cos(cameraInfo->yaw);
  float s2 = sin(cameraInfo->yaw);
  float matp[] = {
    -cameraInfo->cameraHeight*c2/cameraInfo->focalLength.x,
    cameraInfo->cameraHeight*s1*s2/cameraInfo->focalLength.y,
    (cameraInfo->cameraHeight*c2*cameraInfo->opticalCenter.x/
      cameraInfo->focalLength.x)-
      (cameraInfo->cameraHeight *s1*s2* cameraInfo->opticalCenter.y/
      cameraInfo->focalLength.y) - cameraInfo->cameraHeight *c1*s2,

    cameraInfo->cameraHeight *s2 /cameraInfo->focalLength.x,
    cameraInfo->cameraHeight *s1*c2 /cameraInfo->focalLength.y,
    (-cameraInfo->cameraHeight *s2* cameraInfo->opticalCenter.x
      /cameraInfo->focalLength.x)-(cameraInfo->cameraHeight *s1*c2*
      cameraInfo->opticalCenter.y /cameraInfo->focalLength.y) -
      cameraInfo->cameraHeight *c1*c2,

    0,
    cameraInfo->cameraHeight *c1 /cameraInfo->focalLength.y,
    (-cameraInfo->cameraHeight *c1* cameraInfo->opticalCenter.y /
      cameraInfo->focalLength.y) + cameraInfo->cameraHeight *s1,

    0,
    -c1 /cameraInfo->focalLength.y,
    (c1* cameraInfo->opticalCenter.y /cameraInfo->focalLength.y) - s1,
  };
  CvMat mat = cvMat(4, 3, CV_32FC1, matp);
  //multiply
  cvMatMul(&mat, &inPoints3, inPoints4);
  //divide by last row of inPoints4
  for (int i=0; i<inPoints->cols; i++)
  {
    float div = CV_MAT_ELEM(inPointsr4, float, 0, i);
    CV_MAT_ELEM(*inPoints4, float, 0, i) =
        CV_MAT_ELEM(*inPoints4, float, 0, i) / div ;
    CV_MAT_ELEM(*inPoints4, float, 1, i) =
        CV_MAT_ELEM(*inPoints4, float, 1, i) / div;
  }
  //put back the result into outPoints
  cvCopy(&inPoints2, outPoints);
  //clear
  cvReleaseMat(&inPoints4);
}

/**
 * Transforms points from the ground plane (z=-h) in the world frame
 * into points on the image in image frame (uv-coordinates)
 *
 * \param inPoints 2xN array of input points on the ground in world coordinates
 * \param outPoints 2xN output points in on the image in image coordinates
 * \param cameraInfo the camera parameters
 *
 */
void mcvTransformGround2Image(const CvMat *inPoints,
                              CvMat *outPoints, const CameraInfo *cameraInfo)
{
  //add two rows to the input points
  CvMat *inPoints3 = cvCreateMat(inPoints->rows+1, inPoints->cols,
      cvGetElemType(inPoints));

  //copy inPoints to first two rows
  CvMat inPoints2,  inPointsr3;
  cvGetRows(inPoints3, &inPoints2, 0, 2);
  cvGetRow(inPoints3, &inPointsr3, 2);
  cvSet(&inPointsr3, cvRealScalar(-cameraInfo->cameraHeight));
  cvCopy(inPoints, &inPoints2);
  //create the transformation matrix
  float c1 = cos(cameraInfo->pitch);
  float s1 = sin(cameraInfo->pitch);
  float c2 = cos(cameraInfo->yaw);
  float s2 = sin(cameraInfo->yaw);
  float matp[] = {
    cameraInfo->focalLength.x * c2 + c1*s2* cameraInfo->opticalCenter.x,
    -cameraInfo->focalLength.x * s2 + c1*c2* cameraInfo->opticalCenter.x,
    - s1 * cameraInfo->opticalCenter.x,

    s2 * (-cameraInfo->focalLength.y * s1 + c1* cameraInfo->opticalCenter.y),
    c2 * (-cameraInfo->focalLength.y * s1 + c1* cameraInfo->opticalCenter.y),
    -cameraInfo->focalLength.y * c1 - s1* cameraInfo->opticalCenter.y,

    c1*s2,
    c1*c2,
    -s1
  };
  CvMat mat = cvMat(3, 3, CV_32FC1, matp);
  //multiply
  cvMatMul(&mat, inPoints3, inPoints3);
  //divide by last row of inPoints4
  for (int i=0; i<inPoints->cols; i++)
  {
    float div = CV_MAT_ELEM(inPointsr3, float, 0, i);
    CV_MAT_ELEM(*inPoints3, float, 0, i) =
        CV_MAT_ELEM(*inPoints3, float, 0, i) / div ;
    CV_MAT_ELEM(*inPoints3, float, 1, i) =
        CV_MAT_ELEM(*inPoints3, float, 1, i) / div;
  }
  //put back the result into outPoints
  cvCopy(&inPoints2, outPoints);
  //clear
  cvReleaseMat(&inPoints3);
}

/**
 * Computes the vanishing point in the image plane uv. It is
 * the point of intersection of the image plane with the line
 * in the XY-plane in the world coordinates that makes an
 * angle yaw clockwise (form Y-axis) with Y-axis
 *
 * \param cameraInfo the input camera parameter
 *
 * \return the computed vanishing point in image frame
 *
 */
FLOAT_POINT2D mcvGetVanishingPoint(const CameraInfo *cameraInfo)
{
  //get the vp in world coordinates
  FLOAT_MAT_ELEM_TYPE vpp[] = {sin(cameraInfo->yaw)/cos(cameraInfo->pitch),
          cos(cameraInfo->yaw)/cos(cameraInfo->pitch), 0};
  CvMat vp = cvMat(3, 1, FLOAT_MAT_TYPE, vpp);

  //transform from world to camera coordinates
  //
  //rotation matrix for yaw
  FLOAT_MAT_ELEM_TYPE tyawp[] = {cos(cameraInfo->yaw), -sin(cameraInfo->yaw), 0,
                sin(cameraInfo->yaw), cos(cameraInfo->yaw), 0,
                0, 0, 1};
  CvMat tyaw = cvMat(3, 3, FLOAT_MAT_TYPE, tyawp);
  //rotation matrix for pitch
  FLOAT_MAT_ELEM_TYPE tpitchp[] = {1, 0, 0,
                  0, -sin(cameraInfo->pitch), -cos(cameraInfo->pitch),
                  0, cos(cameraInfo->pitch), -sin(cameraInfo->pitch)};
  CvMat transform = cvMat(3, 3, FLOAT_MAT_TYPE, tpitchp);
  //combined transform
  cvMatMul(&transform, &tyaw, &transform);

  //
  //transformation from (xc, yc) in camra coordinates
  // to (u,v) in image frame
  //
  //matrix to shift optical center and focal length
  FLOAT_MAT_ELEM_TYPE t1p[] = {
    cameraInfo->focalLength.x, 0,
    cameraInfo->opticalCenter.x,
    0, cameraInfo->focalLength.y,
    cameraInfo->opticalCenter.y,
    0, 0, 1};
  CvMat t1 = cvMat(3, 3, FLOAT_MAT_TYPE, t1p);
  //combine transform
  cvMatMul(&t1, &transform, &transform);
  //transform
  cvMatMul(&transform, &vp, &vp);

  //
  //clean and return
  //
  FLOAT_POINT2D ret;
  ret.x = cvGetReal1D(&vp, 0);
  ret.y = cvGetReal1D(&vp, 1);
  return ret;
}

/**
 * Converts a point from IPM pixel coordinates into world coordinates
 *
 * \param point in/out point
 * \param ipmInfo the ipm info from mcvGetIPM
 *
 */
void mcvPointImIPM2World(FLOAT_POINT2D *point, const IPMInfo *ipmInfo)
{
  //x-direction
  point->x /= ipmInfo->xScale;
  point->x += ipmInfo->xLimits[0];
  //y-direction
  point->y /= ipmInfo->yScale;
  point->y = ipmInfo->yLimits[1] - point->y;
}

/**
 * Converts from IPM pixel coordinates into world coordinates
 *
 * \param inMat input matrix 2xN
 * \param outMat output matrix 2xN
 * \param ipmInfo the ipm info from mcvGetIPM
 *
 */
void mcvTransformImIPM2Ground(const CvMat *inMat, CvMat* outMat, const IPMInfo *ipmInfo)
{
  CvMat *mat;
  mat = outMat;
  if(inMat != mat)
  {
    cvCopy(inMat, mat);
  }

  //work on the x-direction i.e. first row
  CvMat row;
  cvGetRow(mat, &row, 0);
  cvConvertScale(&row, &row, 1./ipmInfo->xScale, ipmInfo->xLimits[0]);

  //work on y-direction
  cvGetRow(mat, &row, 1);
  cvConvertScale(&row, &row, -1./ipmInfo->yScale, ipmInfo->yLimits[1]);
}

/**
 * Converts from IPM pixel coordinates into Image coordinates
 *
 * \param inMat input matrix 2xN
 * \param outMat output matrix 2xN
 * \param ipmInfo the ipm info from mcvGetIPM
 * \param cameraInfo the camera info
 *
 */
void mcvTransformImIPM2Im(const CvMat *inMat, CvMat* outMat, const IPMInfo *ipmInfo,
			  const CameraInfo *cameraInfo)
{
  //convert to world coordinates
  mcvTransformImIPM2Ground(inMat, outMat, ipmInfo);

  //convert to image coordinates
  mcvTransformGround2Image(outMat, outMat, cameraInfo);

}

/**
 * Initializes the cameraInfo structure with data read from the conf file
 *
 * \param fileName the input camera conf file name
 * \param cameraInfo the returned camera parametrs struct
 *
 */
void mcvInitCameraInfo (char * const fileName, CameraInfo *cameraInfo)
{
  //parsed camera data
  CameraInfoParserInfo camInfo;
  //read the data
  assert(cameraInfoParser_configfile(fileName, &camInfo, 0, 1, 1)==0);
  //init the strucure
  cameraInfo->focalLength.x = camInfo.focalLengthX_arg;
  cameraInfo->focalLength.y = camInfo.focalLengthY_arg;
  cameraInfo->opticalCenter.x = camInfo.opticalCenterX_arg;
  cameraInfo->opticalCenter.y = camInfo.opticalCenterY_arg;
  cameraInfo->cameraHeight = camInfo.cameraHeight_arg;
  cameraInfo->pitch = camInfo.pitch_arg * CV_PI/180;
  cameraInfo->yaw = camInfo.yaw_arg * CV_PI/180;
  cameraInfo->imageWidth = camInfo.imageWidth_arg;
  cameraInfo->imageHeight = camInfo.imageHeight_arg;
}

/**
 * Scales the cameraInfo according to the input image size
 *
 * \param cameraInfo the input/return structure
 * \param size the input image size
 *
 */
 void mcvScaleCameraInfo (CameraInfo *cameraInfo, CvSize size)
 {
  //compute the scale factor
  double scaleX = size.width/cameraInfo->imageWidth;
  double scaleY = size.height/cameraInfo->imageHeight;
  //scale
  cameraInfo->imageWidth = size.width;
  cameraInfo->imageHeight = size.height;
  cameraInfo->focalLength.x *= scaleX;
  cameraInfo->focalLength.y *= scaleY;
  cameraInfo->opticalCenter.x *= scaleX;
  cameraInfo->opticalCenter.y *= scaleY;
 }

/**
 * Gets the extent of the image on the ground plane given the camera parameters
 *
 * \param cameraInfo the input camera info
 * \param ipmInfo the IPM info containing the extent on ground plane:
 *  xLimits & yLimits only are changed
 *
 */
void mcvGetIPMExtent(const CameraInfo *cameraInfo, IPMInfo *ipmInfo )
{
  //get size of input image
  FLOAT u, v;
  v = cameraInfo->imageHeight;
  u = cameraInfo->imageWidth;

  //get the vanishing point
  FLOAT_POINT2D vp;
  vp = mcvGetVanishingPoint(cameraInfo);
  vp.y = MAX(0, vp.y);

  //get extent of the image in the xfyf plane
  FLOAT_MAT_ELEM_TYPE eps = VP_PORTION*v;
  FLOAT_MAT_ELEM_TYPE uvLimitsp[] = {vp.x, u, 0, vp.x,
                      vp.y+eps, vp.y+eps, vp.y+eps, v};
  CvMat uvLimits = cvMat(2, 4, FLOAT_MAT_TYPE, uvLimitsp);

  //get these points on the ground plane
  CvMat * xyLimitsp = cvCreateMat(2, 4, FLOAT_MAT_TYPE);
  CvMat xyLimits = *xyLimitsp;
  mcvTransformImage2Ground(&uvLimits, &xyLimits,cameraInfo);
  //SHOW_MAT(xyLimitsp, "xyLImits");

  //get extent on the ground plane
  CvMat row1, row2;
  cvGetRow(&xyLimits, &row1, 0);
  cvGetRow(&xyLimits, &row2, 1);
  double xfMax, xfMin, yfMax, yfMin;
  cvMinMaxLoc(&row1, (double*)&xfMin, (double*)&xfMax, 0, 0, 0);
  cvMinMaxLoc(&row2, (double*)&yfMin, (double*)&yfMax, 0, 0, 0);

  //return
  ipmInfo->xLimits[0] = xfMin;
  ipmInfo->xLimits[1] = xfMax;
  ipmInfo->yLimits[1] = yfMax;
  ipmInfo->yLimits[0] = yfMin;

}

} // namespace LaneDetector


text:
---
layout: article
title: Programmer des jeux sous Linux avec SDL <br/>Partie III
description: Gestion des évènements
section: Linux Programming
redirect_from: /SDL/progsdl3.html
tags:
- linux
- programming
- SDL
seo:
  type: TechArticle
locale: fr_FR
published: Planète Linux numéro 5
---
## Gestion des évènements

Le numéro précédent traitait de la programmation graphique par l'intermédiaire de la librairie SDL. Cet article aborde la gestion des événements, ce qui va vous permettre d'ajouter un peu d'interactivité avec l'utilisateur, via le clavier et la souris.

Il est à noter que, dans la version actuelle de SDL, les joysticks ne sont pas encore supportés. Cependant, cela ne saurait tarder (n'oublions pas que Loki se sert de SDL pour la réalisation de ses jeux), le support de ce type de périphérique étant nécessaire à nombre de jeux vidéo.

SDL aborde la gestion des événements par l'intermédiaire d'une file ('event queue'), similaire aux files d'événements présentes dans la plupart des systèmes d'interface graphique, que ce soit X11, Win32, ou MacOS. La librairie prend en charge l'insertion des éléments dans la file, au fur et à mesure qu'ils se produisent. Il est ensuite à la charge de l'application de retirer les événements de la file d'attente et de les traiter en conséquence. SDL permet une gestion de la file des événements dans une thread séparée, afin qu'il n'y ait pas d'interférence avec le programme principal. La thread des événements sera ainsi chargée de surveiller en permanence l'arrivée de nouveaux événements X11, en parallèle avec le programme, assurant que ceux-ci seront traités aussi vite que possible.

### Initialisation de SDL

Il n'est pas nécessaire de passer d'argument supplémentaire à la fonction `SDL_Init()`, la gestion des événements étant toujours démarrée par défaut avec le sous-système graphique (**SDL_INIT_VIDEO**). Cependant, il existe le flag **SDL_INIT_EVENTTHREAD** qui peut être combiné et permet l'activation de la gestion threadée des événements. Cela suppose certaines implications que nous verrons plus loin dans cet article. Certaines fonctions de base permettent d'accéder à la file d'événements. Chaque événement SDL est représenté par le type `SDL_Event`, défini comme une union C des différents sous-types possibles :

{% highlight c %}
typedef union {
        Uint8 type;
        SDL_ActiveEvent active;
        SDL_KeyboardEvent key;
        SDL_MouseMotionEvent motion;
        SDL_MouseButtonEvent button;
        SDL_QuitEvent quit;
        SDL_SysWMEvent syswm;
} SDL_Event;
{% endhighlight %}

Le champ `type` permet d'identifier le type de l'événement, parmi les valeurs suivantes : **SDL_ACTIVEEVENT**, **SDL_KEYDOWN**, **SDL_KEYUP**, **SDL_MOUSEMOTION**, **SDL_MOUSEBUTTONUP**, **SDL_MOUSEBUTTONDOWN**, **SDL_SYSWMEVENT**, **SDL_QUIT**.

### Manipulation de la queue

Elle se fait par l'intermédiaire des cinq fonctions suivantes :

{% highlight c %}
void SDL_PumpEvents(void);
{% endhighlight %}

Cette fonction permet de laisser SDL remplir la file d'événements avec ceux en attente sur le système (mise à jour de la file). Cette fonction est généralement appelée dans la boucle principale de gestion des événements de l'application (voir l'exemple ci-dessous).

{% highlight c %}
int SDL_PollEvent(SDL_Event *event);
{% endhighlight %}

Essaie de sortir un événement de la file d'attente (opération non bloquante). La fonction retourne 0, si aucun événement n'est disponible et 1, dans le cas contraire. L'événement éventuellement récupéré est stocké dans la structure dont l'adresse est fournie en paramètre et qui peut être `NULL`, si l'on désire simplement ne pas en tenir compte.

{% highlight c %}
int SDL_WaitEvent(SDL_Event *event);
{% endhighlight %}

Il s'agit de la variante bloquante de `SDL_PollEvent()`, autrement dit la fonction ne finit que lorsqu'un événement est disponible (auquel cas la valeur retournée est 1), ou en cas d'erreur (retourne 0).

{% highlight c %}
int SDL_PeepEvents(SDL_Event *events, int numevents, SDL_eventaction action, Uint32 mask);
{% endhighlight %}

Cette fonction permet une manipulation plus poussée de la file d'événements. Plusieurs opérations sont disponibles, comme l'indiquent les valeurs possibles du paramètre 'action':

* **SDL_ADDEVENT** : `numevents` événements sont ajoutés à la file.
* **SDL_PEEKEVENT** : Jusqu'à `numevents` événements en attente sont lus dans la file, mais ceux-ci n'en sont pas extraits (utiliser **GETEVENT** à cet effet).
* **SDL_GETEVENT** : Comme pour **PEEKEVENT**, mais les événements lus sont retirés de la file.

Le paramètre `mask` optionnel indique un masque des événements à extraire qui est une combinaison binaire.

{% highlight c %}
Uint8 SDL_EventState(Uint8 type, int state);
{% endhighlight %}

Cette fonction permet de changer la manière dont sont traités certains types d'événements. Le paramètre `type` indique les types d'événements auxquels la fonction s'applique et `state` peut avoir l'une des valeurs suivantes :

* **SDL_IGNORE** : les événements seront ignorés et ne seront donc plus mis dans la file.
* **SDL_ENABLE** : active certains types d'événements qui étaient auparavant ignorés.
* **SDL_QUERY** : la fonction retourne l'état actuel de traitement des événements spécifiés, c'est-à-dire soit **SDL_IGNORE**, soit **SDL_ENABLE**.

### Types d'événements

Le champ `type` de `SDL_Event` indique le type d'événement reçu. Suivant la valeur de celui-ci, il faudra consulter l'un des champs de la structure, et lui seul (les autres n'étant pas valides pour le 'type' spécifié) !

**Fin d'application (SDL_QUIT) :** cet événement est reçu lorsque l'utilisateur a requis la fin de l'application de manière indirecte, c'est-à-dire s'il a tenté de fermer la fenêtre X11 de l'application ou s'il a utilisé la combinaison de touche Control-C. Cela permet de terminer proprement le programme dans ces conditions. Aucune autre information n'est fournie par SDL pour ce type d'événement.

**Evénements d'activation (SDL_ACTIVEEVENT) :** ces événements sont reçus pour indiquer des changements d'état de l'application, notamment si celle-ci a perdu le focus de la souris et/ou du clavier. Les détails de l'événement sont fournis dans le champ `active` de `SDL_Event` qui est du type suivant :

{% highlight c %}
typedef struct {
        Uint8 type; /* Le type d'événement, SDL_ACTIVEEVENT */
        Uint8 gain; /* Valeur booléenne indiquant s'il s'agit
                       d'un gain ou d'une perte */
        Uint8 state;/* Combinaison de SDL_APPMOUSEFOCUS,
                       SDL_APPINPUTFOCUS, SDL_APPACTIVE */
} SDL_ActiveEvent;
{% endhighlight %}

On peut donc savoir quand l'application perd le focus pour la souris, le clavier ou si, tout simplement, l'application est inactive (non disponible, comme lorsqu'elle est icônifiée sous X11).

La fonction `SDL_GetAppState(void)` permet de connaître l'état actuel de l'application, sous la forme d'une combinaison similaire au champ `state` ci-dessus.

**Clavier (SDL_KEYDOWN, SDL_KEYUP) :** la pression et le relâchement d'une touche sont signalés au programme par deux types d'événements distincts. Les détails sont dans le champ `key` de `SDL_Event` dont le type est le suivant :

{% highlight c %}
typedef struct {
Uint8 type;   /* Type d'événement: SDL_KEYDOWN
                         ou SDL_KEYUP */
        Uint8 state;  /* SDL_PRESSED ou SDL_RELEASED */
        SDL_keysym keysym;
} SDL_KeyboardEvent;
{% endhighlight %}

`state` indique donc si la touche décrite dans `keysym` a été enfoncée ou relâchée. Le type `SDL_keysym` est défini comme suit :

{% highlight c %}
typedef struct {
Uint8 scancode; /* Code dépendant du système, recueilli par SDL */
        SDLKey sym;     /* Symbole correspondant, abstrait par SDL */
        SDLMod mod;     /* Etat des modificateurs (Shift, Alt, Control, etc...)
*/
        Uint16 unicode; /* Caractère Unicode correspondant, si activé */
} SDL_keysym;
{% endhighlight %}

SDL définit un ensemble de symboles pour les touches les plus répandues et ces symboles sont portables entre les systèmes, au contraire du 'scancode' qui est dépendant de ceux-ci. Vous pourrez en consulter la liste complète dans le fichier `SDL_keysym.h`.

La fonction `SDL_EnableUNICODE(int enable)` permet d'activer/désactiver la gestion du mode Unicode (utile surtout pour les claviers non QWERTY). Concrètement, cela permet d'intercepter les touches non gérées directement par SDL. Sous X11, cette fonction laisse notamment le serveur X faire la traduction entre le code de la touche et son caractère ASCII.

Parmi les fonctions utilitaires liées au clavier, on trouve `SDL_GetKeyName(SDLKey key)` qui renvoie une chaîne de caractères décrivant "en clair" la touche passée en argument. La fonction `SDL_GetKeyState(int *numkeys)` permet de connaître l'état global du clavier par l'intermédiaire d'un tableau d'entiers 8 bits indexés par les valeurs du type `SDLKey`. Ainsi, si l'on voulait tester si la touche 'F' est enfoncée à l'aide de cette fonction, on ferait :

{% highlight c %}
	int numkeys; /* Taille du tableau renvoyé, en nombre de touches */
	Uint8 *ks = SDL_GetKeyState(&numkeys);
	if( ks[SDLK_f] ) {
		/* La touche F est enfoncée */
	}
{% endhighlight %}

Les modifieurs (qui sont en fait les touches Alt, Control, Shift et Meta) ont un état maintenu par SDL et rappelé avec chaque événement clavier. Néanmoins, des événements séparés sont envoyés lors de la pression ou la relâche de chacune de ces touches. La fonction `SDL_GetModState()` permet de savoir à tout moment l'état actuel des modifieurs. Il s'agit d'une combinaison des valeurs suivantes (une liste complète est dans `SDL_keysym.h`) : **KMOD_CTRL**, **KMOD_SHIFT**, **KMOD_ALT**, ...

**Souris (SDL_MOUSEBUTTONDOWN, SDL_MOUSEBUTTONUP, SDL_MOUSEMOTION) :** SDL gère l'état des 3 boutons de la souris, ainsi que le placement du curseur. La plupart du temps, le système sous-jacent est chargé de la gestion du curseur de la souris. Néanmoins, si le besoin s'en fait sentir, SDL est également capable de gérer par lui-même l'affichage du curseur (particulièrement dans les versions récentes de la librairie). Nous verrons ceci plus en détails, dans un prochain numéro de notre initiation.

Les événements **SDL_MOUSEMOTION**, déclenchés lors du déplacement du curseur, fournissent les détails suivants :

{% highlight c %}
typedef struct {
        Uint8 type;  /* Toujours SDL_MOUSEMOTION */
        Uint8 state;
        Uint16 x, y; /* Nouvelles coordonnées du curseur */
        Sint16 xrel;
        Sint16 yrel; /* Différences par rapport aux dernières
coordonnées */
} SDL_MouseMotionEvent;
{% endhighlight %}

De même, pour l'interaction avec les boutons, il faudra utiliser la structure suivante :

{% highlight c %}
typedef struct {
        Uint8 type; /* SDL_MOUSEBUTTONDOWN ou SDL_MOUSEBUTTONUP */
        Uint8 state;/* SDL_PRESSED ou SDL_RELEASED */
        Uint8 button; /* Numéro du bouton concerné */
        Uint16 x, y; /* Coordonnées du curseur au moment de
l'événement */
} SDL_MouseButtonEvent;
{% endhighlight %}

SDL gère les 3 boutons de la souris (numérotés de 1 à 3, 2 étant utilisé pour le bouton du milieu). La fonction `SDL_GetMouseState(Uint16 *x, Uint16 *y)` permet de récupérer de manière aisée la position actuelle du curseur. La fonction renvoie également une combinaison binaire indiquant l'état des boutons de la souris, état qui peut être testé à l'aide de la macro `SDL_BUTTON()`. A l'inverse, `SDL_WarpMouse()` permet de déplacer explicitement le curseur de la souris à un endroit précis, par rapport à la surface SDL principale (généralement la fenêtre de l'application). Un événement **SDL_MOUSEMOTION** est également généré dans ce cas.

**Evénements divers (SDL_SYSWMEVENT) :** si ceux-ci ont été activés, ils permettent de récupérer les événements dépendants du système et non interprétés directement par la librairie. Libre à vous d'en faire ce que bon vous semble ! Une utilisation possible est le couper/coller (clipboard) avec X11, ceci demandant l'interception d'événements spécifiques.

### Mise en place de filtres

Afin de garder un contrôle encore plus strict sur la nature des événements à traiter par SDL (et outre les attributs simples 'ignoré' et 'activé'), la fonction

{% highlight c %}
SDL_SetEventFilter(SDL_EventFilter filter);
{% endhighlight %}

permet la mise en place d'un filtre plus fin. Il s'agit, en fait, d'une fonction fournie par l'utilisateur et qui permettra ainsi un examen approfondi de chaque événement avant de décider s'il doit être ajouté dans la liste des événements.

Le type `SDL_EventFilter` est en fait un pointeur de fonction. Sa définition est la suivante :

{% highlight c %}
typedef int (*SDL_EventFilter)(const SDL_Event *event);
{% endhighlight %}

La fonction filtre devra renvoyer 1, si l'événement doit être enfilé et 0, dans le cas contraire. Le filtre est donc appelé après que SDL ait intercepté l'événement, mais avant que celui-ci ne soit mis dans la file.

### Enfin, l'exemple !

Si la gestion des événements à SDL peut paraître un peu indigeste au premier abord, en fait, elle est très facile à utiliser, comme le montre le programme de l'encadré 1. Ce programme ouvre une fenêtre SDL et met en place un filtre d'événements qui affiche les coordonnées du curseur de la souris. Rien de très visuel pour l'instant, mais c'est obligatoire si l'on veut garder les exemples suffisamment simples dans un premier temps. La fin du programme est déclenchée, soit par l'envoi de deux événements `SDL_QUIT` (fermeture de la fenêtre) ou de l'appui simultané de la touche Esc et de l'un des boutons de la souris (bien que les événements du clavier ne soient pas explicitement traités !).

Une nouvelle version de SDL, 0.11.x, a récemment été diffusée. Elle apporte un tout nouveau système de configuration/compilation (basé sur les outils GNU *autoconf* et *libtool*). Le processus de compilation est ainsi grandement facilité et cette nouvelle version apporte également son lot de corrections de bugs.

Dans le prochain article, nous aborderons un domaine complètement différent et nous apprendrons à faire du bruit avec SDL, grâce à la programmation audio... En attendant, amusez-vous bien avec les événements !

*Stéphane Peter*

----

SDL Home Page: [libsdl.org](http://www.libsdl.org)

### Encadré 1 : Un programme utilisant les événements.

{% highlight c %}
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>

int FilterEvents(const SDL_Event *event) {
  static int boycott = 1;

  /* This quit event signals the closing of the window */
  if ( (event->type == SDL_QUIT) && boycott ) {
printf("Evénement QUIT reçu et filtré. Le prochain quittera l'application.\n");
	boycott = 0;
	return(0);
  }
  if ( event->type == SDL_MOUSEMOTION ) {
	printf("Souris déplacée en (%d,%d)\n",
		   event->motion.x, event->motion.y);
	return(0);
  }
  return(1);
}

int main(int argc, char *argv[])
{
  SDL_Event event;

  /* Initialisation de la librairie */
  if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
	fprintf(stderr,
			"Erreur SDL: %s\n", SDL_GetError());
	exit(1);
  }

  atexit(SDL_Quit);

/* On ignore les événements du clavier */
  SDL_EventState(SDL_KEYDOWN, SDL_IGNORE);
  SDL_EventState(SDL_KEYUP, SDL_IGNORE);

  /* Mise en place du filtre pour le reste des événements */
  SDL_SetEventFilter(FilterEvents);

  /* Ouverture d'une fenêtre pour pouvoir intercepter les événements */
  if ( SDL_SetVideoMode(640, 480, 8, 0) == NULL ) {
	fprintf(stderr, "Ne peut changer le mode video 640x480x8: %s\n",
			SDL_GetError());
	exit(1);
  }

  /* Boucler jusqu'à l'appui simultané de Esc et de l'un des boutons de la souris
*/
  while ( SDL_WaitEvent(&event) >= 0 ) {
	switch (event.type) {
	case SDL_ACTIVEEVENT: {
	  if ( event.active.state & SDL_APPACTIVE ) {
		if ( event.active.gain ) {
		  printf("Application activée\n");
		} else {
		  printf("Application iconifiée\n");
		}
	  }
	}
	break;

	case SDL_MOUSEBUTTONDOWN: {
	  Uint8 *keys;

	  keys = SDL_GetKeyState(NULL);
	  if ( keys[SDLK_ESCAPE] == SDL_PRESSED ) {
		printf("Bye bye...\n");
		exit(0);
	  }
	  printf("Bouton de la souris pressé: %d\n", event.button.button);
	}
	break;

	case SDL_QUIT: {
	  printf("Evénement SDL_QUIT reçu, fin du programme\n");
	  exit(0);
	}
	break;
	}
  }
  return 1;
}
{% endhighlight %}

redpajama_set_name: RedPajamaGithub


text:
namespace com { namespace microsoft { namespace maker { namespace SecuritySystem {

// Signals

} } } }


text:
// ------------------------------------------------------------------------------
//  <auto-generated>
//      This code was generated by SpecFlow (http://www.specflow.org/).
//      SpecFlow Version:1.9.0.77
//      SpecFlow Generator Version:1.9.0.0
//      Runtime Version:4.0.30319.18003
//
//      Changes to this file may cause incorrect behavior and will be lost if
//      the code is regenerated.
//  </auto-generated>
// ------------------------------------------------------------------------------
#region Designer generated code
#pragma warning disable
namespace Orchard.Specs
{
    using TechTalk.SpecFlow;

    [System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "1.9.0.77")]
    [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [NUnit.Framework.TestFixtureAttribute()]
    [NUnit.Framework.DescriptionAttribute("Addition")]
    public partial class AdditionFeature
    {

        private static TechTalk.SpecFlow.ITestRunner testRunner;

#line 1 "PermissionModel.feature"
#line hidden

        [NUnit.Framework.TestFixtureSetUpAttribute()]
        public virtual void FeatureSetup()
        {
            testRunner = TechTalk.SpecFlow.TestRunnerManager.GetTestRunner();
            TechTalk.SpecFlow.FeatureInfo featureInfo = new TechTalk.SpecFlow.FeatureInfo(new System.Globalization.CultureInfo("en-US"), "Addition", "  In order to prevent security model regressions\r\n  As a user with specific permi" +
                    "ssions\r\n  I should to be granted or denied access to various actions", ProgrammingLanguage.CSharp, ((string[])(null)));
            testRunner.OnFeatureStart(featureInfo);
        }

        [NUnit.Framework.TestFixtureTearDownAttribute()]
        public virtual void FeatureTearDown()
        {
            testRunner.OnFeatureEnd();
            testRunner = null;
        }

        [NUnit.Framework.SetUpAttribute()]
        public virtual void TestInitialize()
        {
        }

        [NUnit.Framework.TearDownAttribute()]
        public virtual void ScenarioTearDown()
        {
            testRunner.OnScenarioEnd();
        }

        public virtual void ScenarioSetup(TechTalk.SpecFlow.ScenarioInfo scenarioInfo)
        {
            testRunner.OnScenarioStart(scenarioInfo);
        }

        public virtual void ScenarioCleanup()
        {
            testRunner.CollectScenarioErrors();
        }

        [NUnit.Framework.TestAttribute()]
        [NUnit.Framework.DescriptionAttribute("Login can be automated")]
        [NUnit.Framework.CategoryAttribute("security")]
        public virtual void LoginCanBeAutomated()
        {
            TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Login can be automated", new string[] {
                        "security"});
#line 7
this.ScenarioSetup(scenarioInfo);
#line 8
    testRunner.Given("I have installed Orchard", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given ");
#line 9
        testRunner.And("I have a user \"bob\" with permissions \"AccessFrontEnd\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 10
    testRunner.When("I go to \"users/account/logoff\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line 11
        testRunner.And("I go to \"users/account/logon\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
            TechTalk.SpecFlow.Table table1 = new TechTalk.SpecFlow.Table(new string[] {
                        "name",
                        "value"});
            table1.AddRow(new string[] {
                        "userNameOrEmail",
                        "bob"});
            table1.AddRow(new string[] {
                        "password",
                        "qwerty123!"});
#line 12
        testRunner.And("I fill in", ((string)(null)), table1, "And ");
#line 16
        testRunner.And("I hit \"Sign In\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 17
        testRunner.And("I am redirected", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 18
    testRunner.Then("I should see \"Welcome\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 19
        testRunner.And("I should see \"bob\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
            this.ScenarioCleanup();
        }

        [NUnit.Framework.TestAttribute()]
        [NUnit.Framework.DescriptionAttribute("Anonymous user can see the home page but not the dashboard")]
        [NUnit.Framework.CategoryAttribute("security")]
        public virtual void AnonymousUserCanSeeTheHomePageButNotTheDashboard()
        {
            TechTalk.SpecFlow.ScenarioInfo scenarioInfo = new TechTalk.SpecFlow.ScenarioInfo("Anonymous user can see the home page but not the dashboard", new string[] {
                        "security"});
#line 22
this.ScenarioSetup(scenarioInfo);
#line 23
    testRunner.Given("I have installed Orchard", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Given ");
#line 24
    testRunner.And("I have a user \"bob\" with permissions \"AccessFrontEnd\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 25
    testRunner.When("I sign in as \"bob\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "When ");
#line 26
     testRunner.And("I go to \"/\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line 27
    testRunner.Then("I should see \"this is the homepage of your new site\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "Then ");
#line 28
     testRunner.And("I should be denied access when I go to \"admin\"", ((string)(null)), ((TechTalk.SpecFlow.Table)(null)), "And ");
#line hidden
            this.ScenarioCleanup();
        }
    }
}
#pragma warning restore
#endregion


text:
/*jshint node:true*/
/* global require, module */
var EmberAddon = require('ember-cli/lib/broccoli/ember-addon');

module.exports = function(defaults) {
  var app = new EmberAddon(defaults, {
    // Add options here
  });

  /*
    This build file specifies the options for the dummy test app of this
    addon, located in `/tests/dummy`
    This build file does *not* influence how the addon or the app using it
    behave. You most likely want to be modifying `./index.js` or app's build file
  */
  app.import({ test: 'bower_components/bind-polyfill/index.js' });
  return app.toTree();
};


text:
module Neo4j

  # Represents a node in the Neo4j space.
  #
  # Is a wrapper around a Java Neo4j::Node (org.neo4j.graphdb.Node)
  # The following methods are delegated to the Java Neo4j::Node
  #   []=, [], property?, props, update, neo_id, rels, rel?, to_param
  #   rel, del, list?, list, lists, print, add_rel, outgoing, incoming,
  #   next, prev, next=, prev=, head
  #
  # Those methods are defined in included mixins
  # This mixin also include the class method in the
  #
  # === Included Mixins
  # * Neo4j::JavaPropertyMixin - instance methods for properties
  # * Neo4j::JavaNodeMixin - instance methods
  # * Neo4j::JavaListMixin - instance methods for list methods
  # * Neo4j::RelClassMethods - class methods for generating relationship accessors
  # * Neo4j::PropertyClassMethods - class methods for generating property accessors
  #
  module NodeMixin
    extend Forwardable

    def_delegators :@_java_node, :[]=, :[], :property?, :props, :update, :neo_id, :rels, :rel?, :to_param,
                   :rel, :del, :list?, :list, :lists, :print, :print_sub, :add_rel, :outgoing, :incoming,
                   :add_list_item_methods, :next, :prev, :next=, :prev=, :head # used for has_list, defined in Neo4j::JavaListMixin

    # --------------------------------------------------------------------------
    # Initialization methods
    #

    # Initialize the the neo node for this instance.
    # Will create a new transaction if one is not already running.
    #
    # Does
    # * sets the neo4j property '_classname' to self.class.to_s
    # * creates a neo4j node java object (in @_java_node)
    # * calls init_node if that is defined in the current class.
    #
    # If you want to provide your own initialize method you should instead implement the
    # method init_node method.
    #
    # === Example
    #
    #   class MyNode
    #     include Neo4j::NodeMixin
    #
    #     def init_node(name, age)
    #        self[:name] = name
    #        self[:age] = age
    #     end
    #   end
    #
    #   node = MyNode('jimmy', 23)
    #   # or also possible
    #   node = MyNode :name => 'jimmy', :age => 12
    #
    # The init_node is only called when the node is created in the database.
    # The initialize method is used both for to purposes:
    # loading an already existing node from the Neo4j database and creating a new node in the database.
    #
    def initialize(*args)
      # was a neo java node provided ?
      if args.length == 1 && args[0].kind_of?(org.neo4j.graphdb.Node)
        # yes, it was loaded from the database
        init_with_node(args[0])
      elsif self.respond_to?(:init_node)
        # does the class provide an initialization method ?
        init_without_node({})
        init_node(*args)
      else
        # no, but maybe it had a hash of properties to initialize it with, create node
        init_without_node(args[0] || {})
      end
      # was a block given in order to initialize the neo4j node ?
      yield self if block_given?
      # must call super with no arguments so that chaining of the initialize method works
      super()
    end

    # Inits this node with the specified java neo node
    #
    def init_with_node(java_node) # :nodoc:
      @_java_node = java_node
      java_node._wrapper=self
    end

    # Returns the org.neo4j.graphdb.Node wrapped object
    def _java_node
      @_java_node
    end

    # Creates a new node and initialize with given properties.
    #
    def init_without_node(props) # :nodoc:
      props[:_classname] = self.class.to_s
      @_java_node = Neo4j.create_node props
      update_index if props && !props.empty?
      @_java_node._wrapper = self
      Neo4j.event_handler.node_created(self)
    end

    # Since we sometimes don't know if we have a java node or a wrapped Ruby node we need this so that we
    # always can call this method
    def wrapper # :nodoc:
      self
    end

    # --------------------------------------------------------------------------
    # Property methods
    #

    # Creates a struct class containing all properties of this class.
    # This value object can be used from Ruby on Rails RESTful routing.
    #
    # ==== Example
    #
    # h = Person.value_object.new
    # h.name    # => nil
    # h.name='kalle'
    # h[:name]   # => 'kalle'
    #
    # ==== Returns
    # a value object struct
    #
    def value_object
      vo = self.class.value_object.new
      vo._update(props)
      vo
    end

    # --------------------------------------------------------------------------
    # Equal and hash methods
    #

    def equal?(o)
      eql?(o)
    end

    def eql?(o)
      o.kind_of?(NodeMixin) && o._java_node == @_java_node
    end

    def ==(o)
      eql?(o)
    end

    def hash
      @_java_node.hashCode
    end

    # --------------------------------------------------------------------------
    # Update and Delete methods
    #

    # Specifies which relationships should be ignored when trying to cascade delete a node.
    # If a node does not have any relationships (except those specified here to ignore) it will be cascade deleted
    #
    def ignore_incoming_cascade_delete?(relationship) # :nodoc:
      # ignore relationship with property _cascade_delete_incoming
      relationship.property?(:_cascade_delete_incoming)
    end

    # Updates the index for this node.
    # This method will be automatically called when needed
    # (a property changed or a relationship was created/deleted)
    #
    def update_index # :nodoc:
      self.class.indexer.index(self)
    end

    # --------------------------------------------------------------------------
    # Relationship methods
    #

    # Returns a Neo4j::Relationships::NodeTraverser object for traversing nodes from and to this node.
    # The Neo4j::Relationships::NodeTraverser is an Enumerable that returns Neo4j::NodeMixin objects.
    #
    # ==== Example
    #
    #   person_node.traverse.outgoing(:friends).each { ... }
    #   person_node.traverse.outgoing(:friends).raw.each { }
    #
    # The raw false parameter means that the ruby wrapper object will not be loaded, instead the raw Java Neo4j object will be used,
    # it might improve the performance.
    #
    def traverse(*args)
      if args.empty?
        Neo4j::Relationships::NodeTraverser.new(self)
      else
        @_java_node.traverse(*args)
      end

    end

    # --------------------------------------------------------------------------
    # Private methods
    #

    def _to_java_direction(dir) # :nodoc:
      case dir
        when :outgoing
          org.neo4j.graphdb.Direction::OUTGOING
        when :incoming
          org.neo4j.graphdb.Direction::INCOMING
        when :both
          org.neo4j.graphdb.Direction::BOTH
        else
          raise "Unknown parameter: '#{dir}', only accept :outgoing, :incoming or :both"
      end
    end

    # --------------------------------------------------------------------------
    # Hooks
    #

    # Adds class methods from
    #
    # * Neo4j::RelClassMethods
    # * Neo4j::PropertyClassMethods
    #
    def self.included(c) # :nodoc:
      c.instance_eval do
        # these constants are used in the Neo4j::RelClassMethods and Neo4j::PropertyClassMethods
        # they are defined here since they should only be defined once -
        # all subclasses share the same index, declared properties and index_updaters
        const_set(:ROOT_CLASS, self)
        const_set(:DECL_RELATIONSHIPS, {})
        const_set(:PROPERTIES_INFO, {})
      end unless c.const_defined?(:DECL_RELATIONSHIPS)

      c.extend Neo4j::RelClassMethods
      c.extend Neo4j::PropertyClassMethods
    end
  end
end


text:
The 1.0 release of the google-cloud-monitoring client is a significant upgrade
based on a [next-gen code generator](https://github.com/googleapis/gapic-generator-ruby),
and includes substantial interface changes. Existing code written for earlier
versions of this library will likely require updates to use this version.
This document describes the changes that have been made, and what you need to
do to update your usage.

To summarize:

 *  The library has been broken out into multiple libraries. The new gems
    `google-cloud-monitoring-v3` and `google-cloud-monitoring-dashboard-v1`
    contain the actual client classes for version V3 of the monitoring service
    and version V1 of the monitoring-dashboard service, respectively, and the
    gem `google-cloud-monitoring` now simply provides a convenience wrapper.
    See [Library Structure](#library-structure) for more info.
 *  The library uses a new configuration mechanism giving you closer control
    over endpoint address, network timeouts, and retry. See
    [Client Configuration](#client-configuration) for more info. Furthermore,
    when creating a client object, you can customize its configuration in a
    block rather than passing arguments to the constructor. See
    [Creating Clients](#creating-clients) for more info.
 *  Previously, positional arguments were used to indicate required arguments.
    Now, all method arguments are keyword arguments, with documentation that
    specifies whether they are required or optional. Additionally, you can pass
    a proto request object instead of separate arguments. See
    [Passing Arguments](#passing-arguments) for more info.
 *  Previously, some client classes included class methods for constructing
    resource paths. These paths are now instance methods on the client objects,
    and are also available in a separate paths module. See
    [Resource Path Helpers](#resource-path-helpers) for more info.
 *  Previously, clients reported RPC errors by raising instances of
    `Google::Gax::GaxError` and its subclasses. Now, RPC exceptions are of type
    `Google::Cloud::Error` and its subclasses. See
    [Handling Errors](#handling-errors) for more info.
 *  Some classes have moved into different namespaces. See
    [Class Namespaces](#class-namespaces) for more info.

### Library Structure

Older 0.x releases of the `google-cloud-monitoring` gem were all-in-one gems
that included multiple clients for potentially multiple versions of the various
monitoring-related services. Factory methods such as `Google::Cloud::Monitoring::Metric.new`
would return you instances of the actual client classes such as
`Google::Cloud::Monitoring::V3::MetricServiceClient`. These classes were all
defined in the same gem.

With the 1.0 release, the `google-cloud-monitoring` gem still provides factory
methods for obtaining clients. (The method signatures will have changed. See
[Creating Clients](#creating-clients) for details.) However, the actual client
classes have been moved into separate gems, one per service and version. The
`Google::Cloud::Monitoring::V3::MetricService::Client` class, along with its
helpers and data types, is now part of the `google-cloud-monitoring-v3` gem.
Similarly, the `Google::Cloud::Monitoring::Dashboard::V1::DashboardsService::Client`
class is part of the `google-cloud-monitoring-dashboard-v1` gem.

For normal usage, you can continue to install the `google-cloud-monitoring` gem
(which will bring in the various client gems as dependencies) and continue to
use factory methods to create clients. However, you may alternatively choose to
install only one of the versioned gems. For example, if you know you will only
use `V3` of the base monitoring service, you can install `google-cloud-monitoring-v3` by
itself, and construct instances of the `Google::Cloud::Monitoring::V3::*` client
classes directly.

### Client Configuration

In older releases, if you wanted to customize performance parameters or
low-level behavior of the client (such as credentials, timeouts, or
instrumentation), you would pass a variety of keyword arguments to the client
constructor. It was also extremely difficult to customize the default settings.

With the 1.0 release, a configuration interface provides control over these
parameters, including defaults for all instances of a client, and settings for
each specific client instance. For example, to set default credentials and
timeout for all Monitoring V3 MetricService clients:

```
Google::Cloud::Monitoring::V3::MetricService::Client.configure do |config|
  config.credentials = "/path/to/credentials.json"
  config.timeout = 10.0
end
```

Individual RPCs can also be configured independently. For example, to set the
timeout for the `create_metric_descriptor` call:

```
Google::Cloud::Monitoring::V3::MetricService::Client.configure do |config|
  config.rpcs.create_metric_descriptor.timeout = 20.0
end
```

Defaults for certain configurations can be set for all Monitoring versions and
services globally:

```
Google::Cloud::Monitoring.configure do |config|
  config.credentials = "/path/to/credentials.json"
  config.timeout = 10.0
end
```

Finally, you can override the configuration for each client instance. See the
next section on [Creating Clients](#creating-clients) for details.

### Creating Clients

In older releases, to create a client object, you would use the `new` method
of modules under `Google::Cloud::Monitoring`. For example, you might call
`Google::Cloud::Monitoring::Metric.new`. Keyword arguments were available to
select a service version and to configure parameters such as credentials and
timeouts.

With the 1.0 release, use named class methods of `Google::Cloud::Monitoring` to
create a client object. For example, `Google::Cloud::Monitoring.metric_service`.
You may select a service version using the `:version` keyword argument.
However, other configuration parameters should be set in a configuration block
when you create the client.

Old:
```
client = Google::Cloud::Monitoring::Metric.new credentials: "/path/to/credentials.json"
```

New:
```
client = Google::Cloud::Monitoring.metric_service do |config|
  config.credentials = "/path/to/credentials.json"
end
```

The configuration block is optional. If you do not provide it, or you do not
set some configuration parameters, then the default configuration is used. See
[Client Configuration](#client-configuration).

A similar change was made for the monitoring dashboards service:

Old:
```
client = Google::Cloud::Monitoring::Dashboard.new credentials: "/path/to/credentials.json"
```

New:
```
client = Google::Cloud::Monitoring::Dashboard.dashboards_service do |config|
  config.credentials = "/path/to/credentials.json"
end
```

### Passing Arguments

In older releases, required arguments would be passed as positional method
arguments, while most optional arguments would be passed as keyword arguments.

With the 1.0 release, all RPC arguments are passed as keyword arguments,
regardless of whether they are required or optional. For example:

Old:
```
client = Google::Cloud::Monitoring::Metric.new

name = "projects/my-project"

# The required name argument is positional, while the optional page_size
# argument is a keyword argument
response = client.list_metric_descriptors name, page_size: 10
```

New:
```
client = Google::Cloud::Monitoring.metric_service

name = "projects/my-project"

# All arguments are keyword arguments
response = client.list_metric_descriptors name: name, page_size: 10
```

In the 1.0 release, it is also possible to pass a request object, either
as a hash or as a protocol buffer.

New:
```
client = Google::Cloud::Monitoring.metric_service

request = Google::Cloud::Monitoring::V3::ListMetricDescriptorsRequest.new(
  name: "projects/my-project",
  page_size: 10
)

# Pass a request object as a positional argument:
response = client.list_metric_descriptors request
```

Finally, in older releases, to provide call options, you would pass a
`Google::Gax::CallOptions` object with the `:options` keyword argument. In the
1.0 release, pass call options using a _second set_ of keyword arguments.

Old:
```
client = Google::Cloud::Monitoring::Metric.new

name = "projects/my-project"

options = Google::Gax::CallOptions.new timeout: 10.0

response = client.list_metric_descriptors name, page_size: 10, options: options
```

New:
```
client = Google::Cloud::Monitoring.metric_service

name = "projects/my-project"

# Use a hash to wrap the normal call arguments (or pass a request object), and
# then add further keyword arguments for the call options.
response = client.list_metric_descriptors(
  { name: name, page_size: 10 },
  timeout: 10.0)
```

### Resource Path Helpers

The client library includes helper methods for generating the resource path
strings passed to many calls. These helpers have changed in two ways:

* In older releases, they are _class_ methods on the client class. In the 1.0
  release, they are _instance_ methods on the client. They are also available
  on a separate paths module that you can include elsewhere for convenience.
* In older releases, arguments to a resource path helper are passed as
  _positional_ arguments. In the 1.0 release, they are passed as named _keyword_
  arguments. Some helpers also support different sets of arguments, each set
  corresponding to a different type of path.

Following is an example involving using a resource path helper.

Old:
```
client = Google::Cloud::Monitoring::UptimeCheck.new

# Call the helper on the client class
name = Google::Cloud::Monitoring::V3::UptimeCheckServiceClient.
         uptime_check_config_path("my-project", "my-uptime-check")

response = client.get_uptime_check_config name
```

New:
```
client = Google::Cloud::Monitoring.uptime_check_service

# Call the helper on the client instance, and use keyword arguments
name = client.uptime_check_config_path project: "my-project",
                                       uptime_check_config: "my-uptime-check"

response = client.get_uptime_check_config name: name
```

Because helpers take keyword arguments, some can now generate several different
variations on the path that were not available under earlier versions of the
library. For example, `get_uptime_check_config` can generate paths with either
a project, an organization, or a folder as the parent resource.

New:
```
client = Google::Cloud::Monitoring.uptime_check_service

# Create paths with different parent resource types
name = client.uptime_check_config_path project: "my-project",
                                       uptime_check_config: "my-uptime-check"
# => "projects/my-project/uptimeCheckConfigs/my-uptime-check"
name = client.uptime_check_config_path folder: "my-folder",
                                       uptime_check_config: "my-uptime-check"
# => "folders/my-folder/uptimeCheckConfigs/my-uptime-check"
```

Finally, in the 1.0 client, you can also use the paths module as a convenience module.

New:
```
# Bring the path helper methods into the current class
include Google::Cloud::Monitoring::V3::UptimeCheckService::Paths

def foo
  client = Google::Cloud::Monitoring.uptime_check_service

  # Call the included helper method
  name = uptime_check_config_path project: "my-project",
                                  uptime_check_config: "my-uptime-check"

  response = client.get_uptime_check_config name: name

  # Do something with response...
end
```

### Handling Errors

The client reports standard
[gRPC error codes](https://github.com/grpc/grpc/blob/master/doc/statuscodes.md)
by raising exceptions. In older releases, these exceptions were located in the
`Google::Gax` namespace and were subclasses of the `Google::Gax::GaxError` base
exception class, defined in the `google-gax` gem. However, these classes were
different from the standard exceptions (subclasses of `Google::Cloud::Error`)
thrown by other client libraries such as `google-cloud-storage`.

The 1.0 client library now uses the `Google::Cloud::Error` exception hierarchy
for consistency across all the Google Cloud client libraries. In general, these
exceptions have the same name as their counterparts from older releases, but
are located in the `Google::Cloud` namespace rather than the `Google::Gax`
namespace.

Old:
```
client = Google::Cloud::Monitoring::Metric.new

name = "projects/my-project"

begin
  response = client.list_metric_descriptors name, page_size: 10
rescue Google::Gax::Error => e
  # Handle exceptions that subclass Google::Gax::Error
end
```

New:
```
client = Google::Cloud::Monitoring.metric_service

name = "projects/my-project"

begin
  response = client.list_metric_descriptors name: name, page_size: 10
rescue Google::Cloud::Error => e
  # Handle exceptions that subclass Google::Cloud::Error
end
```

### Class Namespaces

In older releases, some data type (protobuf) classes were located under the module
`Google::Monitoring`. In the 1.0 release, these classes have been moved into the
same `Google::Cloud::Monitoring` module by the client object, for consistency.

In older releases, the client object was of classes with names like:
`Google::Cloud::Monitoring::V3::MetricServiceClient`.
In the 1.0 release, the client object is of a different class:
`Google::Cloud::Monitoring::V3::MetricService::Client`.
Note that most users will use the factory methods such as
`Google::Cloud::Monitoring.metric_service` to create instances of the client object,
so you may not need to reference the actual class directly.
See [Creating Clients](#creating-clients).

In older releases, the credentials object was of class
`Google::Cloud::Monitoring::V3::Credentials`.
In the 1.0 release, each service has its own credentials class, e.g.
`Google::Cloud::Monitoring::V3::MetricService::Credentials`.
Again, most users will not need to reference this class directly.
See [Client Configuration](#client-configuration).


text:
'''
python-lambda-local: Test module.

Meant for use with py.test.
Write each test as a function named test_<something>.
Read more here: http://pytest.org/

Copyright 2015-2022 HENNGE K.K. (formerly known as HDE, Inc.)
Licensed under MIT
'''

def test_example():
    assert True


text:
package org.opensmartgridplatform.adapter.domain.smartmetering.infra.jms.core.messageprocessors;

import org.opensmartgridplatform.adapter.domain.smartmetering.application.services.ConfigurationService;
import org.opensmartgridplatform.adapter.domain.smartmetering.infra.jms.core.OsgpCoreResponseMessageProcessor;
import org.opensmartgridplatform.adapter.domain.smartmetering.infra.jms.ws.WebServiceResponseMessageSender;
import org.opensmartgridplatform.dto.valueobjects.smartmetering.GetMbusEncryptionKeyStatusResponseDto;
import org.opensmartgridplatform.shared.exceptionhandling.ComponentType;
import org.opensmartgridplatform.shared.exceptionhandling.OsgpException;
import org.opensmartgridplatform.shared.infra.jms.DeviceMessageMetadata;
import org.opensmartgridplatform.shared.infra.jms.MessageProcessorMap;
import org.opensmartgridplatform.shared.infra.jms.MessageType;
import org.opensmartgridplatform.shared.infra.jms.ResponseMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

@Component
public class GetMbusEncryptionKeyStatusResponseMessageProcessor extends OsgpCoreResponseMessageProcessor {

    @Autowired
    private ConfigurationService configurationService;

    @Autowired
    public GetMbusEncryptionKeyStatusResponseMessageProcessor(
            WebServiceResponseMessageSender responseMessageSender,
            @Qualifier("domainSmartMeteringOsgpCoreResponseMessageProcessorMap") MessageProcessorMap messageProcessorMap) {
        super(responseMessageSender, messageProcessorMap, MessageType.GET_MBUS_ENCRYPTION_KEY_STATUS,
                ComponentType.DOMAIN_SMART_METERING);
    }

    @Override
    protected boolean hasRegularResponseObject(final ResponseMessage responseMessage) {
        return responseMessage.getDataObject() instanceof GetMbusEncryptionKeyStatusResponseDto;
    }

    @Override
    protected void handleMessage(final DeviceMessageMetadata deviceMessageMetadata,
            final ResponseMessage responseMessage, final OsgpException osgpException) {

        final GetMbusEncryptionKeyStatusResponseDto getMbusEncryptionKeyStatusResponseDto = (GetMbusEncryptionKeyStatusResponseDto) responseMessage
                .getDataObject();
        this.configurationService.handleGetMbusEncryptionKeyStatusResponse(deviceMessageMetadata,
                responseMessage.getResult(), osgpException, getMbusEncryptionKeyStatusResponseDto);
    }
}


text:
namespace ants
{
extern int
TensorDerivedImage(std::vector<std::string>, // equivalent to argv of command line parameters to main()
                   std::ostream * out_stream // [optional] output stream to write
);
} // namespace ants

#endif // TENSORDERIVEDIMAGE_H


text:
/**
 *
ClassName: java edu.wustl.geneconnect.action.HomeAction

 */

package edu.wustl.geneconnect.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import edu.wustl.geneconnect.metadata.MetadataManager;
import edu.wustl.geneconnect.util.global.GCConstants;

/**
 * Action class for Home page. This class will prepare required data for Home page
 * @author krunal_thakkar
 * @version 1.0
 */
public class HomeAction extends Action
{

	/**
	 * Defalut Constructor
	 */
	public HomeAction()
	{
		super();
	}

	//TODO : Logging needs to be added.

	/**
	 * Execute method which will be invoked by struts framework.
	 * @param mapping -
	 *            This is the action mapping object
	 * @param form -
	 *            Contains the form data
	 * @param request -
	 *            Request Object
	 * @param response -
	 *            Response Object
	 * @return ActionForward - Returns the the next page to forward to
	 * @throws Exception -
	 *             Throws any action related exceptions
	 */
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) throws Exception
	{
		request.setAttribute(GCConstants.NO_OF_PARIWISE_LINKS, MetadataManager.getPairwiseLinks()
				.toString());

		request.setAttribute(GCConstants.NO_OF_GI_SETS, MetadataManager.getDistinctGISets()
				.toString());

		request.setAttribute(GCConstants.NO_OF_GRAPH_PATHS, MetadataManager.getPossibleGraphPaths()
				.toString());

		return mapping.findForward(GCConstants.FORWARD_TO_HOME_PAGE);
	}

}


text:
#pragma once

/// \file
/// Declaration of Diligent::RootSignatureD3D12 class

// Root signature object combines multiple pipeline resource signatures into a single
// d3d12 root signature. The signatures "stack" on top of each other. Their "local"
// root indices and register spaces are biased by the root indices and spaces of
// previous signatures.
//
//   __________________________________________________________
//  |                                                          |
//  |  Pipeline Resource Signature 2 (NRootIndices2, NSpaces2) |  BaseRootIndex2 = BaseRootIndex1 + NRootIndices1
//  |__________________________________________________________|  BaseSpace2     = BaseSpace1 + NSpaces1
//  |                                                          |
//  |  Pipeline Resource Signature 1 (NRootIndices1, NSpaces1) |  BaseRootIndex1 = BaseRootIndex0 + NRootIndices0
//  |__________________________________________________________|  BaseSpace1     = BaseSpace0 + NSpaces0
//  |                                                          |
//  |  Pipeline Resource Signature 0 (NRootIndices0, NSpaces0) |  BaseRootIndex0 = 0
//  |__________________________________________________________|  BaseSpace0     = 0
//

#include <mutex>
#include <unordered_map>
#include <memory>

#include "PrivateConstants.h"
#include "ShaderResources.hpp"
#include "ObjectBase.hpp"
#include "ResourceBindingMap.hpp"

namespace Diligent
{

class RenderDeviceD3D12Impl;
class RootSignatureCacheD3D12;
class PipelineResourceSignatureD3D12Impl;

/// Implementation of the Diligent::RootSignature class
class RootSignatureD3D12 final : public ObjectBase<IObject>
{
public:
    RootSignatureD3D12(IReferenceCounters*                                     pRefCounters,
                       RenderDeviceD3D12Impl*                                  pDeviceD3D12Impl,
                       const RefCntAutoPtr<PipelineResourceSignatureD3D12Impl> ppSignatures[],
                       Uint32                                                  SignatureCount,
                       size_t                                                  Hash);
    ~RootSignatureD3D12();

    size_t GetHash() const { return m_Hash; }

    Uint32 GetSignatureCount() const { return m_SignatureCount; }

    PipelineResourceSignatureD3D12Impl* GetResourceSignature(Uint32 index) const
    {
        VERIFY_EXPR(index < m_SignatureCount);
        return m_ResourceSignatures[index].pSignature;
    }

    ID3D12RootSignature* GetD3D12RootSignature() const
    {
        VERIFY_EXPR(m_pd3d12RootSignature);
        return m_pd3d12RootSignature;
    }

    Uint32 GetBaseRootIndex(Uint32 BindingIndex) const
    {
        VERIFY_EXPR(BindingIndex < m_SignatureCount);
        return m_ResourceSignatures[BindingIndex].BaseRootIndex;
    }

    Uint32 GetBaseRegisterSpace(Uint32 BindingIndex) const
    {
        VERIFY_EXPR(BindingIndex <= m_SignatureCount);
        return m_ResourceSignatures[BindingIndex].BaseRegisterSpace;
    }

    /// Returns the total number of register spaces used by all resource signatures
    Uint32 GetTotalSpaces() const
    {
        return m_TotalSpacesUsed;
    }

    bool IsCompatibleWith(const RefCntAutoPtr<PipelineResourceSignatureD3D12Impl> ppSignatures[], Uint32 SignatureCount) const noexcept;

private:
    // The number of pipeline resource signatures used to initialize this root signature.
    const Uint32 m_SignatureCount;

    // The total number of register spaces used by this root signature.
    Uint32 m_TotalSpacesUsed = 0;

    // Root signature hash.
    const size_t m_Hash;

    CComPtr<ID3D12RootSignature> m_pd3d12RootSignature;

    struct ResourceSignatureInfo
    {
        RefCntAutoPtr<PipelineResourceSignatureD3D12Impl> pSignature;

        Uint32 BaseRootIndex     = 0;
        Uint32 BaseRegisterSpace = 0;
    };
    std::unique_ptr<ResourceSignatureInfo[]> m_ResourceSignatures;

    RootSignatureCacheD3D12* m_pCache = nullptr;
};

class LocalRootSignatureD3D12
{
public:
    LocalRootSignatureD3D12(const char* pCBName, Uint32 ShaderRecordSize);

    bool IsShaderRecord(const D3DShaderResourceAttribs& CB) const;

    bool Create(ID3D12Device* pDevice, Uint32 RegisterSpace);

    ID3D12RootSignature* GetD3D12RootSignature() const { return m_pd3d12RootSignature; }
    bool                 IsDefined() const { return m_ShaderRecordSize > 0 && !m_Name.empty(); }
    const char*          GetName() const { return m_Name.c_str(); }
    Uint32               GetShaderRegister() const { return 0; }

    Uint32 GetRegisterSpace() const
    {
        VERIFY_EXPR(m_RegisterSpace != ~0U);
        return m_RegisterSpace;
    }

private:
    const std::string            m_Name;
    const Uint32                 m_ShaderRecordSize = 0;
    Uint32                       m_RegisterSpace    = ~0u;
    CComPtr<ID3D12RootSignature> m_pd3d12RootSignature;
};

/// Root signature cache that deduplicates RootSignatureD3D12 objects.
class RootSignatureCacheD3D12
{
public:
    RootSignatureCacheD3D12(RenderDeviceD3D12Impl& DeviceD3D12Impl);

    // clang-format off
    RootSignatureCacheD3D12             (const RootSignatureCacheD3D12&) = delete;
    RootSignatureCacheD3D12             (RootSignatureCacheD3D12&&)      = delete;
    RootSignatureCacheD3D12& operator = (const RootSignatureCacheD3D12&) = delete;
    RootSignatureCacheD3D12& operator = (RootSignatureCacheD3D12&&)      = delete;
    // clang-format on

    ~RootSignatureCacheD3D12();

    RefCntAutoPtr<RootSignatureD3D12> GetRootSig(const RefCntAutoPtr<PipelineResourceSignatureD3D12Impl>* ppSignatures, Uint32 SignatureCount);

    void OnDestroyRootSig(RootSignatureD3D12* pRootSig);

private:
    RenderDeviceD3D12Impl& m_DeviceD3D12Impl;

    std::mutex                                                         m_RootSigCacheMtx;
    std::unordered_multimap<size_t, RefCntWeakPtr<RootSignatureD3D12>> m_RootSigCache;
};

} // namespace Diligent


text:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>net.aslettemark</groupId>
	<artifactId>ESABot</artifactId>
    <packaging>jar</packaging>
	<version>0.1.4</version>
	<name>ESABot</name>
	<description>Java IRC bot</description>
    <url>https://github.com/aslettemark/ESABot</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	</properties>

	<repositories>

	</repositories>

	<dependencies>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpcore</artifactId>
            <version>4.2</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.3</version>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>pircbot</groupId>
            <artifactId>pircbot</artifactId>
            <version>1.5.0</version>
        </dependency>
	</dependencies>

	<build>
		<defaultGoal>clean package</defaultGoal>
		<finalName>${project.artifactId}</finalName>
        <sourceDirectory>src</sourceDirectory>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>2.5</version>
                <configuration>
                    <archive>
                        <manifest>
                            <mainClass>net.aslettemark.esabot.MainClass</mainClass>
                            <addClasspath>true</addClasspath>
                        </manifest>
                    </archive>
                </configuration>
            </plugin>
		</plugins>
		<resources>

		</resources>
	</build>
</project>


text:
package fr.arnaudguyon.smartgl.opengl;

import java.util.Vector;

import android.opengl.Matrix;

public abstract class RenderObject implements IShaderTextureFade {

	private boolean mIs3D;
	private boolean mVisible;
	private Vector<Face3D> mFaces;
	private float[] mMatrix;
    private float mAlpha = 1;
    private boolean mInvalidMatrix = true;

	public RenderObject(boolean is3D) {
		mIs3D = is3D;
		mFaces = new Vector<Face3D>();
		mMatrix = new float[16];
		mVisible = true;
		Matrix.setIdentityM(mMatrix, 0);
	}

	public final boolean is3D() {
		return mIs3D;
	}

	public final void setVisible(boolean visible) {
		mVisible = visible;
	}

	public final boolean isVisible() {
		return mVisible;
	}

	public final boolean isHidden() {
		return !mVisible;
	}

	public final Vector<Face3D> getFaces() {
		return mFaces;
	}

	public final void setFaces(Vector<Face3D> faces) {
		mFaces = faces;
	}
	public final void addFace(Face3D face) {
		mFaces.add(face);
	}

//	protected final float[] getMatrixArray() {
//		return mMatrix;
//	}

	protected boolean isContainer() {
		return false;
	}

	abstract protected void computeMatrix(float[] matrix);

    public float[] getMatrix() {
        if (mInvalidMatrix) {
            computeMatrix(mMatrix);
            mInvalidMatrix = false;
        }
        return mMatrix;
    }

    protected void invalidMatrix() {
        mInvalidMatrix = true;
    }

	public void forceReleaseAll() {

		// force deleteOpenGLResource
		final int faceSize = mFaces.size();
		for (int faceIt = 0; faceIt < faceSize; ++faceIt) {
			Face3D face = mFaces.get(faceIt);
			Texture texture = face.getTexture();
			if (texture != null) {
				texture.unbindTexture();
			}
		}
		// then normal release resources
		releaseResources();
	}

	protected void releaseResources() {
		final int faceSize = mFaces.size();
		for (int faceIt = 0; faceIt < faceSize; ++faceIt) {
			Face3D face = mFaces.get(faceIt);
			face.releaseResources();
		}
		mFaces.clear();
	}

	public void releaseTextures() {
		Vector<Face3D> faces = getFaces();
		final int faceSize = faces.size();
		for (int faceIt = 0; faceIt < faceSize; ++faceIt) {
			Face3D face = faces.get(faceIt);
			Texture texture = face.getTexture();
			if (texture != null) {
				texture.unbindTexture();
			}
		}
	}

	// always called, even if object is hidden
	public void tick(OpenGLRenderer renderer) {}

	public boolean shouldDisplay(OpenGLRenderer renderer) {
		return mVisible;
	}
	// called only if shouldDisplay return true
	public void onPreRenderObject(OpenGLRenderer renderer) {}
	// called for each face, typically used to add specific shader links
	public void onPreRenderFace(OpenGLRenderer renderer, Shader shader, Face3D face) {}

    @Override
    public float getAlpha() {
        return mAlpha;
    }

    @Override
    public void setAlpha(float alpha) {
        mAlpha = alpha;
    }

    public void localToGlobalPosition(float localX, float localY, float localZ, float[] result4f) {
        float[] rectMatrix = getMatrix();
        result4f[0] = localX;
        result4f[1] = localY;
        result4f[2] = localZ;
        result4f[3] = 1;
        Matrix.multiplyMV(result4f, 0, rectMatrix, 0, result4f, 0);
    }
}


text:
CREATE DATABASE IF NOT EXISTS memex_sotera;
USE memex_sotera;

DROP TABLE IF EXISTS datawake_org;
CREATE TABLE datawake_org (
  email VARCHAR(300),
  org VARCHAR(300)
);

DROP TABLE IF EXISTS datawake_domains;
CREATE TABLE datawake_domains (
  name VARCHAR(300),
  description TEXT,
  PRIMARY KEY(name)
);

DROP TABLE IF EXISTS datawake_selections;
CREATE TABLE datawake_selections (
  id INT NOT NULL AUTO_INCREMENT,
  postId INT NOT NULL,
  selection TEXT,
  PRIMARY KEY(id),
  INDEX(postId)
);

DROP TABLE IF EXISTS datawake_data;
CREATE TABLE datawake_data (
  id INT NOT NULL AUTO_INCREMENT,
  ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  url TEXT,
  userId TEXT,
  userName TEXT,
  trail VARCHAR(100),
  org VARCHAR(300),
  domain VARCHAR(300),
  PRIMARY KEY(id),
  INDEX(url(30))
);

DROP TABLE IF EXISTS datawake_trails;
CREATE TABLE datawake_trails (
  name VARCHAR(100) NOT NULL,
  created TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  created_by TEXT,
  description TEXT,
  org VARCHAR(300),
  domain VARCHAR(300),
  PRIMARY KEY(name,org,domain)
);

DROP TABLE IF EXISTS starred_features;
CREATE TABLE starred_features (
  org VARCHAR(300),
  trail VARCHAR(100) NOT NULL,
  type VARCHAR(100),
  value VARCHAR(1024),
  INDEX(org,trail)
);

DROP TABLE IF EXISTS datawake_url_rank;
CREATE TABLE datawake_url_rank (
  id INT NOT NULL AUTO_INCREMENT,
  url TEXT,
  userId TEXT,
  trailname VARCHAR(100),
  rank INT,
  org VARCHAR(300),
  domain VARCHAR(300),
  PRIMARY KEY(id),
  INDEX(url(30),userId(20),trailname)
);

DROP TABLE IF EXISTS datawake_domain_entities;
CREATE TABLE datawake_domain_entities (
  rowkey varchar(1024),
  INDEX(rowkey(300))
);

DROP TABLE IF EXISTS general_extractor_web_index;
CREATE TABLE general_extractor_web_index (
  url varchar(1024),
  entity_type varchar(100),
  entity_value varchar(1024),
  ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  index(url(300))
);

DROP TABLE IF EXISTS domain_extractor_web_index;
CREATE TABLE domain_extractor_web_index (
  domain VARCHAR(300),
  url varchar(1024),
  entity_type varchar(100),
  entity_value varchar(1024),
  ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  index(domain(300),url(300))
);

DROP TABLE IF EXISTS domain_extractor_runtimes;
CREATE TABLE domain_extractor_runtimes (
  domain VARCHAR(300),
  url varchar(1024),
  entity_type varchar(100),
  ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  index(domain(300),url(300))
);

DROP TABLE IF EXISTS scraping_feedback;
CREATE TABLE scraping_feedback (
  entity_type varchar(100),
  entity_value varchar(1024),
  raw_text varchar (100),
  url TEXT,
  domain varchar (300),
  org VARCHAR(300),
  index(org(300),domain(300))
);

DROP TABLE IF EXISTS invalid_extracted_entity;
CREATE TABLE invalid_extracted_entity (
  entity_value varchar (1024),
  entity_type varchar (100),
  domain varchar (300),
  org VARCHAR(300),
  userName TEXT,
  ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  index(org(300),domain(300), entity_type(100), entity_value(100))
);

\q


text:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context="com.xunjie.skuaike.ui.activity.bill.NewBillActivity">

    <data class="ActivityZbarCaptureBinding">

    </data>

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="@mipmap/shadow"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
            app:theme="@style/ThemeOverlay.AppCompat.ActionBar"
            app:title=" ">

            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerInParent="true"
                android:layout_gravity="center"
                android:text="二维码扫描"
                android:textColor="@color/white"
                android:textSize="@dimen/page_18" />
        </android.support.v7.widget.Toolbar>

        <RelativeLayout
            android:id="@+id/capture_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_below="@id/toolbar">

            <FrameLayout
                android:id="@+id/capture_preview"
                android:layout_width="match_parent"
                android:layout_height="match_parent" />

            <ImageView
                android:id="@+id/capture_mask_top"
                android:layout_width="match_parent"
                android:layout_height="80dp"
                android:layout_alignParentTop="true"
                android:background="@drawable/shadow" />

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginLeft="15dp"
                android:layout_marginTop="70dp"
                android:src="@mipmap/scan_up" />

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_marginRight="15dp"
                android:layout_marginTop="340dp"
                android:src="@mipmap/scan_down" />

            <RelativeLayout
                android:id="@+id/capture_crop_view"
                android:layout_width="match_parent"
                android:layout_height="300dp"
                android:layout_alignParentLeft="true"
                android:layout_alignParentStart="true"
                android:layout_below="@+id/capture_mask_top"
                android:background="@color/transparent">

                <ImageView
                    android:layout_width="30dp"
                    android:layout_height="300dp"
                    android:background="@drawable/shadow" />

                <ImageView
                    android:id="@+id/capture_scan_line"
                    android:layout_width="match_parent"
                    android:layout_height="2dp"
                    android:layout_marginTop="5dp"
                    android:background="@drawable/red_line" />

                <ImageView
                    android:layout_width="30dp"
                    android:layout_height="300dp"
                    android:layout_alignRight="@id/capture_scan_line"
                    android:background="@drawable/shadow" />

            </RelativeLayout>
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/capture_crop_view"
                android:layout_centerHorizontal="true"
                android:layout_marginTop="30dp"
                android:textColor="@color/white"
                android:text="将条形码放入框内,即可自动扫描"/>
            <ImageView
                android:id="@+id/capture_mask_bottom"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_below="@id/capture_crop_view"
                android:background="@drawable/shadow" />

            <ImageView
                android:id="@+id/capture_mask_left"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_above="@id/capture_mask_bottom"
                android:layout_alignParentLeft="true"
                android:layout_below="@id/capture_mask_top"
                android:layout_toLeftOf="@id/capture_crop_view"
                android:background="@drawable/shadow" />

            <ImageView
                android:id="@+id/capture_mask_right"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
                android:layout_above="@id/capture_mask_bottom"
                android:layout_alignParentRight="true"
                android:layout_below="@id/capture_mask_top"
                android:layout_toRightOf="@id/capture_crop_view"
                android:background="@drawable/shadow" />
        </RelativeLayout>

    </RelativeLayout>
</layout>


text:
module ControlledQuit
  VERSION = '0.1.0'
end