text:
package org.gearvrf.scene_objects;

import java.util.ArrayList;
import java.util.concurrent.Future;

import org.gearvrf.FutureWrapper;
import org.gearvrf.GVRMaterial;
import org.gearvrf.GVRSceneObject;
import org.gearvrf.GVRRenderData;
import org.gearvrf.GVRContext;
import org.gearvrf.GVRMesh;
import org.gearvrf.GVRTexture;
import org.gearvrf.utility.Log;

public class GVRCylinderSceneObject extends GVRSceneObject {
    public static class CylinderParams {
        public float       Height = 1.0f;
        public float       TopRadius = 0.5f;
        public float       BottomRadius = 0.5f;
        public int         StackNumber = 10;
        public int         SliceNumber = 36;
        public boolean     FacingOut = true;
        public boolean     HasTopCap = true;
        public boolean     HasBottomCap = true;
        public GVRMaterial Material = null;
    };

    @SuppressWarnings("unused")
    private static final String TAG = Log.tag(GVRCylinderSceneObject.class);

    private static final int STACK_NUMBER = 10;
    private static final int SLICE_NUMBER = 36;
    private static final float BASE_RADIUS = 0.5f;
    private static final float TOP_RADIUS = 0.5f;
    private static final float HEIGHT = 1.0f;

    private float[] vertices;
    private float[] normals;
    private float[] texCoords;
    private char[] indices;
    private int vertexCount = 0;
    private int texCoordCount = 0;
    private char indexCount = 0;
    private int triangleCount = 0;

    /**
     * Constructs a cylinder scene object based on a set of parameters.
     *  Height          height of cylinder (default 1).
     *  TopRadius       radius of cylinder top (default 0.5).
     *  BottomRadius    radius of cylinder bottom (default 0.5).
     *  StackNumber     number of stacks in cylinder body (default 10).
     *  SliceNumber     number of slices in cylinder caps (default 36).
     *  FacingOut       true for normals facing out, false for normals facing in (default true).
     *  HasTopCap       true to include top cap, false to omit it (default true).
     *  HasBottomCap    true to include bottom cap, false to omit it (default true).
     *  Material        GVRMaterial to apply to cylinder (default null).
     *
     * @param gvrContext
     *            current {@link GVRContext}
     * @param params    CylinderParams object with cylinder construction parameters.
     */
    public GVRCylinderSceneObject(GVRContext gvrContext, CylinderParams params) {
        super(gvrContext);
        generateCylinderObject(gvrContext, params);
    }

    /**
     * Constructs a cylinder scene object with a height of 1, radius of 0.5, 10
     * stacks, and 36 slices.
     *
     * The cylinder's triangles and normals are facing out and the same texture
     * will be applied to top, bottom, and side of the cylinder.
     *
     * @param gvrContext
     *            current {@link GVRContext}
     */
    public GVRCylinderSceneObject(GVRContext gvrContext) {
        super(gvrContext);
        CylinderParams params = new CylinderParams();
        params.Material = new GVRMaterial(gvrContext);
        generateCylinderObject(gvrContext, params);
    }

    /**
     * Constructs a cylinder scene object with a height of 1, radius of 0.5, 10
     * stacks, and 36 slices.
     *
     * The cylinder's triangles and normals are facing either in or out and the
     * same texture will be applied to top, bottom, and side of the cylinder.
     *
     * @param gvrContext
     *            current {@link GVRContext}
     *
     * @param facingOut
     *            whether the triangles and normals should be facing in or
     *            facing out.
     */
    public GVRCylinderSceneObject(GVRContext gvrContext, boolean facingOut) {
        super(gvrContext);
        CylinderParams params = new CylinderParams();
        params.Material = new GVRMaterial(gvrContext);
        params.FacingOut = facingOut;
        generateCylinderObject(gvrContext, params);
    }

    /**
     * Constructs a cylinder scene object with a height of 1, radius of 0.5, 10
     * stacks, and 36 slices.
     *
     * The cylinder's triangles and normals are facing either in or out and the
     * same texture will be applied to top, bottom, and side of the cylinder.
     *
     * @param gvrContext
     *            current {@link GVRContext}
     *
     * @param facingOut
     *            whether the triangles and normals should be facing in or
     *            facing out.
     *
     * @param futureTexture
     *            the texture for the cylinder. {@code Future<GVRTexture>} is
     *            used here for asynchronously loading the texture.
     */
    public GVRCylinderSceneObject(GVRContext gvrContext, boolean facingOut,
            Future<GVRTexture> futureTexture) {
        super(gvrContext);
        CylinderParams params = new CylinderParams();
        GVRMaterial material = new GVRMaterial(gvrContext);
        material.setMainTexture(futureTexture);
        params.Material = material;
        params.FacingOut = facingOut;
        generateCylinderObject(gvrContext, params);
    }

    /**
     * Constructs a cylinder scene object with a height of 1, radius of 0.5, 10
     * stacks, and 36 slices.
     *
     * The cylinder's triangles and normals are facing either in or out and the
     * same material will be applied to top, bottom, and side of the cylinder.
     *
     * @param gvrContext
     *            current {@link GVRContext}
     *
     * @param facingOut
     *            whether the triangles and normals should be facing in or
     *            facing out.
     *
     * @param material
     *            the material for the cylinder.
     */
    public GVRCylinderSceneObject(GVRContext gvrContext, boolean facingOut,
            GVRMaterial material) {
        super(gvrContext);
        CylinderParams params = new CylinderParams();
        params.Material = material;
        params.FacingOut = facingOut;
        generateCylinderObject(gvrContext, params);
    }

    /**
     * Constructs a cylinder scene object with a height of 1, radius of 0.5, 10
     * stacks, and 36 slices.
     *
     * The cylinder's triangles and normals are facing either in or out. The top, bottom, and side of the cylinder each has its own texture.
     *
     * @param gvrContext
     *            current {@link GVRContext}
     *
     * @param facingOut
     *            whether the triangles and normals should be facing in or
     *            facing out.
     *
     * @param futureTextureList
     *            the list of three textures for the cylinder. {@code Future<GVRTexture>} is used here for asynchronously loading
     *            the texture. The six textures are for top, side, and bottom faces respectively.
     */
    public GVRCylinderSceneObject(GVRContext gvrContext, boolean facingOut,
            ArrayList<Future<GVRTexture>> futureTextureList) {
        super(gvrContext);
        CylinderParams params = new CylinderParams();

        // assert length of futureTextureList is 3
        if (futureTextureList.size() != 3) {
            throw new IllegalArgumentException(
                    "The length of futureTextureList is not 3.");
        }

        generateCylinderObjectThreeMeshes(gvrContext, params, futureTextureList);
    }

    /**
     * Constructs a cylinder scene object with user-specified height, top-radius, bottom-radius,
     * stacks, slices.
     *
     * The cylinder's triangles and normals are facing either in or out and the
     * same material will be applied to top, bottom, and side of the cylinder.
     *
     * @param gvrContext
     *            current {@link GVRContext}
     *
     * @param bottomRadius
     *            radius for the bottom of the cylinder
     *
     * @param topRadius
     *            radius for the top of the cylinder
     *
     * @param height
     *            height of the cylinder
     *
     * @param stackNumber
     *            number of quads high to make the cylinder.
     *
     * @param sliceNumber
     *            number of quads around to make the cylinder.
     *
     * @param facingOut
     *            true for normals facing out, false for normals facing in.
     */
    public GVRCylinderSceneObject(GVRContext gvrContext, float bottomRadius,
            float topRadius, float height, int stackNumber, int sliceNumber,
            boolean facingOut) {
        super(gvrContext);
        // assert height, numStacks, numSlices > 0
        if (height <= 0 || stackNumber <= 0 || sliceNumber <= 0) {
            throw new IllegalArgumentException(
                    "height, numStacks, and numSlices must be > 0.  Values passed were: height="
                            + height + ", numStacks=" + stackNumber
                            + ", numSlices=" + sliceNumber);
        }
        // assert numCaps > 0
        if (bottomRadius <= 0 && topRadius <= 0) {
            throw new IllegalArgumentException(
                    "bottomRadius and topRadius must be >= 0 and at least one of bottomRadius or topRadius must be > 0.  Values passed were: bottomRadius="
                            + bottomRadius + ", topRadius=" + topRadius);
        }
        CylinderParams params = new CylinderParams();
        params.BottomRadius = bottomRadius;
        params.TopRadius = topRadius;
        params.Height = height;
        params.SliceNumber = sliceNumber;
        params.StackNumber = stackNumber;
        params.FacingOut = facingOut;
        params.Material = new GVRMaterial(gvrContext);
        generateCylinderObject(gvrContext, params);
    }

    /**
     * Constructs a cylinder scene object with user-specified height, top-radius, bottom-radius,
     * stacks, slices.
     *
     * The cylinder's triangles and normals are facing either in or out and the
     * same material will be applied to top, bottom, and side of the cylinder.
     *
     * @param gvrContext
     *            current {@link GVRContext}
     *
     * @param bottomRadius
     *            radius for the bottom of the cylinder
     *
     * @param topRadius
     *            radius for the top of the cylinder
     *
     * @param height
     *            height of the cylinder
     *
     * @param stackNumber
     *            number of quads high to make the cylinder.
     *
     * @param sliceNumber
     *            number of quads around to make the cylinder.
     *
     * @param material
     *            the material for the cylinder.
     *
     * @param facingOut
     *            true for normals facing out, false for normals facing in.
     */
    public GVRCylinderSceneObject(GVRContext gvrContext, float bottomRadius,
            float topRadius, float height, int stackNumber, int sliceNumber,
            boolean facingOut, GVRMaterial material) {
        super(gvrContext);
        // assert height, numStacks, numSlices > 0
        if (height <= 0 || stackNumber <= 0 || sliceNumber <= 0) {
            throw new IllegalArgumentException(
                    "height, numStacks, and numSlices must be > 0.  Values passed were: height="
                            + height + ", numStacks=" + stackNumber
                            + ", numSlices=" + sliceNumber);
        }

        // assert numCaps > 0
        if (bottomRadius <= 0 && topRadius <= 0) {
            throw new IllegalArgumentException(
                    "bottomRadius and topRadius must be >= 0 and at least one of bottomRadius or topRadius must be > 0.  Values passed were: bottomRadius="
                            + bottomRadius + ", topRadius=" + topRadius);
        }
        CylinderParams params = new CylinderParams();
        params.BottomRadius = bottomRadius;
        params.TopRadius = topRadius;
        params.Height = height;
        params.SliceNumber = sliceNumber;
        params.StackNumber = stackNumber;
        params.FacingOut = facingOut;
        params.Material = material;
        generateCylinderObject(gvrContext, params);
    }

    /**
     * Constructs a cylinder scene object with user-specified height, top-radius, bottom-radius,
     * stacks, slices.
     *
     * The cylinder's triangles and normals are facing either in or out. The top, bottom, and side of the cylinder each has its own texture.
     *
     * @param gvrContext
     *            current {@link GVRContext}
     *
     * @param bottomRadius
     *            radius for the bottom of the cylinder
     *
     * @param topRadius
     *            radius for the top of the cylinder
     *
     * @param height
     *            height of the cylinder
     *
     * @param stackNumber
     *            number of quads high to make the cylinder.
     *
     * @param sliceNumber
     *            number of quads around to make the cylinder.
     *
     * @param futureTextureList
     *            the list of three textures for the cylinder. {@code Future<GVRTexture>} is used here for asynchronously loading
     *            the texture. The six textures are for top, side, and bottom faces respectively.
     *
     * @param facingOut
     *            true for normals facing out, false for normals facing in.
     */
    public GVRCylinderSceneObject(GVRContext gvrContext, float bottomRadius,
            float topRadius, float height, int stackNumber, int sliceNumber,
            boolean facingOut, ArrayList<Future<GVRTexture>> futureTextureList) {
        super(gvrContext);
        // assert height, numStacks, numSlices > 0
        if (height <= 0 || stackNumber <= 0 || sliceNumber <= 0) {
            throw new IllegalArgumentException(
                    "height, numStacks, and numSlices must be > 0.  Values passed were: height="
                            + height + ", numStacks=" + stackNumber
                            + ", numSlices=" + sliceNumber);
        }

        // assert numCaps > 0
        if (bottomRadius <= 0 && topRadius <= 0) {
            throw new IllegalArgumentException(
                    "bottomRadius and topRadius must be >= 0 and at least one of bottomRadius or topRadius must be > 0.  Values passed were: bottomRadius="
                            + bottomRadius + ", topRadius=" + topRadius);
        }
        CylinderParams params = new CylinderParams();
        params.BottomRadius = bottomRadius;
        params.TopRadius = topRadius;
        params.Height = height;
        params.SliceNumber = sliceNumber;
        params.StackNumber = stackNumber;
        params.FacingOut = facingOut;

        // assert length of futureTextureList is 3
        if (futureTextureList.size() != 3) {
            throw new IllegalArgumentException(
                    "The length of futureTextureList is not 3.");
        }

        generateCylinderObjectThreeMeshes(gvrContext, params, futureTextureList);
    }

    /**
     * Constructs a cylinder scene object with user-specified height, top-radius, bottom-radius,
     * stacks, slices. The sphere is subdivided into MxN meshes, where M=sliceSegmengNumber and N=(stackSegmentNumber+2) are specified by user.
     *
     * The cylinder's triangles and normals are facing either in or out. The top, bottom, and side of the cylinder each has its own texture.
     *
     * @param gvrContext
     *            current {@link GVRContext}
     *
     * @param bottomRadius
     *            radius for the bottom of the cylinder
     *
     * @param topRadius
     *            radius for the top of the cylinder
     *
     * @param height
     *            height of the cylinder
     *
     * @param stackNumber
     *            number of quads high to make the cylinder.
     *
     * @param sliceNumber
     *            number of quads around to make the cylinder.
     *
     * @param futureTextureList
     *            the list of three textures for the cylinder. {@code Future<
     *            {@code GVRTexture}>} is used here for asynchronously loading
     *            the texture. The six textures are for top, side, and bottom faces respectively.
     *
     * @param stackSegmentNumber
     *            the segment number along vertical direction (i.e. stacks).
     *            Note only body is subdivided along
     *            vertical direction. Number of stacks (i.e.
     *            stackNumber) should be divisible by stackSegmentNumber.
     *
     * @param sliceSegmentNumber
     *            the segment number along horizontal direction (i.e. slices).
     *            Number of slices (i.e. sliceNumber) should be divisible by
     *            sliceSegmentNumber.
     *
     * @param facingOut
     *            true for normals facing out, false for normals facing in.
     */
    public GVRCylinderSceneObject(GVRContext gvrContext, float bottomRadius,
            float topRadius, float height, int stackNumber, int sliceNumber,
            boolean facingOut, ArrayList<Future<GVRTexture>> futureTextureList, int stackSegmentNumber, int sliceSegmentNumber) {
        super(gvrContext);
        // assert height, numStacks, numSlices > 0
        if (height <= 0 || stackNumber <= 0 || sliceNumber <= 0) {
            throw new IllegalArgumentException(
                    "height, numStacks, and numSlices must be > 0.  Values passed were: height="
                            + height + ", numStacks=" + stackNumber
                            + ", numSlices=" + sliceNumber);
        }

        // assert numCaps > 0
        if (bottomRadius <= 0 && topRadius <= 0) {
            throw new IllegalArgumentException(
                    "bottomRadius and topRadius must be >= 0 and at least one of bottomRadius or topRadius must be > 0.  Values passed were: bottomRadius="
                            + bottomRadius + ", topRadius=" + topRadius);
        }

        // assert length of futureTextureList is 3
        if (futureTextureList.size() != 3) {
            throw new IllegalArgumentException(
                    "The length of futureTextureList is not 3.");
        }

        // assert for valid stackSegmentNumber
        if (stackNumber % stackSegmentNumber != 0) {
            throw new IllegalArgumentException(
                    "stackNumber should be divisible by stackSegmentNumber.");
        }

        // assert for valid sliceSegmentNumber
        if (sliceNumber % sliceSegmentNumber != 0) {
            throw new IllegalArgumentException(
                    "sliceNumber should be divisible by sliceSegmentNumber.");
        }
        CylinderParams params = new CylinderParams();
        params.BottomRadius = bottomRadius;
        params.TopRadius = topRadius;
        params.Height = height;
        params.SliceNumber = sliceNumber;
        params.StackNumber = stackNumber;
        params.FacingOut = facingOut;
        generateComplexCylinderObject(gvrContext, params, futureTextureList, stackSegmentNumber, sliceSegmentNumber);
    }

    /**
     * Constructs a cylinder scene object with user-specified height, top-radius, bottom-radius,
     * stacks, slices. The sphere is subdivided into MxN meshes, where M=sliceSegmengNumber and N=(stackSegmentNumber+2) are specified by user.
     *
     * The cylinder's triangles and normals are facing either in or out and the
     * same material will be applied to top, bottom, and side of the cylinder.
     *
     * @param gvrContext
     *            current {@link GVRContext}
     *
     * @param bottomRadius
     *            radius for the bottom of the cylinder
     *
     * @param topRadius
     *            radius for the top of the cylinder
     *
     * @param height
     *            height of the cylinder
     *
     * @param stackNumber
     *            number of quads high to make the cylinder.
     *
     * @param sliceNumber
     *            number of quads around to make the cylinder.
     *
     * @param material
     *            the material for the cylinder.
     *
     * @param stackSegmentNumber
     *            the segment number along vertical direction (i.e. stacks).
     *            Note only body is subdivided along
     *            vertical direction. Number of stacks (i.e.
     *            stackNumber) should be divisible by stackSegmentNumber.
     *
     * @param sliceSegmentNumber
     *            the segment number along horizontal direction (i.e. slices).
     *            Number of slices (i.e. sliceNumber) should be divisible by
     *            sliceSegmentNumber.
     *
     * @param facingOut
     *            true for normals facing out, false for normals facing in.
     */
    public GVRCylinderSceneObject(GVRContext gvrContext, float bottomRadius,
            float topRadius, float height, int stackNumber, int sliceNumber,
            boolean facingOut, GVRMaterial material, int stackSegmentNumber, int sliceSegmentNumber) {
        super(gvrContext);
        // assert height, numStacks, numSlices > 0
        if (height <= 0 || stackNumber <= 0 || sliceNumber <= 0) {
            throw new IllegalArgumentException(
                    "height, numStacks, and numSlices must be > 0.  Values passed were: height="
                            + height + ", numStacks=" + stackNumber
                            + ", numSlices=" + sliceNumber);
        }

        // assert numCaps > 0
        if (bottomRadius <= 0 && topRadius <= 0) {
            throw new IllegalArgumentException(
                    "bottomRadius and topRadius must be >= 0 and at least one of bottomRadius or topRadius must be > 0.  Values passed were: bottomRadius="
                            + bottomRadius + ", topRadius=" + topRadius);
        }

        // assert for valid stackSegmentNumber
        if (stackNumber % stackSegmentNumber != 0) {
            throw new IllegalArgumentException(
                    "stackNumber should be divisible by stackSegmentNumber.");
        }

        // assert for valid sliceSegmentNumber
        if (sliceNumber % sliceSegmentNumber != 0) {
            throw new IllegalArgumentException(
                    "sliceNumber should be divisible by sliceSegmentNumber.");
        }
        CylinderParams params = new CylinderParams();
        params.BottomRadius = bottomRadius;
        params.TopRadius = topRadius;
        params.Height = height;
        params.SliceNumber = sliceNumber;
        params.StackNumber = stackNumber;
        params.FacingOut = facingOut;
        params.Material = material;

        generateComplexCylinderObject(gvrContext, params, stackSegmentNumber, sliceSegmentNumber);
    }

    private void generateCylinderObject(GVRContext gvrContext, CylinderParams params) {
        generateCylinder(params);

        GVRMesh mesh = new GVRMesh(gvrContext);
        GVRMaterial material = params.Material;

        if (material == null)
            material = new GVRMaterial(gvrContext);
        mesh.setVertices(vertices);
        mesh.setNormals(normals);
        mesh.setTexCoords(texCoords);
        mesh.setTriangles(indices);

        GVRRenderData renderData = new GVRRenderData(gvrContext);
        attachRenderData(renderData);
        renderData.setMesh(mesh);
        renderData.setMaterial(material);
    }

    private void generateCylinderObjectThreeMeshes(GVRContext gvrContext,
            CylinderParams params,
            ArrayList<Future<GVRTexture>> futureTextureList) {
        float halfHeight = params.Height / 2.0f;

        // top cap
        if (params.TopRadius > 0) {
            createCapMesh(gvrContext, params.TopRadius, halfHeight, params.SliceNumber,
                    1.0f, params.FacingOut, futureTextureList.get(0));
        }

        // cylinder body
        createBodyMesh(gvrContext, params, futureTextureList.get(1));

        // bottom cap
        if (params.BottomRadius > 0) {
            createCapMesh(gvrContext, params.BottomRadius, -halfHeight, params.SliceNumber,
                    -1.0f, params.FacingOut, futureTextureList.get(2));
        }

        // attached an empty renderData for parent object, so that we can set some common properties
        GVRRenderData renderData = new GVRRenderData(gvrContext);
        attachRenderData(renderData);
    }

    private void generateCylinder(CylinderParams params) {

        int capNumber = 2;
        if (params.BottomRadius == 0) {
            capNumber--;
        }

        if (params.TopRadius == 0) {
            capNumber--;
        }

        int capVertexNumber = 3 * params.SliceNumber;
        int bodyVertexNumber = 4 * params.SliceNumber * params.StackNumber;
        int vertexNumber = (capNumber * capVertexNumber) + bodyVertexNumber;
        int triangleNumber = (capNumber * capVertexNumber)
                + (6 * params.SliceNumber * params.StackNumber);
        float halfHeight = params.Height / 2.0f;

        vertices = new float[3 * vertexNumber];
        normals = new float[3 * vertexNumber];
        texCoords = new float[2 * vertexNumber];
        indices = new char[triangleNumber];

        // top cap
        // 3 * numSlices
        if (params.HasTopCap && (params.TopRadius > 0)) {
            createCap(params.TopRadius, halfHeight, params.SliceNumber, 1.0f, params.FacingOut);
        }

        // cylinder body
        // 4 * numSlices * numStacks
        createBody(params);

        // bottom cap
        // 3 * numSlices
        if (params.BottomRadius > 0) {
            createCap(params.BottomRadius, -halfHeight, params.SliceNumber, -1.0f, params.FacingOut);
        }
    }

    private void createCap(float radius, float height, int sliceNumber,
            float normalDirection, boolean facingOut) {
        if (!facingOut) {
            normalDirection = -normalDirection;
        }
        for (int slice = 0; slice < sliceNumber; slice++) {
            double theta0 = ((double) (slice) / sliceNumber) * 2.0 * Math.PI;
            double theta1 = ((double) (slice + 1) / sliceNumber) * 2.0
                    * Math.PI;

            float y = height;
            float x0 = (float) (radius * Math.cos(theta0));
            float z0 = (float) (radius * Math.sin(theta0));
            float x1 = (float) (radius * Math.cos(theta1));
            float z1 = (float) (radius * Math.sin(theta1));

            float s0, s1;
            if (normalDirection > 0) {
                s0 = (float) (slice) / sliceNumber;
                s1 = (float) (slice + 1) / sliceNumber;
            } else {
                s0 = 1.0f - (float) (slice) / sliceNumber;
                s1 = 1.0f - (float) (slice + 1) / sliceNumber;
            }
            float s2 = (s0 + s1) / 2.0f;

            vertices[vertexCount + 0] = x0;
            vertices[vertexCount + 1] = y;
            vertices[vertexCount + 2] = z0;
            vertices[vertexCount + 3] = x1;
            vertices[vertexCount + 4] = y;
            vertices[vertexCount + 5] = z1;
            vertices[vertexCount + 6] = 0.0f;
            vertices[vertexCount + 7] = y;
            vertices[vertexCount + 8] = 0.0f;

            normals[vertexCount + 0] = 0.0f;
            normals[vertexCount + 1] = normalDirection;
            normals[vertexCount + 2] = 0.0f;
            normals[vertexCount + 3] = 0.0f;
            normals[vertexCount + 4] = normalDirection;
            normals[vertexCount + 5] = 0.0f;
            normals[vertexCount + 6] = 0.0f;
            normals[vertexCount + 7] = normalDirection;
            normals[vertexCount + 8] = 0.0f;

            texCoords[texCoordCount + 0] = s0;
            texCoords[texCoordCount + 1] = 0.0f;

            texCoords[texCoordCount + 2] = s1;
            texCoords[texCoordCount + 3] = 0.0f;

            texCoords[texCoordCount + 4] = s2;
            texCoords[texCoordCount + 5] = 1.0f;

            if (normalDirection > 0) {
                indices[indexCount + 0] = (char) (triangleCount + 1);
                indices[indexCount + 1] = (char) (triangleCount + 0);
                indices[indexCount + 2] = (char) (triangleCount + 2);
            } else {
                indices[indexCount + 0] = (char) (triangleCount + 0);
                indices[indexCount + 1] = (char) (triangleCount + 1);
                indices[indexCount + 2] = (char) (triangleCount + 2);
            }

            vertexCount += 9;
            texCoordCount += 6;
            indexCount += 3;
            triangleCount += 3;
        }
    }

    private void createBody(CylinderParams params) {
        float difference = params.BottomRadius - params.TopRadius;
        float length = (float) Math.sqrt(difference*difference + params.Height * params.Height);
        float ratio = params.Height / length;
        float halfHeight = params.Height / 2.0f;

        for (int stack = 0; stack < params.StackNumber; stack++) {

            float stackPercentage0 = ((float) (stack) / params.StackNumber);
            float stackPercentage1 = ((float) (stack + 1) / params.StackNumber);
            float radius0 = (params.BottomRadius - (difference * stackPercentage0));
            float radius1 = (params.BottomRadius - (difference * stackPercentage1));

            float t0 = 1.0f - stackPercentage0;
            float t1 = 1.0f - stackPercentage1;
            float y0 = -halfHeight + (stackPercentage0 * params.Height);
            float y1 = -halfHeight + (stackPercentage1 * params.Height);

            for (int slice = 0; slice < params.SliceNumber; slice++) {
                float slicePercentage0 = ((float) (slice) / params.SliceNumber);
                float slicePercentage1 = ((float) (slice + 1) / params.SliceNumber);
                double theta0 = slicePercentage0 * 2.0 * Math.PI;
                double theta1 = slicePercentage1 * 2.0 * Math.PI;
                double cosTheta0 = Math.cos(theta0);
                double sinTheta0 = Math.sin(theta0);
                double cosTheta1 = Math.cos(theta1);
                double sinTheta1 = Math.sin(theta1);

                float x0 = (float) (radius0 * cosTheta0);
                float z0 = (float) (-radius0 * sinTheta0);
                float x1 = (float) (radius0 * cosTheta1);
                float z1 = (float) (-radius0 * sinTheta1);

                float x2 = (float) (radius1 * cosTheta0);
                float z2 = (float) (-radius1 * sinTheta0);
                float x3 = (float) (radius1 * cosTheta1);
                float z3 = (float) (-radius1 * sinTheta1);

                float s0, s1;
                if (params.FacingOut) {
                    s0 = slicePercentage0;
                    s1 = slicePercentage1;
                } else {
                    s0 = 1.0f - slicePercentage0;
                    s1 = 1.0f - slicePercentage1;
                }

                vertices[vertexCount + 0] = x0;
                vertices[vertexCount + 1] = y0;
                vertices[vertexCount + 2] = z0;

                vertices[vertexCount + 3] = x1;
                vertices[vertexCount + 4] = y0;
                vertices[vertexCount + 5] = z1;

                vertices[vertexCount + 6] = x2;
                vertices[vertexCount + 7] = y1;
                vertices[vertexCount + 8] = z2;

                vertices[vertexCount + 9] = x3;
                vertices[vertexCount + 10] = y1;
                vertices[vertexCount + 11] = z3;

                // calculate normal
                float nx0 = (float) (ratio * cosTheta0);
                float nx1 = (float) (ratio * cosTheta1);
                float ny = difference / length;
                float nz0 = (float) (-ratio * sinTheta0);
                float nz1 = (float) (-ratio * sinTheta0);

                normals[vertexCount + 0] = nx0;
                normals[vertexCount + 1] = ny;
                normals[vertexCount + 2] = nz0;

                normals[vertexCount + 3] = nx1;
                normals[vertexCount + 4] = ny;
                normals[vertexCount + 5] = nz1;

                normals[vertexCount + 6] = nx0;
                normals[vertexCount + 7] = ny;
                normals[vertexCount + 8] = nz0;

                normals[vertexCount + 9] = nx1;
                normals[vertexCount + 10] = ny;
                normals[vertexCount + 11] = nz1;

                texCoords[texCoordCount + 0] = s0;
                texCoords[texCoordCount + 1] = t0;

                texCoords[texCoordCount + 2] = s1;
                texCoords[texCoordCount + 3] = t0;

                texCoords[texCoordCount + 4] = s0;
                texCoords[texCoordCount + 5] = t1;

                texCoords[texCoordCount + 6] = s1;
                texCoords[texCoordCount + 7] = t1;

                // one quad looking from outside toward center
                //
                // @formatter:off
                //
                // t1   2-----3
                //  |   |     |
                //  v   |     |
                // t0   0-----1
                //
                //     s0 --> s1
                //
                // @formatter:on
                //
                // Note that tex_coord t increase from top to bottom because the
                // texture image is loaded upside down.
                if (params.FacingOut) {
                    indices[indexCount + 0] = (char) (triangleCount + 0); // 0
                    indices[indexCount + 1] = (char) (triangleCount + 1); // 1
                    indices[indexCount + 2] = (char) (triangleCount + 2); // 2

                    indices[indexCount + 3] = (char) (triangleCount + 2); // 2
                    indices[indexCount + 4] = (char) (triangleCount + 1); // 1
                    indices[indexCount + 5] = (char) (triangleCount + 3); // 3
                } else {
                    indices[indexCount + 0] = (char) (triangleCount + 0); // 0
                    indices[indexCount + 1] = (char) (triangleCount + 2); // 2
                    indices[indexCount + 2] = (char) (triangleCount + 1); // 1

                    indices[indexCount + 3] = (char) (triangleCount + 2); // 2
                    indices[indexCount + 4] = (char) (triangleCount + 3); // 3
                    indices[indexCount + 5] = (char) (triangleCount + 1); // 1
                }

                vertexCount += 12;
                texCoordCount += 8;
                indexCount += 6;
                triangleCount += 4;
            }
        }
    }

    private void createCapMesh(GVRContext gvrContext, float radius, float height, int sliceNumber,
            float normalDirection, boolean facingOut, Future<GVRTexture> futureTexture) {
        int capVertexNumber = 3 * sliceNumber;
        vertices = new float[3 * capVertexNumber];
        normals = new float[3 * capVertexNumber];
        texCoords = new float[2 * capVertexNumber];
        indices = new char[capVertexNumber];

        vertexCount = 0;
        texCoordCount = 0;
        indexCount = 0;
        triangleCount = 0;

        createCap(radius, height, sliceNumber, normalDirection, facingOut);

        GVRMesh mesh = new GVRMesh(gvrContext);
        mesh.setVertices(vertices);
        mesh.setNormals(normals);
        mesh.setTexCoords(texCoords);
        mesh.setTriangles(indices);

        GVRSceneObject child = new GVRSceneObject(gvrContext,
                new FutureWrapper<GVRMesh>(mesh),
                futureTexture);
        addChildObject(child);
   }

    private void createBodyMesh(GVRContext gvrContext, CylinderParams params, Future<GVRTexture> futureTexture) {
        int bodyVertexNumber = 4 * params.SliceNumber * params.StackNumber;
        int triangleNumber = 6 * params.SliceNumber * params.StackNumber;

        vertices = new float[3 * bodyVertexNumber];
        normals = new float[3 * bodyVertexNumber];
        texCoords = new float[2 * triangleNumber];
        indices = new char[triangleNumber];

        vertexCount = 0;
        texCoordCount = 0;
        indexCount = 0;
        triangleCount = 0;

        createBody(params);

        GVRMesh mesh = new GVRMesh(gvrContext);
        mesh.setVertices(vertices);
        mesh.setNormals(normals);
        mesh.setTexCoords(texCoords);
        mesh.setTriangles(indices);

        GVRSceneObject child = new GVRSceneObject(gvrContext,
                new FutureWrapper<GVRMesh>(mesh),
                futureTexture);
        addChildObject(child);
    }

    private void generateComplexCylinderObject(GVRContext gvrContext,
            CylinderParams params,
            ArrayList<Future<GVRTexture>> futureTextureList, int stackSegmentNumber, int sliceSegmentNumber) {
        float halfHeight = params.Height / 2.0f;

        GVRMaterial material;
        // top cap
        if (params.HasTopCap && (params.TopRadius > 0)) {
            material = new GVRMaterial(gvrContext);
            material.setMainTexture(futureTextureList.get(0));
            createComplexCap(gvrContext, params.TopRadius, halfHeight, params.SliceNumber,
                    1.0f, params.FacingOut, material, params.SliceNumber);
        }

        // cylinder body
        material = new GVRMaterial(gvrContext);
        material.setMainTexture(futureTextureList.get(1));
        createComplexBody(gvrContext, params, stackSegmentNumber, sliceSegmentNumber);

        // bottom cap
        if (params.HasBottomCap && (params.BottomRadius > 0)) {
            material = new GVRMaterial(gvrContext);
            material.setMainTexture(futureTextureList.get(2));
            createComplexCap(gvrContext, params.BottomRadius, -halfHeight, params.SliceNumber,
                    -1.0f, params.FacingOut, material, params.SliceNumber);
        }

        // attached an empty renderData for parent object, so that we can set some common properties
        GVRRenderData renderData = new GVRRenderData(gvrContext);
        attachRenderData(renderData);
    }

    private void generateComplexCylinderObject(GVRContext gvrContext,
            CylinderParams params,
            int stackSegmentNumber, int sliceSegmentNumber) {
        float halfHeight = params.Height / 2.0f;

        // top cap
        if (params.HasTopCap && (params.TopRadius > 0)) {
            createComplexCap(gvrContext, params.TopRadius, halfHeight, params.SliceNumber,
                    1.0f, params.FacingOut, params.Material, params.SliceNumber);
        }

        // cylinder body
        createComplexBody(gvrContext, params, stackSegmentNumber, sliceSegmentNumber);

        // bottom cap
        if (params.HasBottomCap && (params.BottomRadius > 0)) {
            createComplexCap(gvrContext, params.BottomRadius, -halfHeight, params.SliceNumber,
                    -1.0f, params.FacingOut, params.Material, params.SliceNumber);
        }

        // attached an empty renderData for parent object, so that we can set some common properties
        GVRRenderData renderData = new GVRRenderData(gvrContext);
        attachRenderData(renderData);
    }

    private void createComplexCap(GVRContext gvrContext, float radius, float height, int sliceNumber,
            float normalDirection, boolean facingOut, GVRMaterial material, int sliceSegmentNumber) {
        if (!facingOut) {
            normalDirection = -normalDirection;
        }

        int slicePerSegment = sliceNumber / sliceSegmentNumber;
        int vertexNumber = 3 * slicePerSegment;
        vertices = new float[3 * vertexNumber];
        normals = new float[3 * vertexNumber];
        texCoords = new float[2 * vertexNumber];
        indices = new char[vertexNumber];

        vertexCount = 0;
        texCoordCount = 0;
        indexCount = 0;
        triangleCount = 0;

        int sliceCounter = 0;

        for (int slice = 0; slice < sliceNumber; slice++) {
            double theta0 = ((double) (slice) / sliceNumber) * 2.0 * Math.PI;
            double theta1 = ((double) (slice + 1) / sliceNumber) * 2.0
                    * Math.PI;

            float y = height;
            float x0 = (float) (radius * Math.cos(theta0));
            float z0 = (float) (radius * Math.sin(theta0));
            float x1 = (float) (radius * Math.cos(theta1));
            float z1 = (float) (radius * Math.sin(theta1));

            float s0, s1;
            if (normalDirection > 0) {
                s0 = (float) (slice) / sliceNumber;
                s1 = (float) (slice + 1) / sliceNumber;
            } else {
                s0 = 1.0f - (float) (slice) / sliceNumber;
                s1 = 1.0f - (float) (slice + 1) / sliceNumber;
            }
            float s2 = (s0 + s1) / 2.0f;

            vertices[vertexCount + 0] = x0;
            vertices[vertexCount + 1] = y;
            vertices[vertexCount + 2] = z0;
            vertices[vertexCount + 3] = x1;
            vertices[vertexCount + 4] = y;
            vertices[vertexCount + 5] = z1;
            vertices[vertexCount + 6] = 0.0f;
            vertices[vertexCount + 7] = y;
            vertices[vertexCount + 8] = 0.0f;

            normals[vertexCount + 0] = 0.0f;
            normals[vertexCount + 1] = normalDirection;
            normals[vertexCount + 2] = 0.0f;
            normals[vertexCount + 3] = 0.0f;
            normals[vertexCount + 4] = normalDirection;
            normals[vertexCount + 5] = 0.0f;
            normals[vertexCount + 6] = 0.0f;
            normals[vertexCount + 7] = normalDirection;
            normals[vertexCount + 8] = 0.0f;

            texCoords[texCoordCount + 0] = s0;
            texCoords[texCoordCount + 1] = 0.0f;

            texCoords[texCoordCount + 2] = s1;
            texCoords[texCoordCount + 3] = 0.0f;

            texCoords[texCoordCount + 4] = s2;
            texCoords[texCoordCount + 5] = 1.0f;

            if (normalDirection > 0) {
                indices[indexCount + 0] = (char) (triangleCount + 1);
                indices[indexCount + 1] = (char) (triangleCount + 0);
                indices[indexCount + 2] = (char) (triangleCount + 2);
            } else {
                indices[indexCount + 0] = (char) (triangleCount + 0);
                indices[indexCount + 1] = (char) (triangleCount + 1);
                indices[indexCount + 2] = (char) (triangleCount + 2);
            }

            sliceCounter++;
            if (sliceCounter == slicePerSegment) {
                GVRMesh mesh = new GVRMesh(gvrContext);
                mesh.setVertices(vertices);
                mesh.setNormals(normals);
                mesh.setTexCoords(texCoords);
                mesh.setTriangles(indices);
                GVRSceneObject childObject = new GVRSceneObject(gvrContext,
                        mesh);
                childObject.getRenderData().setMaterial(material);
                addChildObject(childObject);

                sliceCounter = 0;

                vertexCount = 0;
                texCoordCount = 0;
                indexCount = 0;
                triangleCount = 0;
            } else {
                vertexCount += 9;
                texCoordCount += 6;
                indexCount += 3;
                triangleCount += 3;
            }
        }
    }

    private void createComplexBody(GVRContext gvrContext, CylinderParams params, int stackSegmentNumber, int sliceSegmentNumber) {
        float difference = params.BottomRadius - params.TopRadius;
        float length = (float) Math.sqrt(difference*difference + params.Height * params.Height);
        float ratio = params.Height / length;
        float halfHeight = params.Height / 2.0f;

        int stackPerSegment = params.StackNumber / stackSegmentNumber;
        int slicePerSegment = params.SliceNumber / sliceSegmentNumber;

        int vertexNumber = 4 * stackPerSegment * slicePerSegment;
        int triangleNumber = 6 * stackPerSegment * slicePerSegment;
        vertices = new float[3 * vertexNumber];
        normals = new float[3 * vertexNumber];
        texCoords = new float[2 * vertexNumber];
        indices = new char[triangleNumber];

        vertexCount = 0;
        texCoordCount = 0;
        indexCount = 0;
        triangleCount = 0;

        for (int stackSegment = 0; stackSegment < stackSegmentNumber; stackSegment++) {
            for (int sliceSegment = 0; sliceSegment < sliceSegmentNumber; sliceSegment++) {
                for (int stack = stackSegment * stackPerSegment; stack < (stackSegment+1) * stackPerSegment; stack++) {
                    float stackPercentage0 = ((float) (stack) / params.StackNumber);
                    float stackPercentage1 = ((float) (stack + 1) / params.StackNumber);

                    float t0 = 1.0f - stackPercentage0;
                    float t1 = 1.0f - stackPercentage1;
                    float y0 = -halfHeight + (stackPercentage0 * params.Height);
                    float y1 = -halfHeight + (stackPercentage1 * params.Height);

                    for (int slice = sliceSegment * slicePerSegment; slice < (sliceSegment+1) * slicePerSegment; slice++) {
                        float slicePercentage0 = ((float) (slice) / params.SliceNumber);
                        float slicePercentage1 = ((float) (slice + 1) / params.SliceNumber);
                        double theta0 = slicePercentage0 * 2.0 * Math.PI;
                        double theta1 = slicePercentage1 * 2.0 * Math.PI;
                        double cosTheta0 = Math.cos(theta0);
                        double sinTheta0 = Math.sin(theta0);
                        double cosTheta1 = Math.cos(theta1);
                        double sinTheta1 = Math.sin(theta1);

                        float radius = (params.BottomRadius - (difference * stackPercentage0));
                        float x0 = (float) (radius * cosTheta0);
                        float z0 = (float) (-radius * sinTheta0);
                        float x1 = (float) (radius * cosTheta1);
                        float z1 = (float) (-radius * sinTheta1);

                        radius = (params.BottomRadius - (difference * stackPercentage1));
                        float x2 = (float) (radius * cosTheta0);
                        float z2 = (float) (-radius * sinTheta0);
                        float x3 = (float) (radius * cosTheta1);
                        float z3 = (float) (-radius * sinTheta1);

                        float s0, s1;
                        if (params.FacingOut) {
                            s0 = slicePercentage0;
                            s1 = slicePercentage1;
                        } else {
                            s0 = 1.0f - slicePercentage0;
                            s1 = 1.0f - slicePercentage1;
                        }

                        vertices[vertexCount + 0] = x0;
                        vertices[vertexCount + 1] = y0;
                        vertices[vertexCount + 2] = z0;

                        vertices[vertexCount + 3] = x1;
                        vertices[vertexCount + 4] = y0;
                        vertices[vertexCount + 5] = z1;

                        vertices[vertexCount + 6] = x2;
                        vertices[vertexCount + 7] = y1;
                        vertices[vertexCount + 8] = z2;

                        vertices[vertexCount + 9] = x3;
                        vertices[vertexCount + 10] = y1;
                        vertices[vertexCount + 11] = z3;

                        // calculate normal
                        float nx0 = (float) (ratio * cosTheta0);
                        float nx1 = (float) (ratio * cosTheta1);
                        float ny = difference / length;
                        float nz0 = (float) (-ratio * sinTheta0);
                        float nz1 = (float) (-ratio * sinTheta0);

                        normals[vertexCount + 0] = nx0;
                        normals[vertexCount + 1] = ny;
                        normals[vertexCount + 2] = nz0;

                        normals[vertexCount + 3] = nx1;
                        normals[vertexCount + 4] = ny;
                        normals[vertexCount + 5] = nz1;

                        normals[vertexCount + 6] = nx0;
                        normals[vertexCount + 7] = ny;
                        normals[vertexCount + 8] = nz0;

                        normals[vertexCount + 9] = nx1;
                        normals[vertexCount + 10] = ny;
                        normals[vertexCount + 11] = nz1;

                        texCoords[texCoordCount + 0] = s0;
                        texCoords[texCoordCount + 1] = t0;

                        texCoords[texCoordCount + 2] = s1;
                        texCoords[texCoordCount + 3] = t0;

                        texCoords[texCoordCount + 4] = s0;
                        texCoords[texCoordCount + 5] = t1;

                        texCoords[texCoordCount + 6] = s1;
                        texCoords[texCoordCount + 7] = t1;

                        // one quad looking from outside toward center
                        //
                        // @formatter:off
                        //
                        // t1   2-----3
                        //  |   |     |
                        //  v   |     |
                        // t0   0-----1
                        //
                        //     s0 --> s1
                        //
                        // @formatter:on
                        //
                        // Note that tex_coord t increase from top to bottom because the
                        // texture image is loaded upside down.
                        if (params.FacingOut) {
                            indices[indexCount + 0] = (char) (triangleCount + 0); // 0
                            indices[indexCount + 1] = (char) (triangleCount + 1); // 1
                            indices[indexCount + 2] = (char) (triangleCount + 2); // 2

                            indices[indexCount + 3] = (char) (triangleCount + 2); // 2
                            indices[indexCount + 4] = (char) (triangleCount + 1); // 1
                            indices[indexCount + 5] = (char) (triangleCount + 3); // 3
                        } else {
                            indices[indexCount + 0] = (char) (triangleCount + 0); // 0
                            indices[indexCount + 1] = (char) (triangleCount + 2); // 2
                            indices[indexCount + 2] = (char) (triangleCount + 1); // 1

                            indices[indexCount + 3] = (char) (triangleCount + 2); // 2
                            indices[indexCount + 4] = (char) (triangleCount + 3); // 3
                            indices[indexCount + 5] = (char) (triangleCount + 1); // 1
                        }

                        vertexCount += 12;
                        texCoordCount += 8;
                        indexCount += 6;
                        triangleCount += 4;
                    }
                }

                GVRMesh mesh = new GVRMesh(gvrContext);
                mesh.setVertices(vertices);
                mesh.setNormals(normals);
                mesh.setTexCoords(texCoords);
                mesh.setTriangles(indices);
                GVRSceneObject childObject = new GVRSceneObject(gvrContext,
                        mesh);
                childObject.getRenderData().setMaterial(params.Material);
                addChildObject(childObject);

                vertexCount = 0;
                texCoordCount = 0;
                indexCount = 0;
                triangleCount = 0;
            }
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
package dreamhost

import (
	"fmt"
	"net/http"
	"net/http/httptest"
	"testing"
	"time"

	"github.com/go-acme/lego/v3/platform/tester"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

var envTest = tester.NewEnvTest("DREAMHOST_API_KEY").
	WithDomain("DREAMHOST_TEST_DOMAIN")

const (
	fakeAPIKey         = "asdf1234"
	fakeChallengeToken = "foobar"
	fakeKeyAuth        = "w6uP8Tcg6K2QR905Rms8iXTlksL6OD1KOWBxTK7wxPI"
)

func setupTest() (*DNSProvider, *http.ServeMux, func()) {
	handler := http.NewServeMux()
	server := httptest.NewServer(handler)

	config := NewDefaultConfig()
	config.APIKey = fakeAPIKey
	config.BaseURL = server.URL

	provider, err := NewDNSProviderConfig(config)
	if err != nil {
		panic(err)
	}

	return provider, handler, server.Close
}

func TestNewDNSProvider(t *testing.T) {
	testCases := []struct {
		desc     string
		envVars  map[string]string
		expected string
	}{
		{
			desc: "success",
			envVars: map[string]string{
				"DREAMHOST_API_KEY": "123",
			},
		},
		{
			desc: "missing API key",
			envVars: map[string]string{
				"DREAMHOST_API_KEY": "",
			},
			expected: "dreamhost: some credentials information are missing: DREAMHOST_API_KEY",
		},
	}

	for _, test := range testCases {
		t.Run(test.desc, func(t *testing.T) {
			defer envTest.RestoreEnv()
			envTest.ClearEnv()

			envTest.Apply(test.envVars)

			p, err := NewDNSProvider()

			if len(test.expected) == 0 {
				assert.NoError(t, err)
				assert.NotNil(t, p)
			} else {
				require.EqualError(t, err, test.expected)
			}
		})
	}
}

func TestNewDNSProviderConfig(t *testing.T) {
	testCases := []struct {
		desc     string
		apiKey   string
		expected string
	}{
		{
			desc:   "success",
			apiKey: "123",
		},
		{
			desc:     "missing credentials",
			expected: "dreamhost: credentials missing",
		},
	}

	for _, test := range testCases {
		t.Run(test.desc, func(t *testing.T) {
			config := NewDefaultConfig()
			config.APIKey = test.apiKey

			p, err := NewDNSProviderConfig(config)

			if len(test.expected) == 0 {
				assert.NoError(t, err)
				assert.NotNil(t, p)
			} else {
				require.EqualError(t, err, test.expected)
			}
		})
	}
}

func TestDNSProvider_Present(t *testing.T) {
	provider, mux, tearDown := setupTest()
	defer tearDown()

	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, http.MethodGet, r.Method, "method")

		q := r.URL.Query()
		assert.Equal(t, q.Get("key"), fakeAPIKey)
		assert.Equal(t, q.Get("cmd"), "dns-add_record")
		assert.Equal(t, q.Get("format"), "json")
		assert.Equal(t, q.Get("record"), "_acme-challenge.example.com")
		assert.Equal(t, q.Get("value"), fakeKeyAuth)
		assert.Equal(t, q.Get("comment"), "Managed+By+lego")

		_, err := fmt.Fprintf(w, `{"data":"record_added","result":"success"}`)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	})

	err := provider.Present("example.com", "", fakeChallengeToken)
	require.NoError(t, err)
}

func TestDNSProvider_PresentFailed(t *testing.T) {
	provider, mux, tearDown := setupTest()
	defer tearDown()

	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, http.MethodGet, r.Method, "method")

		_, err := fmt.Fprintf(w, `{"data":"record_already_exists_remove_first","result":"error"}`)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	})

	err := provider.Present("example.com", "", fakeChallengeToken)
	require.EqualError(t, err, "dreamhost: add TXT record failed: record_already_exists_remove_first")
}

func TestDNSProvider_Cleanup(t *testing.T) {
	provider, mux, tearDown := setupTest()
	defer tearDown()

	mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		assert.Equal(t, http.MethodGet, r.Method, "method")

		q := r.URL.Query()
		assert.Equal(t, q.Get("key"), fakeAPIKey, "key mismatch")
		assert.Equal(t, q.Get("cmd"), "dns-remove_record", "cmd mismatch")
		assert.Equal(t, q.Get("format"), "json")
		assert.Equal(t, q.Get("record"), "_acme-challenge.example.com")
		assert.Equal(t, q.Get("value"), fakeKeyAuth, "value mismatch")
		assert.Equal(t, q.Get("comment"), "Managed+By+lego")

		_, err := fmt.Fprintf(w, `{"data":"record_removed","result":"success"}`)
		if err != nil {
			http.Error(w, err.Error(), http.StatusInternalServerError)
		}
	})

	err := provider.CleanUp("example.com", "", fakeChallengeToken)
	require.NoError(t, err, "failed to remove TXT record")
}

func TestLivePresentAndCleanUp(t *testing.T) {
	if !envTest.IsLiveTest() {
		t.Skip("skipping live test")
	}

	envTest.RestoreEnv()
	provider, err := NewDNSProvider()
	require.NoError(t, err)

	err = provider.Present(envTest.GetDomain(), "", "123d==")
	require.NoError(t, err)

	time.Sleep(1 * time.Second)

	err = provider.CleanUp(envTest.GetDomain(), "", "123d==")
	require.NoError(t, err)
}


text:
<!DOCTYPE html>

	<meta charset="utf-8" />
	<meta name="viewport" content="width=device-width, user-scalable=no
		initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0" />

	<title>Redbear Labs - Simple Chat</title>

		<button class="back" onclick="history.back()">

		</button>

Simple Chat

		<button class="red wide" onclick="app.startScan()">Scan</button>

			<input id="messageField" value="Hello World!" type="text"
				onchange="app.sendMessage()">

			<button id="sendButton" class="green wide"
				onclick="app.sendMessage()">Send</button>

			<button id="disconnectButton" class="red wide"
				onclick="app.disconnect()">Disconnect</button>


text:
// Copyright 2011-2016 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.security.zynamics.binnavi.Gui.MainWindow;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreePath;

import com.google.common.base.Preconditions;
import com.google.security.zynamics.binnavi.API.plugins.IPluginInterfaceListener;
import com.google.security.zynamics.binnavi.API.plugins.PluginInterface;
import com.google.security.zynamics.binnavi.Database.CDatabaseManager;
import com.google.security.zynamics.binnavi.Gui.MainWindow.ProjectTree.CProjectTree;
import com.google.security.zynamics.binnavi.Gui.MainWindow.ProjectTree.Nodes.IProjectTreeNode;

/**
 * This class creates the panel that is shown in the main window. On the left side of the panel
 * there is the tree that shows the databases/projects/... that are available. On the right side of
 * the panel a panel is shown whose content depends on the currently selected node.
 */
public final class CProjectMainPanel extends JPanel {
  /**
   * Used for serialization.
   */
  private static final long serialVersionUID = 2093952613078997535L;

  /**
   * The main window of BinNavi where this panel belongs to.
   */
  private final JFrame m_window;

  /**
   * The component panel of the main panel is the panel where the components are shown that depend
   * on the current selection inside the project tree.
   */
  private final JPanel m_componentPanel = new JPanel(new BorderLayout());

  /**
   * Project tree shown in the main window.
   */
  private final CProjectTree m_projectTree;

  /**
   * Listener that updates the GUI when plugins are loaded.
   */
  private final InternalPluginListener m_pluginListener = new InternalPluginListener();

  /**
   * Creates a new main panel.
   *
   * @param window Parent window of the panel.
   * @param databaseManager The database manager that contains the known databases.
   *
   * @throws IllegalArgumentException Thrown if any of the arguments is null.
   */
  public CProjectMainPanel(final JFrame window, final CDatabaseManager databaseManager) {
    super(new BorderLayout());
    m_window = Preconditions.checkNotNull(window, "IE01830: Window argument can't be null");
    Preconditions.checkNotNull(databaseManager, "IE01831: Database manager argument can't be null");
    m_projectTree = new CProjectTree(m_window, databaseManager);
    add(createMainSplitPane(), BorderLayout.CENTER);
    PluginInterface.instance().addListener(m_pluginListener);
  }

  /**
   * Creates the main split pane. The main split pane divides the main window into project tree on
   * the left side of the main window and the state-specific views on the right side of the main
   * window.
   *
   * @return The main split pane.
   */
  private JSplitPane createMainSplitPane() {
    final JSplitPane mainSplitPane = new JSplitPane();
    mainSplitPane.setOneTouchExpandable(true);
    mainSplitPane.setDividerLocation(250);
    mainSplitPane.setResizeWeight(0.33);
    mainSplitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);

    m_componentPanel.setBackground(Color.WHITE);

    mainSplitPane.setLeftComponent(createProjectTreePanel());
    mainSplitPane.setRightComponent(m_componentPanel);
    mainSplitPane.setBorder(new LineBorder(Color.GRAY));

    return mainSplitPane;
  }

  /**
   * Creates the project tree that is shown on the left side of the main window.
   *
   * @return The project tree panel that contains the project tree.
   */
  private JPanel createProjectTreePanel() {
    final JPanel projectTreePanel = new JPanel(new BorderLayout());
    projectTreePanel.setBorder(null);
    projectTreePanel.setBackground(Color.WHITE);

    m_projectTree.setBorder(new EmptyBorder(2, 4, 2, 2));
    m_projectTree.addTreeSelectionListener(new InternalTreeSelectionListener());

    final JScrollPane pane = new JScrollPane(m_projectTree);
    pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
    pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
    pane.setBorder(null);

    projectTreePanel.add(pane, BorderLayout.CENTER);

    return projectTreePanel;
  }

  /**
   * Changes the appearance of the main window whenever a new node is selected.
   *
   * @param node The selected node.
   */
  private void nodeSelected(final IProjectTreeNode node) {
    // Depending on the selected tree node, we get rid of
    // the old content of the right side and create a new
    // node-dependent right side.

    final Component component = node.getComponent();

    m_componentPanel.removeAll();

    if (component != null) {
      m_componentPanel.add(component);
    }

    m_componentPanel.updateUI();

    m_window.setJMenuBar(node.getMainMenu());

    m_window.getJMenuBar().updateUI();
  }

  /**
   * Selects the root node of the project tree.
   */
  public void init() {
    m_projectTree.setSelectionPath(new TreePath(m_projectTree.getRootNode()));
  }

  /**
   * Listener that updates the GUI when plugins are loaded.
   */
  private class InternalPluginListener implements IPluginInterfaceListener {
    @Override
    public void loadedPlugins() {
      final IProjectTreeNode node = (IProjectTreeNode) m_projectTree.getLastSelectedPathComponent();

      if (node != null) {
        m_window.setJMenuBar(node.getMainMenu());

        m_window.getJMenuBar().updateUI();
      }
    }
  }

  /**
   * This listener class is responsible for updating the right side of the main window whenever a
   * new node from the tree is selected.
   */
  private class InternalTreeSelectionListener implements TreeSelectionListener {
    @Override
    public void valueChanged(final TreeSelectionEvent event) {
      final DefaultMutableTreeNode node =
          (DefaultMutableTreeNode) m_projectTree.getLastSelectedPathComponent();

      if (node != null) {
        // A new node was selected

        nodeSelected((IProjectTreeNode) node);
      }
      // else: Suppress change during a Drag & Drop event
    }
  }
}


text:
package handlers

import (
	"bytes"
	"fmt"
	html "html/template"
	"net/http"
	"strings"
	"text/template"

	"github.com/andreaskoch/allmark/common/route"
	"github.com/andreaskoch/allmark/web/header"
	"github.com/andreaskoch/allmark/web/orchestrator"
	"github.com/andreaskoch/allmark/web/view/templates"
	"github.com/andreaskoch/allmark/web/view/viewmodel"
)

func Search(headerWriter header.HeaderWriter,
	navigationOrchestrator *orchestrator.NavigationOrchestrator,
	searchOrchestrator *orchestrator.SearchOrchestrator,
	templateProvider templates.Provider,
	error404Handler http.Handler) http.Handler {

	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

		// set headers
		headerWriter.Write(w, header.CONTENTTYPE_HTML)

		hostname := getBaseURLFromRequest(r)

		// get the query parameter
		query, _ := getQueryParameterFromURL(*r.URL)

		// read the page url-parameter
		page, pageParameterIsAvailable := getPageParameterFromURL(*r.URL)
		if !pageParameterIsAvailable || page == 0 {
			page = 1
		}

		// get the search template
		searchTemplate, err := templateProvider.GetSearchTemplate(hostname)
		if err != nil {
			fmt.Fprintf(w, "Template not found. Error: %s", err)
			return
		}

		// Page parameters
		pageType := "search"
		headline := getPageTitle(query)
		pageTitle := searchOrchestrator.GetPageTitle(headline)
		description := getDescription(query)

		// Page model
		pageModel := viewmodel.Model{}
		pageModel.Type = pageType
		pageModel.Title = headline
		pageModel.PageTitle = pageTitle
		pageModel.Description = description
		pageModel.ToplevelNavigation = navigationOrchestrator.GetToplevelNavigation()
		pageModel.BreadcrumbNavigation = navigationOrchestrator.GetBreadcrumbNavigation(route.New())

		// get the search results
		searchResultsModel := searchOrchestrator.GetSearchResults(query, page)

		// display error 404 non-existing page has been requested
		if searchResultsModel.ResultCount == 0 && page > 1 {
			error404Handler.ServeHTTP(w, r)
			return
		}

		// assemble the page model
		searchResultPage := viewmodel.Search{}
		searchResultPage.Model = pageModel
		searchResultPage.Results = searchResultsModel

		renderTemplate(searchTemplate, searchResultPage, w)
	})

}

func getPageTitle(query string) string {
	if strings.TrimSpace(query) == "" {
		return "Search"
	}

	return fmt.Sprintf("%s | Search", html.HTMLEscapeString(query))
}

func getDescription(query string) string {
	if strings.TrimSpace(query) == "" {
		return "Search this repository."
	}

	return fmt.Sprintf("Search results for %q.", html.HTMLEscapeString(query))
}

func renderSearchResultModel(templ *template.Template, searchModel viewmodel.Search) string {
	buffer := new(bytes.Buffer)
	renderTemplate(templ, searchModel, buffer)
	return buffer.String()
}


text:
@interface TKChartRangeColumnSeries : TKChartColumnSeries

@end


text:
"""
Tops Directory
"""


text:
author: Cloud Fundoo
comments: true
date: 2012-08-10 15:41:58+00:00
layout: post
slug: non-blocking-accept-and-connect
title: Non-blocking accept() and connect()
wordpress_id: 254
tags:
- Client
- Linux
- Non Blocking
- server
- sockets
---

I was trying to do accept() and listen() in a non-blocking way. Pseudo code is below.

**Non Blocking Accept()**

1. Check whether listening fd is ready for read, by using select()
2. Once ready issue accept(), this will return a new socket fd

**Non Blocking Connect()**

1. Issue connect on socket fd
2. If it is returning EINPROGRESS, check whether fd is ready for write using select()
3. If it is ready check socket state using getsockopt()
4. If no errors, then socket connection is established

TCP connection establishment is a three-way handshake, see below. Actually it is a 4-way process, but usually server will combine both SYN and ACK in a single packet, so three way handshake.

![3 way handshake"]({{ site.baseurl }}/assets/3-way-handshake.jpg "3 way handshake"){:class="img-responsive"}

Client initiates the connection request by sending the SYN, this is what happens when it calls connect(), then it waits for ACK+SYN from server, when client gets ACK+SYN packets, it sends ACK packet and moves the socket to ESTABLISHED state, see TCP state diagram below.

![TCP States]({{ site.baseurl }}/assets/tcp_states1.jpg "TCP States"){:class="img-responsive"}

Only point at which client has to wait is when it waits for ACK+SYN packet from server, this is indicated by EINPROGRESS return code from connect() call. When  fd returns from select(), indicating ready for write, it means either some error happended or ACK is send(3-way handshake done) by client in response to ACK+SYN packet from server, we can check for error using getsockopt() call, if no errors then client socket is in ESTABLISHED state, ready for send/receive packets. Client need not call another connect() to ACK the ACK+SYN packet from server, it will be done by the stack/kernel.

On the server side, I was on the impression that accept() is the one which is sending ACK+SYN packet to client, so accept() pseudo code may not work properly, it may not eliminate one delay (sending ACK+SYN and waiting for ACK from client)

![TCP Queues]({{ site.baseurl }}/assets/tcp-queues.jpg "TCP Queues"){:class="img-responsive"}

Actually accept() works in a different way, stack/kernel is the one doing the 3-way handshake and then new connection availability is notified to the application(server). TCP stack maintains two queues, one incomplete connection queue and one completed connection queue. Connection which are in SYN_RCVD state(i.e. send ACK+SYN packet in response to SYN from client) are in incomplete connection queue, connections which are in incomplete connection queue are moved to completed connection queue when it receives ACK from client in response to ACK+SYN. Accept() will be successful only if there is any connection in completed connection queue, select() will return ready for read only if there is any connection in completed connection queue.

So Accept() is not the one which does 3-way handshake, but it simply returns new socket fd, if there any connections in completed connection queue, so our pseudo code will work correctly.


text:
require 'puppet/provider/elastic_parsedfile'

Puppet::Type.type(:elasticsearch_user_file).provide(
  :oss_xpack,
  :parent => Puppet::Provider::ElasticParsedFile
) do
  desc 'Provider for OSS X-Pack users using plain files.'

  oss_xpack_config 'users'
  confine :exists => default_target

  has_feature :manages_encrypted_passwords

  text_line :comment,
            :match => /^\s*#/

  record_line :oss_xpack,
              :fields => %w[name hashed_password],
              :separator => ':',
              :joiner => ':'

  def self.valid_attr?(klass, attr_name)
    if klass.respond_to? :parameters
      klass.parameters.include?(attr_name)
    else
      true
    end
  end
end


text:
<!DOCTYPE html>

    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=0"
    />
    <meta name="description" content="ScrollIntoView" />
    <meta
      name="keywords"
      content="vivaxy,samples,github,demo,playground,test,ScrollIntoView,web-apis,scroll-into-view,sample,demos,web-api,native-api"
    />
    <meta name="author" content="vivaxy" />
    <link type="image/png" rel="shortcut icon" href="/vivaxy.icon.png" />
    <link type="text/css" rel="stylesheet" href="index.css" />
    <title>ScrollIntoView</title>


text:
var loaderUtils = require("loader-utils");
var process = require("./lib/process");

module.exports = function (source, sourcemap) {

  this.cacheable && this.cacheable();

  var globalOptions = this.options ? this.options.ng2htmlTemplate : {};
  var loaderOptions = loaderUtils.parseQuery(this.query);
  var opt = Object.assign({}, globalOptions, loaderOptions);

  var ret = process(source, opt, sourcemap);

  if (this.callback) {
    this.callback(null, ret.source, ret.sourcemap)
  } else {
    return ret.source;
  }

};


text:
A simple sitemap generator for PHP Framework.

## Installation

For the 5.4 and 5.5 version of Laravel Framework, use [version 3](https://github.com/andrey-helldar/sitemap/tree/3.x).

To get the latest version of Laravel Sitemap, simply require the project using [Composer](https://getcomposer.org):

```
composer require andrey-helldar/sitemap
```

Instead, you may of course manually update your require block and run `composer update` if you so choose:

```json
{
    "require": {
        "andrey-helldar/sitemap": "^5.0"
    }
}
```

If you don't use auto-discovery, add the `ServiceProvider` to the providers array in `config/app.php`:

```php
Helldar\Sitemap\ServiceProvider::class,
```

You can also publish the config file to change implementations (ie. interface to specific class):

```
php artisan vendor:publish --provider="Helldar\Sitemap\ServiceProvider"
```

Now you can use a `app('sitemap')` method.

## Upgrade Guides

* [Upgrading from 4.x to 5.x](guides/UPGRADE_4X_TO_5X.md)

## Configuration

To configure the generation, you need to fill the `models` array in the `config/sitemap.php` file:

```php
'models' => [
    \App\User::class => [
        'route' => 'route.name',
        'route_parameters' => [
            'slug' => 'table_field_for_slug',
            'foo'  => 'table_field_for_foo',
            bar'  => 'my_relation.slug',
            'baz',
        ],
        'lastmod' => 'updated_at',
        'frequency' => 'daily',
        'priority'  => 0.8,
    ],
]
```

As the key of the array, you must use the model name for which the rules will be defined.

 * **route** - the name of the route to generate the URL.
 * **route_parameters** - the parameters to be passed to the URL generation method, where:
    * the key is the parameter name for the routing. If the name of the routing parameter matches the name of the column in the database, you can specify only the value.
    * the value is the name of the column in the database to substitute the value. If the value needs to be taken from the link, then you should specify the appeal through a point. For example: `'bar' => 'my_relation.slug'`.
 * **lastmod** - is the name of the column containing the record date. In case of absence, the current date is used. If the model does not need to take into account the time field, set the parameter `lastmod` to `false`.
 * **frequency** - is the value of the refresh rate of the content. This is necessary for some search robots. You can also use constants from `Helldar\Sitemap\Services\Sitemap` class.
 * **priority** - is the priority of the reference for model records.

If any of the model values are undefined, a global value will be used.

## Using

### Manual

You can also transfer an array of items created manually:
```php
use Carbon\Carbon;
use Helldar\Sitemap\Helpers\Variables;
use Helldar\Sitemap\Services\Sitemap;

$items_a = [];
$items_b = [];

for ($i = 0; $i < 3; $i++) {
    $item = app('sitemap')->makeItem()
        ->changefreq('weekly')
        ->lastmod(Carbon::now())
        ->loc("http://mysite.local/page/" . $i);

    array_push($items_a, $item);
}

for ($i = 0; $i < 3; $i++) {
    $item = app('sitemap')->makeItem()
        ->changefreq(Variables::FREQUENCY_WEEKLY)
        ->lastmod(Carbon::now())
        ->loc("http://mysite.local/offers/" . $i);

    array_push($items_b, $item);
}

return app('sitemap')
         ->manual($items_a, $items_b)
         ->show();
```

Returned:
```xml
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    <url>
        <changefreq>weekly</changefreq>
        <lastmod>2018-03-06T12:30:17+03:00</lastmod>
        <loc>http://mysite.local/page/0</loc>
        <priority>0.5</priority>
    </url>
    <url>
        <changefreq>weekly</changefreq>
        <lastmod>2018-03-06T12:38:24+03:00</lastmod>
        <loc>http://mysite.local/page/1</loc>
        <priority>0.5</priority>
    </url>
    <url>
        <changefreq>weekly</changefreq>
        <lastmod>2018-03-06T12:30:17+03:00</lastmod>
        <loc>http://mysite.local/page/2</loc>
        <priority>0.5</priority>
    </url>
    <url>
        <changefreq>weekly</changefreq>
        <lastmod>2018-03-06T12:30:17+03:00</lastmod>
        <loc>http://mysite.local/offers/0</loc>
        <priority>0.5</priority>
    </url>
    <url>
        <changefreq>weekly</changefreq>
        <lastmod>2018-03-06T12:38:24+03:00</lastmod>
        <loc>http://mysite.local/offers/1</loc>
        <priority>0.5</priority>
    </url>
    <url>
        <changefreq>weekly</changefreq>
        <lastmod>2018-03-06T12:30:17+03:00</lastmod>
        <loc>http://mysite.local/offers/2</loc>
        <priority>0.5</priority>
    </url>
</urlset>
```

Also you can combine the data from the models builders with the transferred manually:
```php
$query1 = \App\Catalog::query()->where('id', '>', '1000');
$query2 = \App\News::query()->where('category_id', 10);
$query3 = \App\Pages::query();

return app('sitemap')
         ->builders($query1, $query2, $query3)
         ->manual($items1, $items2, $items3)
         ->show();
```

### Images

Your can also transfer an array of image items created manually:
```php
use Helldar\Sitemap\Services\Sitemap;

$items = [];

for ($i = 0; $i < 2; $i++) {
    $item = app('sitemap')->makeImages()
        ->loc("http://mysite.local/page/" . $i)
        ->image("http://mysite.local/images/1.jpg", "My Title 1-".$i, "Caption for image", "Limerick, Ireland", "Royalty free")
        ->image("http://mysite.local/images/2.jpg", "My Title 2-".$i)
        ->image("http://mysite.local/images/3.jpg");

    array_push($items, $item);
}

return app('sitemap')
         ->images($items)
         ->show();
```

Returned:
```xml
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" xmlns:image="http://www.google.com/schemas/sitemap-image/1.1">
    <url>
        <loc>http://mysite.local/page/0</loc>
        <image:image>
            <image:loc>http://mysite.local/images/1.jpg</image:loc>
            <image:title>My Title 1-0</image:title>
            <image:caption>Caption for image</image:caption>
            <image:geo_location>Limerick, Ireland</image:geo_location>
            <image:license>Royalty free</image:license>
        </image:image>
        <image:image>
            <image:loc>http://mysite.local/images/2.jpg</image:loc>
            <image:title>My Title 2-0</image:title>
        </image:image>
        <image:image>
            <image:loc>http://mysite.local/images/3.jpg</image:loc>
        </image:image>
    </url>
    <url>
        <loc>http://mysite.local/page/1</loc>
        <image:image>
            <image:loc>http://mysite.local/images/1.jpg</image:loc>
            <image:title>My Title 1-1</image:title>
            <image:caption>Caption for image</image:caption>
            <image:geo_location>Limerick, Ireland</image:geo_location>
            <image:license>Royalty free</image:license>
        </image:image>
        <image:image>
            <image:loc>http://mysite.local/images/2.jpg</image:loc>
            <image:title>My Title 2-1</image:title>
        </image:image>
        <image:image>
            <image:loc>http://mysite.local/images/3.jpg</image:loc>
        </image:image>
    </url>
</urlset>
```

Attention! Due to the different structure of documents, when trying to call method `show()`, an image map will be shown only if there are no calls to other methods.

Example:
```php
// Will show the image map.
return app('sitemap')
         ->images($items)
         ->show();

// Shows the map for `builders`. The image map will be ignored.
return app('sitemap')
         ->builders($query1, $query2, $query3)
         ->images($items)
         ->show();
```

The same principle applies when saving to one file - images will be ignored. But when saving to several files, the map will be successfully created.

### Show

To display the content on the screen, use the `show()` method:

```php
$query1 = \App\Catalog::query()->where('id', '>', '1000');
$query2 = \App\News::query()->where('category_id', 10);
$query3 = \App\Pages::query();

return app('sitemap')
         ->builders($query1, $query2, $query3)
         ->show();
```

To return the content of the page, add any route:
```php
app('route')->get('sitemap', function() {
    $query1 = \App\Catalog::query()->where('id', '>', '1000');
    $query2 = \App\News::query()->where('category_id', 10);
    $query3 = \App\Pages::query();

    return app('sitemap')
             ->builders($query1, $query2, $query3)
             ->show();
});
```

And go to your URL. Example: `http://mysite.dev/sitemap`.

### Save

#### If the option `separate_files` is DISABLED

To save the contents to the file, use the `save()` method:

```php
$query1 = \App\Catalog::query()->where('id', '>', '1000');
$query2 = \App\News::query()->where('category_id', 10);
$query3 = \App\Pages::query();

app('sitemap')
     ->builders($query1, $query2, $query3)
     ->save();
```

If you want to save multiple files, pass the path to the file as a parameter to the `save()` method:

```php
$query1 = \App\Catalog::query()->where('id', '>', '1000');
$query2 = \App\News::query()->where('category_id', 10);
$query3 = \App\Pages::query();

app('sitemap')
     ->builders($query1, $query2, $query3)
     ->save('sitemap-1.xml');

app('sitemap')
     ->builders($query1, $query2, $query3)
     ->save('foo/bar/sitemap-2.xml');
```

#### If the option `separate_files` is ENABLED

To save the contents to the separated files, use the `save()` method with `'separate_files' => true` parameter in [config/sitemap.php](src/config/sitemap.php) file.

```php
$query1 = \App\Catalog::query()->where('id', '>', '1000');
$query2 = \App\News::query()->where('category_id', 10);
$query3 = \App\Pages::query();

app('sitemap')
     ->builders($query1, $query2, $query3)
     ->save();
```

In this case, the name of the file will be the default name from the settings: `'filename' => 'sitemap.xml'`. The files are saved through the `Storage` facade (see [config/sitemap.php](src/config/sitemap.php)).

Each model builder will be processed and saved in a separate file, and the shared file will contain references to it (with the selected a `public` storage name):

```
/storage/sitemap.xml   // general file
/storage/sitemap-1.xml // generated file for the $query1 collection
/storage/sitemap-2.xml // generated file for the $query2 collection
/storage/sitemap-3.xml // generated file for the $query3 collection
```

```xml
<?xml version="1.0" encoding="utf-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <lastmod>2018-07-05T13:51:40+00:00</lastmod>
    <loc>http://example.com/storage/sitemap-1.xml</loc>
  </sitemap>
  <sitemap>
    <lastmod>2018-07-05T13:51:41+00:00</lastmod>
    <loc>http://example.com/storage/sitemap-2.xml</loc>
  </sitemap>
  <sitemap>
    <lastmod>2018-07-05T13:51:41+00:00</lastmod>
    <loc>http://example.com/storage/sitemap-3.xml</loc>
  </sitemap>
</sitemapindex>
```

If you use a multi-domain application, you can specify the domain names of the generated links to other files, having pre-specified them in the settings:

```php
'domains' => [
    'foo' => env('APP_URL'), // http://example.com
    'bar' => 'http://foo.bar',
],
```

```php
app('sitemap')
     ->builders($query1, $query2, $query3)
     ->domain('foo')
     ->save();

app('sitemap')
     ->builders($query1, $query2, $query3)
     ->domain('bar')
     ->save();
```

This method will create files with the following links:

```xml
<?xml version="1.0" encoding="utf-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <lastmod>2018-07-05T13:51:40+00:00</lastmod>
    <loc>http://example.com/storage/sitemap-1.xml</loc>
  </sitemap>
  <sitemap>
    <lastmod>2018-07-05T13:51:41+00:00</lastmod>
    <loc>http://example.com/storage/sitemap-2.xml</loc>
  </sitemap>
  <sitemap>
    <lastmod>2018-07-05T13:51:41+00:00</lastmod>
    <loc>http://example.com/storage/sitemap-3.xml</loc>
  </sitemap>
</sitemapindex>
```

and

```xml
<?xml version="1.0" encoding="utf-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <lastmod>2018-07-05T13:51:40+00:00</lastmod>
    <loc>http://foo.bar/storage/sitemap-1.xml</loc>
  </sitemap>
  <sitemap>
    <lastmod>2018-07-05T13:51:41+00:00</lastmod>
    <loc>http://foo.bar/storage/sitemap-2.xml</loc>
  </sitemap>
  <sitemap>
    <lastmod>2018-07-05T13:51:41+00:00</lastmod>
    <loc>http://foo.bar/storage/sitemap-3.xml</loc>
  </sitemap>
</sitemapindex>
```

By default, the domain specified in `APP_URL` of `.env` file will be used.

If you want to save multiple files, pass the path to the file as a parameter to the `save($path)` method with `'separate_files' => true` parameter in [config/sitemap.php](src/config/sitemap.php) file:

```php
$query1 = \App\Catalog::query()->where('id', '>', '1000');
$query2 = \App\News::query()->where('category_id', 10);
$query3 = \App\Pages::query();

$manual_items = [];

for ($i = 0; $i < 3; $i++) {
    $item = app('sitemap')->makeItem()
        ->changefreq('weekly')
        ->lastmod(Carbon\Carbon::now())
        ->loc("http://mysite.local/page/" . $i);

    array_push($manual_items, $item);
}

app('sitemap')
     ->builders($query1, $query2, $query3)
     ->manual($manual_items)
     ->save(public_path('first.xml'));

app('sitemap')
     ->builders($query1, $query2, $query3)
     ->manual($manual_items)
     ->save(storage_path('foo/bar/second.xml'));
```

Files will be created:
```
/storage/first.xml   // general file
/storage/first-1.xml // generated file for the $query1 collection
/storage/first-2.xml // generated file for the $query2 collection
/storage/first-3.xml // generated file for the $query3 collection
/storage/first-4.xml // generated file for the $manual_items collection

/storage/foo/bar/second.xml   // general file
/storage/foo/bar/second-1.xml // generated file for the $query1 collection
/storage/foo/bar/second-2.xml // generated file for the $query2 collection
/storage/foo/bar/second-3.xml // generated file for the $query3 collection
/storage/foo/bar/second-4.xml // generated file for the $manual_items collection
```

## SEO

Sitemap is extremely useful when indexing a site by search bots. If you use a sitemap splitting into several files, you only need to add a link to the main file in the `robots.txt` file.

For example, you created several files:
```text
/storage/sitemaps/promo.xml
/storage/sitemaps/promo-1.xml
/storage/sitemaps/promo-2.xml
/storage/sitemaps/promo-3.xml
```

In the `robots.txt` file, you only need to specify a link to the main file:
```text
Sitemap: http://example.com/storage/sitemaps/promo.xml
```

All the rest of the search bots will do for you.

Enjoy!

## License

This package is licensed under the [MIT License](LICENSE).


text:
package com.tvd12.ezyfox.codec;

public class EzySimpleMessageDataEncoder implements EzyMessageDataEncoder {

    private final EzyObjectToByteEncoder encoder;

    public EzySimpleMessageDataEncoder(EzyObjectToByteEncoder encoder) {
        this.encoder = encoder;
    }

    @Override
    public byte[] encode(Object data) throws Exception {
        return encoder.encode(data);
    }

    @Override
    public byte[] toMessageContent(Object data) throws Exception {
        return encoder.toMessageContent(data);
    }

    @Override
    public byte[] encryptMessageContent(
        byte[] messageContent, byte[] encryptionKey) throws Exception {
        return encoder.encryptMessageContent(messageContent, encryptionKey);
    }
}


text:
    <meta http-equiv="Content-Type" content="text/html;charset=UTF-8">
    <title>or-tools/src/graph/bellman_ford.cc File Reference - Doxy</title>
    <link rel="shortcut icon" href="../../../favicon.ico">

    <link href="../../../doxygen.css" rel="stylesheet" type="text/css">
    <link href="../../../tabs.css" rel="stylesheet" type="text/css">

          Generated on: Thu Mar 29 07:46:58 PDT 2012
            for custom file set

        <tt>//
            doxy/
            or-tools/
            src/
            graph/
            </tt>

Main Page

Related Pages

Namespaces

Classes

Files

or-tools/src/graph/bellman_ford.cc File Reference
#include <vector>

#include "base/callback.h"

#include "base/integral_types.h"

#include "base/scoped_ptr.h"

Go to the source code of this file.

Namespaces

namespace  	operations_research

Classes

class  	operations_research::BellmanFord

Functions

bool 	operations_research::BellmanFordShortestPath (int node_count, int start_node, int end_node, ResultCallback2< int64, int, int > *const graph, int64 disconnected_distance, std::vector< int > *nodes)

 	Bellman-Ford Shortest path with callback-based description of the graph.


text:
package org.snmp4j.transport;

import org.snmp4j.TransportStateReference;
import org.snmp4j.smi.Address;
import org.snmp4j.TransportMapping;
import java.nio.ByteBuffer;
// JavaDoc import
import org.snmp4j.MessageDispatcher;

/**
 * The TransportListener interface is implemented by objects
 * that process incoming messages from TransportMappings, for
 * example {@link MessageDispatcher}.
 *
 * @author Frank Fock
 * @version 2.0
 * @since 1.6
 */
public interface TransportListener {

  /**
   * Processes an incoming message.
   * @param sourceTransport
   *    a TransportMapping instance denoting the transport that
   *    received the message and that will be used to send any responses to
   *    this message. The sourceTransport has to support the
   *    incomingAddress's implementation class.
   * @param incomingAddress
   *    the Address from which the message has been received.
   * @param wholeMessage
   *    an ByteBuffer containing the received message.
   * @param tmStateReference
   *    the transport model state reference as defined by RFC 5590.
   * @since 1.6
   */
  void processMessage(TransportMapping sourceTransport,
                      Address incomingAddress,
                      ByteBuffer wholeMessage,
                      TransportStateReference tmStateReference);
}


text:
<?php

namespace mostertb\PHPSA2017Profiles\Profiles;

use mostertb\PHPSA2017Profiles\Abstracts\AbstractProfile;

class VauneenPietersenProfile extends AbstractProfile
{

// Implement the following methods:

// getName()
// getDescription()
// getGitHubUsername()
// getProfileImageURL() (optional)
// getMaintainedProjects() (optional)

    public function getName()
    {
        return 'Vauneen Pietersen';
    }

    public function getBiography()
    {
        return 'description: human';
    }

    public function getGitHubUsername()
    {
        return 'vauneen';
    }

    public function getProfileImageURL()
    {
        return 'http://graph.facebook.com/530448473/picture/';
    }

}


text:
//*********************************************************
//
// Copyright (c) Microsoft. All rights reserved.
// This code is licensed under the MIT License (MIT).
// THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
// IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
// PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
using Windows.Web.Http;

namespace SDKTemplate
{
    public sealed partial class Scenario03_GetList : Page
    {
        MainPage rootPage = MainPage.Current;

        private HttpClient httpClient;
        private CancellationTokenSource cts;

        public Scenario03_GetList()
        {
            this.InitializeComponent();
        }

        protected override void OnNavigatedTo(NavigationEventArgs e)
        {
            httpClient = Helpers.CreateHttpClientWithPlugIn();
            cts = new CancellationTokenSource();
        }

        protected override void OnNavigatedFrom(NavigationEventArgs e)
        {
            cts.Cancel();
            cts.Dispose();
            httpClient.Dispose();
        }

        private async void Start_Click(object sender, RoutedEventArgs e)
        {
            // The value of 'AddressField' is set by the user and is therefore untrusted input. If we can't create a
            // valid, absolute URI, we'll notify the user about the incorrect input.
            Uri resourceUri = Helpers.TryParseHttpUri(AddressField.Text);
            if (resourceUri == null)
            {
                rootPage.NotifyUser("Invalid URI.", NotifyType.ErrorMessage);
                return;
            }

            Helpers.ScenarioStarted(StartButton, CancelButton, OutputField);
            rootPage.NotifyUser("In progress", NotifyType.StatusMessage);

            // This sample uses a "try" in order to support TaskCanceledException.
            // If you don't need to support cancellation, then the "try" is not needed.
            try
            {
                HttpRequestResult result = await httpClient.TryGetAsync(resourceUri).AsTask(cts.Token);

                if (result.Succeeded)
                {
                    await Helpers.DisplayTextResultAsync(result.ResponseMessage, OutputField, cts.Token);
                    result.ResponseMessage.EnsureSuccessStatusCode();

                    XElement element = XElement.Parse(await result.ResponseMessage.Content.ReadAsStringAsync().AsTask(cts.Token));
                    OutputList.ItemsSource = (
                        from c in element.Elements("item")
                        select c.Attribute("name").Value);

                    rootPage.NotifyUser("Completed", NotifyType.StatusMessage);
                }
                else
                {
                    Helpers.DisplayWebError(rootPage, result.ExtendedError);
                }
            }
            catch (TaskCanceledException)
            {
                rootPage.NotifyUser("Request canceled.", NotifyType.ErrorMessage);
            }

            Helpers.ScenarioCompleted(StartButton, CancelButton);
        }

        private void Cancel_Click(object sender, RoutedEventArgs e)
        {
            cts.Cancel();
            cts.Dispose();

            // Re-create the CancellationTokenSource.
            cts = new CancellationTokenSource();
        }
    }
}


text:
<?xml version="1.0" encoding="utf-8"?>
<!-- $Revision: 339448 $ -->
 <sect1 xml:id="language.oop5.properties" xmlns="http://docbook.org/ns/docbook">
  <title>Properties</title>

  <para>
   Class member variables are called "properties". You may also see
   them referred to using other terms such as "attributes" or
   "fields", but for the purposes of this reference we will use
   "properties". They are defined by using one of the
   keywords <literal>public</literal>, <literal>protected</literal>,
   or <literal>private</literal>, followed by a normal variable
   declaration. This declaration may include an initialization, but
   this initialization must be a constant value--that is, it must be
   able to be evaluated at compile time and must not depend on
   run-time information in order to be evaluated.
  </para>
  <para>
   See <xref linkend="language.oop5.visibility" /> for more
   information on the meanings
   of <literal>public</literal>, <literal>protected</literal>,
   and <literal>private</literal>.
  </para>
  <note>
   <para>
    In order to maintain backward compatibility with PHP 4, PHP 5 will
    still accept the use of the keyword <literal>var</literal> in
    property declarations instead of (or in addition
    to) <literal>public</literal>, <literal>protected</literal>,
    or <literal>private</literal>. However, <literal>var</literal> is
    no longer required. In versions of PHP from 5.0 to 5.1.3, the use
    of <literal>var</literal> was considered deprecated and would
    issue an <constant>E_STRICT</constant> warning, but since PHP
    5.1.3 it is no longer deprecated and does not issue the warning.
   </para>
   <para>
    If you declare a property using <literal>var</literal> instead of
    one of <literal>public</literal>, <literal>protected</literal>,
    or <literal>private</literal>, then PHP 5 will treat the property
    as if it had been declared as <literal>public</literal>.
   </para>
  </note>
  <para>
   Within class methods non-static properties may be accessed by using
   <literal>-></literal> (Object Operator): <varname>$this->property</varname>
   (where <literal>property</literal> is the name of the property).
   Static properties are accessed by using the <literal>::</literal> (Double Colon):
   <varname>self::$property</varname>. See <link linkend="language.oop5.static">Static Keyword</link>
   for more information on the difference between static and non-static properties.
  </para>
  <para>
   The pseudo-variable <varname>$this</varname> is available inside
   any class method when that method is called from within an object
   context. <varname>$this</varname> is a reference to the calling
   object (usually the object to which the method belongs, but
   possibly another object, if the method is called
   <link linkend="language.oop5.static">statically</link> from the context
   of a secondary object).
  </para>

  <para>
   <example>
    <title>property declarations</title>
    <programlisting role="php">
<![CDATA[
<?php
class SimpleClass
{
   // valid as of PHP 5.6.0:
   public $var1 = 'hello ' . 'world';
   // valid as of PHP 5.3.0:
   public $var2 = <<<EOD
hello world
EOD;
   // valid as of PHP 5.6.0:
   public $var3 = 1+2;
   // invalid property declarations:
   public $var4 = self::myStaticMethod();
   public $var5 = $myVar;

   // valid property declarations:
   public $var6 = myConstant;
   public $var7 = array(true, false);

   // valid as of PHP 5.3.0:
   public $var8 = <<<'EOD'
hello world
EOD;
}
?>
]]>
    </programlisting>
   </example>
  </para>

  <note>
   <para>
    There are some nice functions to handle classes and objects. You
    might want to take a look at
    the <link linkend="ref.classobj">Class/Object Functions</link>.
   </para>
  </note>

  <para>
   As of PHP 5.3.0
   <link linkend="language.types.string.syntax.heredoc">heredocs</link> and
   <link linkend="language.types.string.syntax.nowdoc">nowdocs</link>
   can be used in any static data context, including property
   declarations.
   <example>
    <title>Example of using a nowdoc to initialize a property</title>
    <programlisting role="php">
<![CDATA[
<?php
class foo {
   // As of PHP 5.3.0
   public $bar = <<<'EOT'
bar
EOT;
   public $baz = <<<EOT
baz
EOT;
}
?>
]]>
    </programlisting>
   </example>
  </para>
  <note>
   <para>
    Nowdoc and Heredoc support was added in PHP 5.3.0.
   </para>
  </note>
 </sect1>

<!-- Keep this comment at the end of the file
Local variables:
mode: sgml
sgml-omittag:t
sgml-shorttag:t
sgml-minimize-attributes:nil
sgml-always-quote-attributes:t
sgml-indent-step:1
sgml-indent-data:t
indent-tabs-mode:nil
sgml-parent-document:nil
sgml-default-dtd-file:"~/.phpdoc/manual.ced"
sgml-exposed-tags:nil
sgml-local-catalogs:nil
sgml-local-ecat-files:nil
End:
vim600: syn=xml fen fdm=syntax fdl=2 si
vim: et tw=78 syn=sgml
vi: ts=1 sw=1
-->