text:
package gov.va.hmp.auth;

import gov.va.hmp.vista.rpc.RpcHost;
import gov.va.hmp.vista.rpc.RpcResponse;
import gov.va.hmp.vista.rpc.RpcTemplate;
import gov.va.hmp.vista.rpc.conn.SystemInfo;
import org.springframework.web.util.UriComponentsBuilder;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.URI;
import java.util.List;
import java.util.concurrent.ExecutionException;

/**
 * Simulates CPRS SSO via Tools menu url passing.
 */
public class CprsSsoTester extends JFrame {

    private RpcTemplate rpcTemplate;
    private JTextArea welcomeText;
    private JPasswordField accessCodeField;
    private JPasswordField verifyCodeField;
    private RpcHost rpcHost = new RpcHost("localhost", 29060);
    private JButton launchButton;
    private JLabel messageLabel;

    public CprsSsoTester() {
        super("CPRS SSO Test");
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        setContentPane(createContent());
        getRootPane().setDefaultButton(launchButton);

        rpcTemplate = new RpcTemplate();

        this.addWindowListener(new WindowAdapter() {
            @Override
            public void windowOpened(WindowEvent e) {
                new FetchIntroMessage().execute();

                accessCodeField.requestFocus();
            }

            @Override
            public void windowClosing(WindowEvent e) {
                try {
                    rpcTemplate.destroy();
                } catch (Exception e1) {
                    e1.printStackTrace();
                }
            }
        });
    }

    private Container createContent() {
        JPanel result = new JPanel();
        result.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        // Create the layout
        GroupLayout layout = new GroupLayout(result);
        result.setLayout(layout);
        layout.setAutoCreateGaps(true);

        // Create the components we will put in the form
        welcomeText = new JTextArea("Fetching intro text from " + rpcHost.toHostString(), 24, 80);
        welcomeText.setFont(Font.decode("Monospaced"));
        welcomeText.setEditable(false);
        JScrollPane welcomeScroller = new JScrollPane(welcomeText, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

        JLabel accessCodeLabel = new JLabel("Access Code");
        accessCodeField = new JPasswordField(20);
        JLabel verifyCodeLabel = new JLabel("Verify Code");
        verifyCodeField = new JPasswordField(20);
        launchButton = new JButton("Launch HMP");
        launchButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                new LaunchHMP().execute();
            }
        });
        messageLabel = new JLabel();

        // Horizontally, we want to align the labels and the text fields
        // along the left (TRAILING) edge
        layout.setHorizontalGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING)
                        .addComponent(accessCodeLabel)
                        .addComponent(verifyCodeLabel)
                )
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addComponent(welcomeScroller)
                        .addComponent(accessCodeField)
                        .addComponent(verifyCodeField)
                        .addGroup(layout.createSequentialGroup()
                                .addComponent(launchButton).addComponent(messageLabel))
                )
        );

        // Vertically, we want to align each label with his textfield
        // on the baseline of the components
        layout.setVerticalGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(welcomeScroller))
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(accessCodeLabel)
                        .addComponent(accessCodeField))
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(verifyCodeLabel)
                        .addComponent(verifyCodeField))
                .addGroup(layout.createParallelGroup(GroupLayout.Alignment.BASELINE)
                        .addComponent(launchButton)
                        .addComponent(messageLabel))
        );

        layout.linkSize(SwingConstants.HORIZONTAL, accessCodeLabel, verifyCodeLabel);

        return result;
    }

    public class FetchIntroMessage extends SwingWorker<String, String> {
        @Override
        protected String doInBackground() throws Exception {
            publish("Fetching intro text from " + rpcHost.toHostString());
            SystemInfo info = rpcTemplate.fetchSystemInfo(rpcHost);
            return info.getIntroText();
        }

        @Override
        protected void process(List<String> messages) {
            for (String message : messages) {
                messageLabel.setText(message);
            }
        }

        @Override
        protected void done() {
            if (!this.isCancelled()) {
                try {
                    welcomeText.setText(this.get());
                    messageLabel.setText(null);
                } catch (InterruptedException e) {
                    messageLabel.setText(e.getMessage());
                } catch (ExecutionException e) {
                    messageLabel.setText(e.getMessage());
                }
            }
        }
    }

    public class LaunchHMP extends SwingWorker<URI, String> {
        @Override
        protected URI doInBackground() throws Exception {
            launchButton.setEnabled(false);

            publish("Fetching App Handle");
            RpcResponse response = rpcTemplate.execute(rpcHost, null, String.valueOf(accessCodeField.getPassword()), String.valueOf(verifyCodeField.getPassword()), null, "XUS GET TOKEN");
            String appHandle = response.toString();

            publish("Building SSO URI");
            UriComponentsBuilder builder = UriComponentsBuilder.fromUriString("https://localhost:8443/j_cprs_sso_spring_security_check");
            builder.queryParam("S", rpcHost.getHostname());
            builder.queryParam("P", rpcHost.getPort());
            builder.queryParam("U", response.getDUZ());
            builder.queryParam("H", appHandle);

            URI uri = builder.build().toUri();
            publish("Launching HMP");
            Desktop.getDesktop().browse(uri);
            return uri;
        }

        @Override
        protected void process(List<String> messages) {
            for (String message : messages) {
                messageLabel.setText(message);
            }
        }

        @Override
        protected void done() {
            launchButton.setEnabled(true);
            if (!this.isCancelled()) {
                messageLabel.setText("Launched HMP");
            } else {
                messageLabel.setText("Cancelled Launch");
            }
        }
    }

    public static void main(String[] args) {
        CprsSsoTester dialog = new CprsSsoTester();
        dialog.pack();
        dialog.setVisible(true);
    }
}


text:
namespace lldb_private {

class OCamlASTContext : public TypeSystem {
public:
  class OCamlType;
  typedef std::map<ConstString, std::unique_ptr<OCamlType>> OCamlTypeMap;

  OCamlASTContext();
  ~OCamlASTContext() override;

  ConstString GetPluginName() override;

  uint32_t GetPluginVersion() override;

  static ConstString GetPluginNameStatic();

  static lldb::TypeSystemSP CreateInstance(lldb::LanguageType language,
                                           Module *module, Target *target);

  static void EnumerateSupportedLanguages(
      std::set<lldb::LanguageType> &languages_for_types,
      std::set<lldb::LanguageType> &languages_for_expressions);

  static void Initialize();

  static void Terminate();

  DWARFASTParser *GetDWARFParser() override;

  void SetAddressByteSize(int byte_size) { m_pointer_byte_size = byte_size; }

  static bool classof(const TypeSystem *ts) {
    return ts->getKind() == TypeSystem::eKindOCaml;
  }

  ConstString DeclGetName(void *opaque_decl) override { return ConstString(); }

  bool DeclContextIsStructUnionOrClass(void *opaque_decl_ctx) override {
    return false;
  }

  ConstString DeclContextGetName(void *opaque_decl_ctx) override {
    return ConstString();
  }

  ConstString DeclContextGetScopeQualifiedName(void *opaque_decl_ctx) override {
    return ConstString();
  }

  bool
  DeclContextIsClassMethod(void *opaque_decl_ctx,
                           lldb::LanguageType *language_ptr,
                           bool *is_instance_method_ptr,
                           ConstString *language_object_name_ptr) override {
    return false;
  }

  bool SupportsLanguage(lldb::LanguageType language) override;
  uint32_t GetPointerByteSize() override;

  bool IsArrayType(lldb::opaque_compiler_type_t type,
                   CompilerType *element_type, uint64_t *size,
                   bool *is_incomplete) override;

  bool IsAggregateType(lldb::opaque_compiler_type_t type) override;

  bool IsCharType(lldb::opaque_compiler_type_t type) override;

  bool IsCompleteType(lldb::opaque_compiler_type_t type) override;

  bool IsDefined(lldb::opaque_compiler_type_t type) override;

  bool IsFloatingPointType(lldb::opaque_compiler_type_t type, uint32_t &count,
                           bool &is_complex) override;

  bool IsFunctionType(lldb::opaque_compiler_type_t type,
                      bool *is_variadic_ptr = nullptr) override;

  size_t
  GetNumberOfFunctionArguments(lldb::opaque_compiler_type_t type) override;

  CompilerType GetFunctionArgumentAtIndex(lldb::opaque_compiler_type_t type,
                                          const size_t index) override;

  bool IsFunctionPointerType(lldb::opaque_compiler_type_t type) override;

  bool IsBlockPointerType(lldb::opaque_compiler_type_t type,
                          CompilerType *function_pointer_type_ptr) override;

  bool IsIntegerType(lldb::opaque_compiler_type_t type,
                     bool &is_signed) override;

  bool IsPossibleDynamicType(lldb::opaque_compiler_type_t type,
                             CompilerType *target_type, bool check_cplusplus,
                             bool check_objc) override;

  bool IsPointerType(lldb::opaque_compiler_type_t type,
                     CompilerType *pointee_type = nullptr) override;

  bool IsScalarType(lldb::opaque_compiler_type_t type) override;

  bool IsVoidType(lldb::opaque_compiler_type_t type) override;

  bool GetCompleteType(lldb::opaque_compiler_type_t type) override;

  ConstString GetTypeName(lldb::opaque_compiler_type_t type) override;

  uint32_t GetTypeInfo(
      lldb::opaque_compiler_type_t type,
      CompilerType *pointee_or_element_compiler_type = nullptr) override;

  lldb::LanguageType
  GetMinimumLanguage(lldb::opaque_compiler_type_t type) override;

  lldb::TypeClass GetTypeClass(lldb::opaque_compiler_type_t type) override;

  CompilerType GetArrayElementType(lldb::opaque_compiler_type_t type,
                                   uint64_t *stride = nullptr) override;

  CompilerType GetCanonicalType(lldb::opaque_compiler_type_t type) override;

  int GetFunctionArgumentCount(lldb::opaque_compiler_type_t type) override;

  CompilerType GetFunctionArgumentTypeAtIndex(lldb::opaque_compiler_type_t type,
                                              size_t idx) override;

  CompilerType
  GetFunctionReturnType(lldb::opaque_compiler_type_t type) override;

  size_t GetNumMemberFunctions(lldb::opaque_compiler_type_t type) override;

  TypeMemberFunctionImpl
  GetMemberFunctionAtIndex(lldb::opaque_compiler_type_t type,
                           size_t idx) override;

  CompilerType GetPointeeType(lldb::opaque_compiler_type_t type) override;

  CompilerType GetPointerType(lldb::opaque_compiler_type_t type) override;

  uint64_t GetBitSize(lldb::opaque_compiler_type_t type,
                      ExecutionContextScope *exe_scope) override;

  lldb::Encoding GetEncoding(lldb::opaque_compiler_type_t type,
                             uint64_t &count) override;

  lldb::Format GetFormat(lldb::opaque_compiler_type_t type) override;

  uint32_t GetNumChildren(lldb::opaque_compiler_type_t type,
                          bool omit_empty_base_classes) override;

  lldb::BasicType
  GetBasicTypeEnumeration(lldb::opaque_compiler_type_t type) override;

  CompilerType GetBuiltinTypeForEncodingAndBitSize(lldb::Encoding encoding,
                                                   size_t bit_size) override;

  uint32_t GetNumFields(lldb::opaque_compiler_type_t type) override;

  CompilerType GetFieldAtIndex(lldb::opaque_compiler_type_t type, size_t idx,
                               std::string &name, uint64_t *bit_offset_ptr,
                               uint32_t *bitfield_bit_size_ptr,
                               bool *is_bitfield_ptr) override;

  uint32_t GetNumDirectBaseClasses(lldb::opaque_compiler_type_t type) override {
    return 0;
  }

  uint32_t
  GetNumVirtualBaseClasses(lldb::opaque_compiler_type_t type) override {
    return 0;
  }

  CompilerType GetDirectBaseClassAtIndex(lldb::opaque_compiler_type_t type,
                                         size_t idx,
                                         uint32_t *bit_offset_ptr) override {
    return CompilerType();
  }

  CompilerType GetVirtualBaseClassAtIndex(lldb::opaque_compiler_type_t type,
                                          size_t idx,
                                          uint32_t *bit_offset_ptr) override {
    return CompilerType();
  }

  CompilerType GetChildCompilerTypeAtIndex(
      lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx, size_t idx,
      bool transparent_pointers, bool omit_empty_base_classes,
      bool ignore_array_bounds, std::string &child_name,
      uint32_t &child_byte_size, int32_t &child_byte_offset,
      uint32_t &child_bitfield_bit_size, uint32_t &child_bitfield_bit_offset,
      bool &child_is_base_class, bool &child_is_deref_of_parent,
      ValueObject *valobj, uint64_t &language_flags) override;

  uint32_t GetIndexOfChildWithName(lldb::opaque_compiler_type_t type,
                                   const char *name,
                                   bool omit_empty_base_classes) override;

  size_t
  GetIndexOfChildMemberWithName(lldb::opaque_compiler_type_t type,
                                const char *name, bool omit_empty_base_classes,
                                std::vector<uint32_t> &child_indexes) override;

  size_t GetNumTemplateArguments(lldb::opaque_compiler_type_t type) override {
    return 0;
  }

  void DumpValue(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
                 Stream *s, lldb::Format format, const DataExtractor &data,
                 lldb::offset_t data_offset, size_t data_byte_size,
                 uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
                 bool show_types, bool show_summary, bool verbose,
                 uint32_t depth) override;

  bool DumpTypeValue(lldb::opaque_compiler_type_t type, Stream *s,
                     lldb::Format format, const DataExtractor &data,
                     lldb::offset_t data_offset, size_t data_byte_size,
                     uint32_t bitfield_bit_size, uint32_t bitfield_bit_offset,
                     ExecutionContextScope *exe_scope) override;

  void DumpTypeDescription(lldb::opaque_compiler_type_t type) override;

  void DumpTypeDescription(lldb::opaque_compiler_type_t type,
                           Stream *s) override;

  bool IsRuntimeGeneratedType(lldb::opaque_compiler_type_t type) override;

  void DumpSummary(lldb::opaque_compiler_type_t type, ExecutionContext *exe_ctx,
                   Stream *s, const DataExtractor &data,
                   lldb::offset_t data_offset, size_t data_byte_size) override;

  size_t ConvertStringToFloatValue(lldb::opaque_compiler_type_t type,
                                   const char *s, uint8_t *dst,
                                   size_t dst_size) override;

  bool IsPointerOrReferenceType(lldb::opaque_compiler_type_t type,
                                CompilerType *pointee_type = nullptr) override;

  unsigned GetTypeQualifiers(lldb::opaque_compiler_type_t type) override;

  bool IsCStringType(lldb::opaque_compiler_type_t type,
                     uint32_t &length) override;

  size_t GetTypeBitAlign(lldb::opaque_compiler_type_t type) override;

  CompilerType GetBasicTypeFromAST(lldb::BasicType basic_type) override;

  bool IsBeingDefined(lldb::opaque_compiler_type_t type) override;

  bool IsConst(lldb::opaque_compiler_type_t type) override;

  uint32_t IsHomogeneousAggregate(lldb::opaque_compiler_type_t type,
                                  CompilerType *base_type_ptr) override;

  bool IsPolymorphicClass(lldb::opaque_compiler_type_t type) override;

  bool IsTypedefType(lldb::opaque_compiler_type_t type) override;

  CompilerType GetTypedefedType(lldb::opaque_compiler_type_t type) override;

  bool IsVectorType(lldb::opaque_compiler_type_t type,
                    CompilerType *element_type, uint64_t *size) override;

  CompilerType
  GetFullyUnqualifiedType(lldb::opaque_compiler_type_t type) override;

  CompilerType GetNonReferenceType(lldb::opaque_compiler_type_t type) override;

  bool IsReferenceType(lldb::opaque_compiler_type_t type,
                       CompilerType *pointee_type = nullptr,
                       bool *is_rvalue = nullptr) override;

  CompilerType CreateBaseType(const ConstString &name, uint64_t);

private:
  int m_pointer_byte_size;
  std::unique_ptr<DWARFASTParser> m_dwarf_ast_parser_ap;
  OCamlTypeMap m_base_type_map;

  OCamlASTContext(const OCamlASTContext &) = delete;
  const OCamlASTContext &operator=(const OCamlASTContext &) = delete;
};

class OCamlASTContextForExpr : public OCamlASTContext {
public:
  OCamlASTContextForExpr(lldb::TargetSP target) : m_target_wp(target) {}

private:
  lldb::TargetWP m_target_wp;
};
}
#endif // liblldb_OCamlASTContext_h_

redpajama_set_name: RedPajamaGithub


text:
package com.wbillingsley.handy.appbase;

trait PasswordLoginT {

  val pwhash: Option[String]

  val username: Option[String]

  val email: Option[String]

}

case class PasswordLogin (

 pwhash: Option[String] = None,

 username: Option[String] = None,

 email:Option[String] = None

) extends PasswordLoginT


text:
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { withStyles } from 'material-ui/styles';
import classNames from 'classnames';
import IconButton from 'material-ui/IconButton';
import Menu, { MenuItem } from 'material-ui/Menu';
import Typography from 'material-ui/Typography';
import ExpandMoreIcon from 'material-ui-icons/ExpandMore';
import { browserHistory as history, withRouter } from 'react-router';
import GridRow from '../../common/grid/gridRow';
import { sessionChange, sessionInitializing } from '../../../reducers/session';

const styleSheet = theme => ({
  expand: {
    transform: 'rotate(0deg)',
    transition: theme.transitions.create('transform', {
      duration: theme.transitions.duration.shortest,
    }),
  },
  expandOpen: {
    transform: 'rotate(180deg)',
  },
  icon: {
    color: theme.palette.secondary[500],
  },
});

class AgencySwitch extends Component {
  constructor() {
    super();
    this.state = {
      anchorEl: null,
      open: false,
    };
    this.handleClick = this.handleClick.bind(this);
    this.handleRequestClose = this.handleRequestClose.bind(this);
  }

  handleClick(event) {
    this.setState({ open: true, anchorEl: event.currentTarget });
  }

  handleRequestClose(office) {
    const { startRefresh, stopRefresh } = this.props;

    if (office.id) {
      this.props.saveNewCurrentOffice({
        officeId: office.office.id,
        officeName: office.office.name,
        officeRole: office.role_display,
        permissions: office.permissions,
        officeCountryCode: office.office.country,
      });

      this.setState({ open: false });
      const loc = history.getCurrentLocation();
      startRefresh();
      history.push('/');
      setTimeout(() => {
        history.push(loc);
        stopRefresh();
      }, 100);
    }

    this.setState({ open: false });
  }

  renderMenuItems(offices = []) {
    return offices.map(office => (
      <MenuItem
        key={office.office.id}
        onClick={() => this.handleRequestClose(office)}
        selected={office.office.id === this.props.officeId}
      >
        <Typography type="body2">
          {office.office.name}
        </Typography>
      </MenuItem>
    ));
  }

  render() {
    const { classes, offices, name, agencyName } = this.props;
    return (
      <div>
        <GridRow alignItems="center">
          <Typography type="body2">
            {name}
          </Typography>
          <IconButton
            className={classNames(classes.icon, classes.expand, {
              [classes.expandOpen]: this.state.open,
            })}
            onClick={this.handleClick}
            aria-haspopup="true"
            aria-label="switch-office"
          >
            <ExpandMoreIcon />
          </IconButton>
        </GridRow>
        <Menu
          id="switch-office"
          anchorEl={this.state.anchorEl}
          open={this.state.open}
          onClose={this.handleRequestClose}

        >
          {this.renderMenuItems(offices)}
        </Menu>
      </div>
    );
  }
}

AgencySwitch.propTypes = {
  classes: PropTypes.object.isRequired,
  offices: PropTypes.array,
  agencyName: PropTypes.string,
  name: PropTypes.string,
  saveNewCurrentOffice: PropTypes.func,
  officeId: PropTypes.number,
  stopRefresh: PropTypes.func,
  startRefresh: PropTypes.func,
};

const mapStateToProps = state => ({
  name: state.session.officeName,
  agencyName: state.session.agencyName,
  offices: state.session.offices,
  countries: state.countries,
  officeId: state.session.officeId,
});

const mapDispatchToProps = dispatch => ({
  saveNewCurrentOffice: session => dispatch(sessionChange(session)),
  startRefresh: () => dispatch(sessionInitializing()),
  stopRefresh: () => dispatch(sessionChange()),
});

export default connect(
  mapStateToProps,
  mapDispatchToProps,
)(withStyles(styleSheet, { name: 'AgencySwitch' })(AgencySwitch));


text:
Kinabogen
=========

Website for links and stuff to remember

Links
-----

http://json-schema.org/latest/json-schema-hypermedia.html
http://restcookbook.com/Mediatypes/json/


text:
module.exports = {
    getLocal: function(){
        return localStorage.getItem('lang') || 'en-us';
    },
    setLocal: function(lang){
        localStorage.setItem('lang', lang);
    }
};


text:
//
// Mesh.cpp - Meshes for vtlib-OSG
//
// Copyright (c) 2001-2011 Virtual Terrain Project
// Free for all uses, see license.txt for details.
//

#include "vtlib/vtlib.h"
#include "vtdata/vtLog.h"

#include <osg/LineWidth>

/////////////////////////////////////////////////////////////////////////////
// vtMesh
//

static FPoint3 c[8] =
{
	FPoint3(-1.0, -1.0, 1.0),	/* 0 */
	FPoint3(-1.0, 1.0, 1.0),	/* 1 */
	FPoint3(1.0, 1.0, 1.0),		/* 2 */
	FPoint3(1.0, -1.0, 1.0),	/* 3 */
	FPoint3(-1.0, -1.0, -1.0),	/* 4 */
	FPoint3(-1.0, 1.0, -1.0),	/* 5 */
	FPoint3(1.0, 1.0, -1.0),	/* 6 */
	FPoint3(1.0, -1.0, -1.0),	/* 7 */
};

static FPoint3 c2[8] =
{
	FPoint3(-0.5, 0, 0.5)	,	/* 0 */
	FPoint3(-0.5, 1.0, 0.5),	/* 1 */
	FPoint3(0.5, 1.0, 0.5),		/* 2 */
	FPoint3(0.5, 0, 0.5),		/* 3 */
	FPoint3(-0.5, 0, -0.5),		/* 4 */
	FPoint3(-0.5, 1.0, -0.5),	/* 5 */
	FPoint3(0.5, 1.0, -0.5),	/* 6 */
	FPoint3(0.5, 0, -0.5),		/* 7 */
};

static FPoint3 n[6] =
{
	FPoint3( 0.0, 0.0, 1.0 ),
	FPoint3( -1.0, 0.0, 0.0 ),
	FPoint3( 0.0, 0.0, -1.0 ),
	FPoint3( 1.0, 0.0, 0.0 ),
	FPoint3( 0.0, -1.0, 0.0 ),
	FPoint3( 0.0, 1.0, 0.0 )
};

static int v_list[6][4] = {
	7, 4, 5, 6,		 /* back */
	3, 7, 6, 2,		 /* right */
	0, 3, 2, 1,		 /* front */
	4, 0, 1, 5,		 /* left */
	6, 5, 1, 2,		 /* top */
	4, 7, 3, 0,		 /* bottom */
};

static FPoint2 t[4] =
{
	FPoint2(0.0, 1.0),
	FPoint2(1.0, 1.0),
	FPoint2(1.0, 0.0),
	FPoint2(0.0, 0.0)
};

/**
 * Construct a Mesh.
 * A Mesh is a container for a set of vertices and primitives.
 *
 * \param ePrimType The type of primitive this mesh will contain.  Allowed
 *		values are:
 *		- osg::PrimitiveSet::POINTS
 *		- osg::PrimitiveSet::LINES
 *		- osg::PrimitiveSet::LINE_STRIP
 *		- osg::PrimitiveSet::TRIANGLES
 *		- osg::PrimitiveSet::TRIANGLE_STRIP
 *		- osg::PrimitiveSet::TRIANGLE_FAN
 *		- osg::PrimitiveSet::QUADS
 *		- osg::PrimitiveSet::POLYGON
 *
 * \param VertType Flags which indicate what type of information is stored
 *		with each vertex.  This can be any combination of the following bit
 *		flags:
 *		- VT_Normals - a normal per vertex.
 *		- VT_Colors - a color per vertex.
 *		- VT_TexCoords - a texture coordinate (UV) per vertex.
 *
 * \param NumVertices The expected number of vertices that the mesh will
 *		contain.  If more than this number of vertices are added, the mesh
 *		will automatically grow to contain them.  However it is more
 *		efficient if you know the number at creation time and pass it in
 *		this parameter.
 */
vtMesh::vtMesh(PrimType ePrimType, int VertType, int NumVertices)
{
#ifdef VTP_AVOID_OSG_INDICES
	m_PrimType = ePrimType;
#endif
	m_iMatIdx = -1;

	osg::Vec3Array *pVert = new osg::Vec3Array;
	pVert->reserve(NumVertices);
	setVertexArray(pVert);

#ifndef VTP_AVOID_OSG_INDICES
	osg::UIntArray *pIndex = new osg::UIntArray;
	pIndex->reserve(NumVertices);
	setVertexIndices(pIndex);
#endif

	if (VertType & VT_Normals)
	{
		osg::Vec3Array *pNorm = new osg::Vec3Array;
		pNorm->reserve(NumVertices);
		setNormalArray(pNorm);
#ifndef VTP_AVOID_OSG_INDICES
		setNormalIndices(pIndex);
#endif
		setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
	}
	if (VertType & VT_Colors)
	{
		osg::Vec4Array *pColor = new osg::Vec4Array;
		pColor->reserve(NumVertices);
		setColorArray(pColor);
#ifndef VTP_AVOID_OSG_INDICES
		setColorIndices(pIndex);
#endif
		setColorBinding(osg::Geometry::BIND_PER_VERTEX);
	}
	if (VertType & VT_TexCoords)
	{
		osg::Vec2Array *pTex = new osg::Vec2Array;
		pTex->reserve(NumVertices);
		setTexCoordArray(0, pTex);
#ifndef VTP_AVOID_OSG_INDICES
		setTexCoordIndices(0, pIndex);
#endif
	}

#ifdef USE_OPENGL_BUFFER_OBJECTS
	// This can only be done after the arrays have been set up
	// The buffer objects will be compiled on the next rendering pass
	// So if you change the contents of the vertex, normal, colour, or tex coord arrys
	// after the next rendering pass you need to call the DirtyBufferObjects() function
	// to cause them to recompile.
	// Element Index buffer objects are handled slightly differently by OSG but the
	// same constraint applies if you change any element indices. This occurs when
	// you add geometry definitions to the mesh e.g by calling AddTriangle etc.
	if (VertType & VT_VBO)
		setUseVertexBufferObjects(true);
#endif

	osg::PrimitiveSet *pPrimSet;
#ifndef VTP_AVOID_OSG_INDICES
	switch (ePrimType)
	{
	case osg::PrimitiveSet::POINTS:
		pPrimSet = new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, NumVertices);
		break;
	case osg::PrimitiveSet::LINES:
		pPrimSet = new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, NumVertices);
		break;
	case osg::PrimitiveSet::TRIANGLES:
		pPrimSet = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES, 0, NumVertices);
		break;
	case osg::PrimitiveSet::QUADS:
		pPrimSet = new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, NumVertices);
		break;
	case osg::PrimitiveSet::LINE_STRIP:
		pPrimSet = new osg::DrawArrayLengths(osg::PrimitiveSet::LINE_STRIP);
		break;
	case osg::PrimitiveSet::TRIANGLE_STRIP:
		pPrimSet = new osg::DrawArrayLengths(osg::PrimitiveSet::TRIANGLE_STRIP);
		break;
	case osg::PrimitiveSet::TRIANGLE_FAN:
		pPrimSet = new osg::DrawArrayLengths(osg::PrimitiveSet::TRIANGLE_FAN);
		break;
	case osg::PrimitiveSet::POLYGON:
		pPrimSet = new osg::DrawArrayLengths(osg::PrimitiveSet::POLYGON);
		break;
	default:	// Keep picky compilers quiet.
		break;
	}
	addPrimitiveSet(pPrimSet);
#else
	pPrimSet = NULL;
	switch (ePrimType)
	{
	case osg::PrimitiveSet::POINTS:
		pPrimSet = new osg::DrawArrays(osg::PrimitiveSet::POINTS, 0, NumVertices);
		break;
	case osg::PrimitiveSet::LINES:
		pPrimSet = new osg::DrawElementsUShort(osg::PrimitiveSet::LINES);
		break;
	case osg::PrimitiveSet::TRIANGLES:
		pPrimSet = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES);
		break;
	case osg::PrimitiveSet::QUADS:
		pPrimSet = new osg::DrawElementsUShort(osg::PrimitiveSet::QUADS);
		break;
	default:	// Keep picky compilers quiet.
		break;
	}
	if (NULL != pPrimSet)
		addPrimitiveSet(pPrimSet);
#endif
}

/**
 * Adds a vertex to the mesh.
 *
 * \return The index of the vertex that was added.
 */
int vtMesh::AddVertex(float x, float y, float z)
{
	int i = NumVertices();
	SetVtxPos(i, FPoint3(x, y, z));
	return i;
}

/**
 * Adds a vertex to the mesh, with a vertex normal.
 *
 * \return The index of the vertex that was added.
 */
int vtMesh::AddVertexN(float x, float y, float z, float nx, float ny, float nz)
{
	int i = NumVertices();
	SetVtxPos(i, FPoint3(x, y, z));
	SetVtxNormal(i, FPoint3(nx, ny, nz));
	return i;
}

/**
 * Adds a vertex to the mesh, with UV coordinates.
 *
 * \return The index of the vertex that was added.
 */
int vtMesh::AddVertexUV(float x, float y, float z, float u, float v)
{
	int i = NumVertices();
	SetVtxPos(i, FPoint3(x, y, z));
	SetVtxTexCoord(i, FPoint2(u, v));
	return i;
}

/**
 * Adds a vertex to the mesh.
 *
 * \return The index of the vertex that was added.
 */
int vtMesh::AddVertex(const FPoint3 &p)
{
	int i = NumVertices();
	SetVtxPos(i, p);
	return i;
}

/**
 * Adds a vertex to the mesh, with a vertex normal.
 *
 * \return The index of the vertex that was added.
 */
int vtMesh::AddVertexN(const FPoint3 &p, const FPoint3 &n)
{
	int i = NumVertices();
	SetVtxPos(i, p);
	SetVtxNormal(i, n);
	return i;
}

/**
 * Adds a vertex to the mesh, with UV coordinates.
 *
 * \return The index of the vertex that was added.
 */
int vtMesh::AddVertexUV(const FPoint3 &p, float u, float v)
{
	int i = NumVertices();
	SetVtxPos(i, p);
	SetVtxTexCoord(i, FPoint2(u, v));
	return i;
}

/**
 * Adds a vertex to the mesh, with UV coordinates.
 *
 * \return The index of the vertex that was added.
 */
int vtMesh::AddVertexUV(const FPoint3 &p, const FPoint2 &uv)
{
	int i = NumVertices();
	SetVtxPos(i, p);
	SetVtxTexCoord(i, uv);
	return i;
}

/**
 * Adds a vertex to the mesh, with a vertex normal and UV coordinates.
 *
 * \return The index of the vertex that was added.
 */
int vtMesh::AddVertexNUV(const FPoint3 &p, const FPoint3 &n, const FPoint2 &uv)
{
	int i = NumVertices();
	SetVtxPos(i, p);
	SetVtxNormal(i, n);
	SetVtxTexCoord(i, uv);
	return i;
}

/**
 * Adds an indexed strip to the mesh, with the assumption that the indices
 * are in linear order.
 *
 * \param iNVerts The number of vertices in the strip.
 * \param iStartIndex The index that starts the linear sequence.
 */
void vtMesh::AddStrip2(int iNVerts, int iStartIndex)
{
	unsigned short *idx = new unsigned short[iNVerts];

	for (int i = 0; i < iNVerts; i++)
		idx[i] = iStartIndex + i;

	AddStrip(iNVerts, idx);
	delete [] idx;
}

/**
 * Add a block (rectangular 3d box) to this mesh.  The width, height and
 * depth are specified with the 'size' parameter.
 */
void vtMesh::CreateBlock(const FPoint3& size)
{
	int i, j;
	FPoint3 vtx[8];			/* individual vertex values */

	for (i = 0; i < 8; i++)
	{
		vtx[i].x = size.x * c[i].x;
		vtx[i].y = size.y * c[i].y;
		vtx[i].z = size.z * c[i].z;
	}

	int vidx = 0;
	for (i = 0; i < 6; i++)
	{
		int start = vidx;
		for (j = 0; j < 4; j++)
		{
			AddVertex(vtx[v_list[i][j]]);
			if (hasVertexNormals())		/* compute normals */
				SetVtxNormal(vidx, -n[i]);
			if (hasVertexTexCoords())	/* compute tex coords */
				SetVtxTexCoord(vidx, t[j]);
			vidx++;
		}
		AddFan(start, start+1, start+2, start+3);
	}
}

/**
 *	Adds a 3D block to a vtMesh as a series of 5 triangle fan primitives.
 *  The bottom face is omitted, the base is placed at y=0, and texture
 *  coordinates are provided such that texture bitmaps appear right-side-up
 *  on the side faces.
 */
void vtMesh::CreateOptimizedBlock(const FPoint3& size)
{
	int i, j;
	FPoint3 vtx[8];			/* individual vertex values */
	FPoint3 half = size / 2.0f;

	for (i = 0; i < 8; i++)
	{
		vtx[i].x = half.x * c[i].x;
		vtx[i].y = half.y * c[i].y + (half.y);
		vtx[i].z = half.z * c[i].z;
	}

	int vidx = 0;
	for (i = 0; i < 5; i++)
	{
		int start = vidx;
		for (j = 0; j < 4; j++)
		{
			AddVertex(vtx[v_list[i][j]]);
			if (hasVertexNormals())		/* compute normals */
				SetVtxNormal(vidx, -n[i]);
			if (hasVertexTexCoords())	/* compute tex coords */
				SetVtxTexCoord(vidx, t[j]);
			vidx++;
		}
		AddFan(start, start+1, start+2, start+3);
	}
}

/**
 * Adds a 3D block (extruded rectangle) to a vtMesh as a series of 5 triangle
 * fan primitives.  The bottom face is omitted, the base is placed at /base/,
 * the extrusion is along /vector_up/.  Texture coordinates are provided such
 * that texture bitmaps appear right-side-up on the side faces.
 */
void vtMesh::CreatePrism(const FPoint3 &base, const FPoint3 &vector_up,
							 const FPoint2 &size1, const FPoint2 &size2)
{
	int i, j;
	FPoint3 vtx[8];		/* individual vertex values */

	for (i = 0; i < 8; i++)
	{
		vtx[i].y = base.y + c2[i].y * (vector_up.y);
		if (c2[i].y == 0)	// bottom
		{
			vtx[i].x = base.x + size1.x * c2[i].x;
			vtx[i].z = base.z + size1.y * c2[i].z;
		}
		else
		{
			vtx[i].x = base.x + vector_up.x + size2.x * c2[i].x;
			vtx[i].z = base.z + vector_up.z + size2.y * c2[i].z;
		}
	}

	int vidx = NumVertices();
	for (i = 0; i < 5; i++)
	{
		int start = vidx;
		for (j = 0; j < 4; j++)
		{
			AddVertex(vtx[v_list[i][j]]);
			if (hasVertexNormals())		/* compute normals */
				SetVtxNormal(vidx, -n[i]);
			if (hasVertexTexCoords())	/* compute tex coords */
				SetVtxTexCoord(vidx, t[j]);
			vidx++;
		}
		AddFan(start, start+1, start+2, start+3);
	}
}

/**
 * Adds triangle/quad strips to this mesh, suitable for a (topologically)
 * rectangular grid.
 *
 * \param xsize Number of vertices in the first dimension.
 * \param ysize Number of vertices in the second dimension.
 * \param bReverseNormals Reverse the vertex order so the normals point the other way.
 */
void vtMesh::CreateRectangularMesh(int xsize, int ysize, bool bReverseNormals)
{
	int i, j;

	unsigned short *strip = new unsigned short[xsize*2];
	for (j = 0; j < ysize - 1; j++)
	{
		int start = j * xsize;
		int len = 0;
		for (i = 0; i < xsize; i++)
		{
			if (bReverseNormals)
			{
				// reverse the vertex order so the normals point the other way
				strip[len++] = start + i + xsize;
				strip[len++] = start + i;
			}
			else
			{
				strip[len++] = start + i;
				strip[len++] = start + i + xsize;
			}
		}
		AddStrip(xsize*2, strip);
	}
	delete [] strip;
}

/**
 * Adds geometry for an ellipsoid to this mesh.
 *
 * The geometry is created with efficient triangle strips.  If the mesh
 * has vertex normals, outward-pointing normals are created for lighting.
 * If the mesh has vertex coordinates, then UVs are set as follows:
 * U ranges from 0 to 1 around the circumference, and V ranges from 0
 * to 1 from the top to the bottom.  For a hemisphere, V ranges from
 * 0 at the top to 1 at the base.
 *
 * \param center Position of the center, pass FPoint3(0,0,0) to center on the origin.
 * \param size The width, height and depth of the ellipsoid.
 * \param res The resolution (number of quads used in the tesselation)
 *		from top to bottom (north pole to south pole).
 * \param hemi Create only the top of the ellipsoid (e.g. a hemisphere).
 * \param bNormalsIn Use a vertex order in the mesh so that the normals point
 *		in, instead of out.  This is useful for, example, a backface-culled
 *		sphere that you want to see from the inside, instead of the outside.
 */
void vtMesh::CreateEllipsoid(const FPoint3 &center, const FPoint3 &size,
								 int res, bool hemi, bool bNormalsIn)
{
	int		i, j;
	int		vidx;
	FPoint3 v;
	float	theta_step, phi_step;
	int		theta_res, phi_res;
	float	phi_range;

	if (hemi)
	{
		phi_res = res/2;
		phi_range = PID2f;
	}
	else
	{
		phi_res = res;
		phi_range = PIf;
	}
	theta_res = res * 2;

	theta_step = PI2f / theta_res;
	phi_step = phi_range / phi_res;
	for (j = 0; j <= phi_res; j++)
	{
		float phi = j * phi_step;

		for (i = 0; i <= theta_res; i++)
		{
			float theta = i * theta_step;
			v.x = sinf(theta) * sinf(phi);
			v.y = cosf(phi);
			v.z = cosf(theta) * sinf(phi);

			FPoint3 p(size.x * v.x, size.y * v.y, size.z * v.z);
			vidx = AddVertex(center + p);
			if (hasVertexNormals())		/* compute normals */
				SetVtxNormal(vidx, v);
			if (hasVertexTexCoords())	/* compute tex coords */
			{
				FPoint2 t((float)i / theta_res, 1.0f - (float)j / phi_res);
				SetVtxTexCoord(vidx, t);
			}
		}
	}
	CreateRectangularMesh(theta_res+1, phi_res+1, bNormalsIn);
}

/**
 * Adds an cylinder to this mesh.
 *
 * \param height The height of the cylinder.
 * \param radius The radius of the cylinder.
 * \param res The resolution (number of side of the cylinder).
 * \param bTop True to create the top of the cylinder.
 * \param bBottom True to create the bottom of the cylinder.  You could set
 *		this to false, for example, if the cylinder is going to sit on a
 *		flat surface where you will never see its bottom.
 * \param bCentered True to create a cylinder centered around its origin,
 *		false for a cylinder with its base at the origin that extends outward.
 * \param direction An orientation, 0-2 corresponds to X, Y, Z.  Default is 1 (Y).
 */
void vtMesh::CreateCylinder(float height, float radius, int res,
								bool bTop, bool bBottom, bool bCentered, int direction)
{
	// One way to model a cylinder is as a triangle/quad strip and
	// a pair of triangle fans for the top and bottom, although that
	// requires 2 kinds of primitive, so we would need 2 vtMesh objects.
	// Instead, we use triangle strips for both the sides and top/bottom.

	// In order to do vertex-based shading, we will have to provide correct
	// vertex normals for the sides and top/bottom separately.  Unfortunately
	// this doubles the number of vertices, since each vertex can only
	// have a single normal.  So we may have to make 2 passes through vertex
	// construction.

	int		a, b, passes;
	int		i, j, k;
	int		vidx;
	FPoint3 p, norm;

	float	theta_step = PI2f / res;
	int		verts_per_pass = res * 2;

	if ((bTop || bBottom) && (hasVertexNormals()))
		passes = 2;
	else
		passes = 1;

	for (a = 0; a < passes; a++)
	{
		for (b = 0; b < 2; b++)
		{
			if (bCentered)
				p.y = b ? height/2 : -height/2;
			else
				p.y = b ? height : 0;

			for (i = 0; i < res; i++)
			{
				float theta = i * theta_step;
				p.x = cosf(theta) * radius;
				p.z = sinf(theta) * radius;
				vidx = AddVertex(p);

				if (hasVertexNormals())	/* compute normals */
				{
					if (a == 0)		// first pass, outward normals for sides
					{
						norm.x = cosf(theta);
						norm.y = 0;
						norm.z = sinf(theta);
					}
					else if (a == 1)	// second pass, top/bottom normals
					{
						norm.x = 0;
						norm.y = b ? 1.0f : -1.0f;
						norm.z = 0;
					}
					SetVtxNormal(vidx, norm);
				}
			}
		}
	}
	// Create sides
	unsigned short *indices = new unsigned short[(res+1) * 2];
	j = 0;
	k = 0;
	for (i = 0; i < res+1; i++)
	{
		indices[j++] = k;
		indices[j++] = k+res;
		k++;
		if (k == res)
			k = 0;
	}
	AddStrip(j, indices);

	// create top and bottom
	int offset = (passes == 2 ? verts_per_pass : 0);
	if (bBottom)
	{
		j = 0;
		for (i = 0; i < res/2; i++)
		{
			indices[j++] = offset + i;
			k = res - 1 - i;
			if (i >= k)
				break;
			indices[j++] = offset + k;
		}
		AddStrip(j, indices);
	}

	if (bTop)
	{
		j = 0;
		for (i = 0; i < res/2; i++)
		{
			indices[j++] = offset + res + i;
			k = res - 1 - i;
			if (i >= k)
				break;
			indices[j++] = offset + res + k;
		}
		AddStrip(j, indices);
	}
	delete indices;
}

void vtMesh::CreateTetrahedron(const FPoint3 &center, float fRadius)
{
	float A = fRadius * 1.632993161858f;
	float B = fRadius;
	float D = fRadius * 0.333333333333f;
	float F = fRadius * 0.9428090415834f;
	float G = fRadius * 0.4714045207904f;
	FPoint3 p0(-A/2, -D, G);
	FPoint3 p1( A/2, -D, G);
	FPoint3 p2( 0, B, 0);
	FPoint3 p3( 0, -D, -F);

	p0 += center;
	p1 += center;
	p2 += center;
	p3 += center;

	int vidx;
	if (hasVertexNormals())
	{
		// We need distinct vertices for each triangle, so they can have
		//  different normals.  This means 12 vertices, 4 faces * 3 corners.
		vidx = AddVertex(p0); AddVertex(p1); AddVertex(p2);
		AddTri(vidx, vidx+1, vidx+2);

		vidx = AddVertex(p1); AddVertex(p3); AddVertex(p2);
		AddTri(vidx, vidx+1, vidx+2);

		vidx = AddVertex(p3); AddVertex(p0); AddVertex(p2);
		AddTri(vidx, vidx+1, vidx+2);

		vidx = AddVertex(p0); AddVertex(p3); AddVertex(p1);
		AddTri(vidx, vidx+1, vidx+2);
	}
	else
	{
		// With no shading, all we need is 4 vertices for the 4 faces.
		vidx = AddVertex(p0); AddVertex(p1); AddVertex(p2); AddVertex(p3);
		AddTri(vidx+0, vidx+1, vidx+2);
		AddTri(vidx+1, vidx+3, vidx+2);
		AddTri(vidx+3, vidx+0, vidx+2);
		AddTri(vidx+0, vidx+3, vidx+1);
	}
}

/**
 * Adds the vertices and a fan primitive for a single flat rectangle.
 */
void vtMesh::AddRectangleXZ(float xsize, float zsize)
{
	int vidx =
	AddVertexUV(-xsize/2, 0.0f, -zsize/2,	0.0f, 0.0f);
	AddVertexUV( xsize/2, 0.0f, -zsize/2,	1.0f, 0.0f);
	AddVertexUV( xsize/2, 0.0f,  zsize/2,	1.0f, 1.0f);
	AddVertexUV(-xsize/2, 0.0f,  zsize/2,	0.0f, 1.0f);
	AddFan(vidx, vidx+1, vidx+2, vidx+3);
}

/**
 * Adds the vertices and a fan primitive for a single flat rectangle.
 */
void vtMesh::AddRectangleXY(float x, float y, float xsize, float ysize,
								float z, bool bCentered)
{
	int vidx;
	if (bCentered)
	{
		vidx =
		AddVertexUV(-xsize/2, -ysize/2,	z, 0.0f, 0.0f);
		AddVertexUV( xsize/2, -ysize/2,	z, 1.0f, 0.0f);
		AddVertexUV( xsize/2,  ysize/2,	z, 1.0f, 1.0f);
		AddVertexUV(-xsize/2,  ysize/2,	z, 0.0f, 1.0f);
	}
	else
	{
		vidx =
		AddVertexUV(x,		 y,			z, 0.0f, 0.0f);
		AddVertexUV(x+xsize, y,			z, 1.0f, 0.0f);
		AddVertexUV(x+xsize, y+ysize,	z, 1.0f, 1.0f);
		AddVertexUV(x,		 y+ysize,	z, 0.0f, 1.0f);
	}
	if (getPrimType() == osg::PrimitiveSet::TRIANGLE_FAN)
		AddFan(vidx, vidx+1, vidx+2, vidx+3);
	else if (getPrimType() == osg::PrimitiveSet::QUADS)
		AddQuad(vidx, vidx+1, vidx+2, vidx+3);
}

/**
 * Adds an conical surface to this mesh.  This is a subset of a full cone,
 * bounded by start/end factors along the two degrees of freedom of the
 * surface of the cone.  The default orientation of the cone is with the
 * tip pointing up (radius increasing downward).
 *
 * \param tip The top point of the cone.
 * \param radial_angle This is the angle between the cone's edge and its
 *		center axis, in radians.  Expected range is 0 to PI/2.  Small values
 *		indicate a sharp, pointed cone, large values indicate a blunt cone.
 *		The slope of the cone's edge is tan(radial_angle).
 * \param theta1, theta2 Start and end values for the theta value, which
 *		ranges from 0 to 2*PI around the central axis of the cone.
 * \param r1, r2 Start and end values for the cone's radius.  These range
 *		from 0 (at the tip of the cone) and increase downward.
 * \param res Resolution, number of polygons along each side of the
 *		surface mesh.
 */
void vtMesh::CreateConicalSurface(const FPoint3 &tip, double radial_angle,
									double theta1, double theta2,
									double r1, double r2, int res)
{
	int i, j, vidx;
	double tan_cr = tan(radial_angle);
	double theta, theta_step = (theta2 - theta1) / (res - 1);
	double r, r_step = (r2 - r1) / (res - 1);

	FPoint3 p, norm;

	r = r1;
	for (i = 0; i < res; i++)
	{
		theta = theta1;
		for (j = 0; j < res; j++)
		{
			p.x = (float) (tip.x + cos(theta) * r);
			p.z = (float) (tip.z - sin(theta) * r);
			p.y = (float) (tip.y - (r / tan_cr));
			vidx = AddVertex(p);

			if (hasVertexNormals())
			{
				// compute vertex normal for lighting
				norm.x = (float) (cos(theta) * r);
				norm.y = 0.0f;
				norm.z = (float) (sin(theta) * r);
				norm.Normalize();
				SetVtxNormal(vidx, norm);
			}

			theta += theta_step;
		}
		r += r_step;
	}
	CreateRectangularMesh(res, res);
}

/**
 * Adds an rectangular surface to this mesh.
 * The rectangle will lie in the first two axes given, facing toward the
 * third.  Axes can be specified by number.  For example, to produce a
 * rectangle in the XZ plane facing along the Y axis, you would pass 0, 2, 1.
 *
 * \param iQuads1 The number of quads along the first axis.
 * \param iQuads2 The number of quads along the second axis.
 * \param Axis1 The first axis (X=0, Y=1, Z=2)
 * \param Axis2 The second axis (X=0, Y=1, Z=2)
 * \param Axis3 The third axis (X=0, Y=1, Z=2)
 * \param min1 The lower-left-hand corner of the rectangle's position
 * \param max1 The size of the rectangle.
 * \param fLevel The value of the rectangle on the third axis.
 * \param fTiling UV tiling.  Set to 1 for UV coordinate of O..1.
 */
void vtMesh::CreateRectangle(int iQuads1, int iQuads2,
		int Axis1, int Axis2, int Axis3,
		const FPoint2 &min1, const FPoint2 &max1, float fLevel, float fTiling)
{
	int iVerts1 = iQuads1 + 1;
	int iVerts2 = iQuads2 + 1;

	FPoint2 size = max1 - min1;
	FPoint3 pos, normal;

	pos[Axis3] = fLevel;
	normal[Axis1] = 0;
	normal[Axis2] = 0;
	normal[Axis3] = 1;

	for (int i = 0; i < iVerts1; i++)
	{
		pos[Axis1] = min1.x + (size.x / iQuads1) * i;
		for (int j = 0; j < iVerts2; j++)
		{
			pos[Axis2] = min1.y + (size.y / iQuads2) * j;

			int vidx = AddVertex(pos);

			if (hasVertexNormals())
				SetVtxNormal(vidx, normal);

			if (hasVertexTexCoords())		/* compute tex coords */
			{
				FPoint2 tc((float) i/iQuads1 * fTiling,
							(float) j/iQuads2 * fTiling);
				SetVtxTexCoord(vidx, tc);
			}
		}
	}
	CreateRectangularMesh(iVerts1, iVerts2);
}

/**
 * Transform all the vertices of the mesh by the indicated matrix.
 */
void vtMesh::TransformVertices(const FMatrix4 &mat)
{
	int i, num = NumVertices();
	FPoint3 p, p2;

	for (i = 0; i < num; i++)
	{
		p = GetVtxPos(i);
		mat.Transform(p, p2);
		SetVtxPos(i, p2);
	}
	if (hasVertexNormals())
	{
		for (i = 0; i < num; i++)
		{
			p = GetVtxNormal(i);
			mat.TransformVector(p, p2);
			SetVtxNormal(i, p2);
		}
	}
}

// Override with ability to get OSG bounding box
void vtMesh::GetBoundBox(FBox3 &box) const
{
	const osg::BoundingBox &osg_box = getBound();
	s2v(osg_box, box);
}

#if 0	// alternate implementation
/**
 * Computes the bounding box of the mesh, based on the extent of its
 * vertices.  Result is placed in the 'box' parameter.  If there
 * are no vertices, then 'box' is unchanged.
 */
void vtMesh::GetBoundBox(FBox3 &box) const
{
	int num = NumVertices();
	if (num == 0)
		return;

	box.min.Set(1E8, 1E8, 1E8);
	box.max.Set(-1E8, -1E8, -1E8);

	for (int i = 0; i < num; i++)
	{
		FPoint3 p = GetVtxPos(i);

		if (p.x < box.min.x) box.min.x = p.x;
		if (p.y < box.min.y) box.min.y = p.y;
		if (p.z < box.min.z) box.min.z = p.z;

		if (p.x > box.max.x) box.max.x = p.x;
		if (p.y > box.max.y) box.max.y = p.y;
		if (p.z > box.max.z) box.max.z = p.z;
	}
}
#endif

/**
 * Add a triangle.
 *  p0, p1, p2 are the indices of the vertices of the triangle.
 */
void vtMesh::AddTri(int p0, int p1, int p2)
{
#ifdef VTP_AVOID_OSG_INDICES
	PrimType PrimType = getPrimType();
	osg::DrawElements *pDrawElements;
	if (PrimType == osg::PrimitiveSet::TRIANGLES)
	{
		pDrawElements = getPrimitiveSet(0)->getDrawElements();
	}
	else if (PrimType == osg::PrimitiveSet::TRIANGLE_STRIP || PrimType == osg::PrimitiveSet::TRIANGLE_FAN)
	{
		pDrawElements = new osg::DrawElementsUShort(PrimType, 3);
		addPrimitiveSet(pDrawElements);
	}
	pDrawElements->addElement(p0);
	pDrawElements->addElement(p1);
	pDrawElements->addElement(p2);
#else
	osg::UIntArray *uia = getIndices();
	uia->push_back(p0);
	uia->push_back(p1);
	uia->push_back(p2);

	if (getPrimType() == osg::PrimitiveSet::TRIANGLES)
	{
		// OSG's "count" is the number of indices, not the number of primitives
		getDrawArrays()->setCount(uia->size());
	}
	else if (getPrimType() == osg::PrimitiveSet::TRIANGLE_STRIP || getPrimType() == osg::PrimitiveSet::TRIANGLE_FAN)
	{
		getDrawArrayLengths()->push_back(3);
	}
#endif
}

/**
 * Add a triangle fan with up to 6 points (center + 5 points).  The first 3
 * arguments are required, the rest are optional.  A fan will be created
 * with as many point indices as you pass.
 */
void vtMesh::AddFan(int p0, int p1, int p2, int p3, int p4, int p5)
{
#ifdef VTP_AVOID_OSG_INDICES
	osg::DrawElements *pDrawElements;
	pDrawElements = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_FAN);
	pDrawElements->addElement(p0);
	pDrawElements->addElement(p1);
	if (p2 != -1)
		pDrawElements->addElement(p2);
	if (p3 != -1)
		pDrawElements->addElement(p3);
	if (p4 != -1)
		pDrawElements->addElement(p4);
	if (p5 != -1)
		pDrawElements->addElement(p5);
	addPrimitiveSet(pDrawElements);
#else
	int len = 2;

	osg::UIntArray *uia = (osg::UIntArray*) getVertexIndices();
	uia->push_back(p0);
	uia->push_back(p1);

	if (p2 != -1) { uia->push_back(p2); len = 3; }
	if (p3 != -1) { uia->push_back(p3); len = 4; }
	if (p4 != -1) { uia->push_back(p4); len = 5; }
	if (p5 != -1) { uia->push_back(p5); len = 6; }

	getDrawArrayLengths()->push_back(len);
#endif
}

/**
 * Add a triangle fan with any number of points.
 *	\param idx An array of vertex indices for the fan.
 *	\param iNVerts the number of vertices in the fan.
 */
void vtMesh::AddFan(int *idx, int iNVerts)
{
#ifdef VTP_AVOID_OSG_INDICES
	osg::DrawElements *pDrawElements;
	pDrawElements = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_FAN);
	pDrawElements->reserveElements(iNVerts);
	for (int i = 0; i < iNVerts; i++)
		pDrawElements->addElement(idx[i]);
	addPrimitiveSet(pDrawElements);
#else
	osg::UIntArray *uia = getIndices();

	for (int i = 0; i < iNVerts; i++)
		uia->push_back(idx[i]);

	getDrawArrayLengths()->push_back(iNVerts);
#endif
}

/**
 * Adds an indexed strip to the mesh.
 *
 * \param iNVerts The number of vertices in the strip.
 * \param pIndices An array of the indices of the vertices in the strip.
 */
void vtMesh::AddStrip(int iNVerts, unsigned short *pIndices)
{
#ifdef VTP_AVOID_OSG_INDICES
	osg::DrawElements *pDrawElements;
	switch(m_PrimType)
	{
		case osg::PrimitiveSet::LINE_STRIP:
			pDrawElements = new osg::DrawElementsUShort(osg::PrimitiveSet::LINE_STRIP);
			break;
		case osg::PrimitiveSet::TRIANGLE_STRIP:
			pDrawElements = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLE_STRIP);
			break;
		case osg::PrimitiveSet::QUAD_STRIP:
			pDrawElements = new osg::DrawElementsUShort(osg::PrimitiveSet::QUAD_STRIP);
			break;
	}
	pDrawElements->reserveElements(iNVerts);
	for (int i = 0; i < iNVerts; i++)
		pDrawElements->addElement(pIndices[i]);
	addPrimitiveSet(pDrawElements);
#else
	osg::UIntArray *uia = getIndices();

	for (int i = 0; i < iNVerts; i++)
		uia->push_back(pIndices[i]);

	getDrawArrayLengths()->push_back(iNVerts);
#endif
}

/**
 * Add a single line primitive to a mesh.
 *	\param p0, p1	The indices of the two vertices of the line.
 */
void vtMesh::AddLine(int p0, int p1)
{
#ifdef VTP_AVOID_OSG_INDICES
	PrimType PrimType = getPrimType();
	osg::DrawElements *pDrawElements;
	if (PrimType == osg::PrimitiveSet::LINES)
	{
		pDrawElements = getPrimitiveSet(0)->getDrawElements();
	}
	else if (PrimType == osg::PrimitiveSet::LINE_STRIP)
	{
		// This seems a bit pointless
		pDrawElements = new osg::DrawElementsUShort(PrimType, 2);
		addPrimitiveSet(pDrawElements);
	}
	pDrawElements->addElement(p0);
	pDrawElements->addElement(p1);
#else
	osg::UIntArray *uia = getIndices();

	uia->push_back(p0);
	uia->push_back(p1);

	if (getPrimType() == osg::PrimitiveSet::LINES)
	{
		getDrawArrays()->setCount(uia->size());
	}
	else if (getPrimType() == osg::PrimitiveSet::LINE_STRIP)
	{
		getDrawArrayLengths()->push_back(2);
	}
#endif
}

/**
 * Add a single line primitive to a mesh.
 *	\param pos1, pos2	The positions of the two vertices of the line.
 *  \return The index of the first vertex added.
 */
int vtMesh::AddLine(const FPoint3 &pos1, const FPoint3 &pos2)
{
	int p0 = AddVertex(pos1);
	int p1 = AddVertex(pos2);
	AddLine(p0, p1);
	return p0;
}

/**
 * Add a triangle.
 *  p0, p1, p2 are the indices of the vertices of the triangle.
 */
void vtMesh::AddQuad(int p0, int p1, int p2, int p3)
{
#ifdef VTP_AVOID_OSG_INDICES
	osg::DrawElements *pDrawElements;
	pDrawElements = getPrimitiveSet(0)->getDrawElements();
	pDrawElements->addElement(p0);
	pDrawElements->addElement(p1);
	pDrawElements->addElement(p2);
	pDrawElements->addElement(p3);
#else
	osg::UIntArray *uia = getIndices();

	uia->push_back(p0);
	uia->push_back(p1);
	uia->push_back(p2);
	uia->push_back(p3);
	getDrawArrays()->setCount(uia->size());
#endif
}

uint vtMesh::NumVertices() const
{
	return getVerts()->size();
}

/**
 * Set the position of a vertex.
 *	\param i	Index of the vertex.
 *	\param p	The position.
 */
void vtMesh::SetVtxPos(uint i, const FPoint3 &p)
{
	osg::Vec3 s;
	v2s(p, s);

	if (i >= (int)getVerts()->size())
		getVerts()->resize(i + 1);
	getVerts()->at(i) = s;

#ifdef VTP_AVOID_OSG_INDICES
	if (getPrimType() == osg::PrimitiveSet::POINTS)
		getDrawArrays()->setCount(getVerts()->size());
#ifdef USE_OPENGL_BUFFER_OBJECTS
	getVerts()->dirty();
#endif
#else
	if (getPrimType() == GL_POINTS)
	{
		osg::UIntArray *uia = getIndices();

		if (i >= (int) uia->size())
			uia->resize(i + 1);

		uia->at(i) = i;
		getDrawArrays()->setCount(getVerts()->size());
	}
#endif
}

/**
 * Get the position of a vertex.
 */
FPoint3 vtMesh::GetVtxPos(uint i) const
{
	FPoint3 p;
	s2v(getVerts()->at(i), p);
	return p;
}

/**
 * Set the normal of a vertex.  This is used for lighting, if the mesh
 *	is used with a material with lighting enabled.  Generally you will
 *	want to use a vector of unit length.
 *
 *	\param i	Index of the vertex.
 *	\param norm	The normal vector.
 */
void vtMesh::SetVtxNormal(uint i, const FPoint3 &norm)
{
	osg::Vec3 s;
	v2s(norm, s);

	if (i >= (int) getNormals()->size())
		getNormals()->resize(i + 1);

	getNormals()->at(i) = s;
#ifdef USE_OPENGL_BUFFER_OBJECTS
	getNormals()->dirty();
#endif
}

/**
 * Get the normal of a vertex.
 */
FPoint3 vtMesh::GetVtxNormal(uint i) const
{
	FPoint3 p;
	s2v(getNormals()->at(i), p);
	return p;
}

/**
 * Set the color of a vertex.  This color multiplies with the color of the
 *	material used with the mesh, so if you want the vertex color to be
 *	dominant, use a white material.
 *
 *	\param i		Index of the vertex.
 *	\param color	The color.
 */
void vtMesh::SetVtxColor(uint i, const RGBAf &color)
{
	if (!hasVertexColors())
		return;

	osg::Vec4 s;
	v2s(color, s);

	if (i >= (int) getColors()->size())
		getColors()->resize(i + 1);

	getColors()->at(i) = s;
#ifdef USE_OPENGL_BUFFER_OBJECTS
	getColors()->dirty();
#endif
}

/**
 * Get the color of a vertex.
 */
RGBAf vtMesh::GetVtxColor(uint i) const
{
	if (hasVertexColors())
	{
		RGBAf p;
		s2v(getColors()->at(i), p);
		return p;
	}
	return RGBf(0,0,0);
}

/**
 * Set the texture coordinates of a vertex.  Generally these values are
 *	in the range of 0 to 1, although you can use higher values if you want
 *	repeating tiling.  The components of the texture coordinates are
 *  usually called "u" and "v".
 *
 *	\param i	Index of the vertex.
 *	\param uv	The texture coordinate.
 */
void vtMesh::SetVtxTexCoord(uint i, const FPoint2 &uv)
{
	if (!hasVertexTexCoords())
		return;

	osg::Vec2 s;
	v2s(uv, s);

	// Not sure whether I need this
	if (i >= (int) getTexCoords()->size())
		getTexCoords()->resize(i + 1);

	getTexCoords()->at(i) = s;
#ifdef USE_OPENGL_BUFFER_OBJECTS
	getTexCoords()->dirty();
#endif
}

/**
 * Get the texture coordinates of a vertex.
 */
FPoint2 vtMesh::GetVtxTexCoord(uint i) const
{
	if (hasVertexTexCoords())
	{
		FPoint2 p;
		s2v(getTexCoords()->at(i), p);
		return p;
	}
	return FPoint2(0,0);
}

int vtMesh::NumPrims() const
{
	return getPrimSet()->getNumPrimitives();
}

/**
 * Set whether to allow rendering optimization of this mesh.  With OpenGL,
 *	this optimization is called a "display list", which increases the speed
 *	of rendering by creating a special representation of the mesh the first
 *	time it is drawn.  The tradeoff is that subsequent changes to the mesh
 *	are not applied unless you call ReOptimize().
 *
 *	\param bAllow	True to allow optimization.  The default is true.
 */
void vtMesh::AllowOptimize(bool bAllow)
{
	setUseDisplayList(bAllow);
}

/**
 * For a mesh with rendering optimization enabled, forces an update of the
 *	optimized representation.
 */
void vtMesh::ReOptimize()
{
	dirtyDisplayList();
	dirtyBound();
}

/**
 * Set the line width, in pixels, for this mesh's geometry.
 *
 * You should call this method _after_ the mesh has been added to some
 *  geometry with vtGeode::AddMesh()
 * (this requirement was found with the OSG flavor of vtlib.)
 */
void vtMesh::SetLineWidth(float fWidth)
{
	osg::LineWidth *lws = new osg::LineWidth;
	osg::StateSet *ss = getOrCreateStateSet();

	lws->setWidth(fWidth);
	ss->setAttributeAndModes(lws,
		osg::StateAttribute::OVERRIDE|osg::StateAttribute::ON);
}

/**
 * Set the normals of the vertices by combining the normals of the
 * surrounding faces.  This requires going through all the primitives
 * to average their contribution to each vertex.
 */
void vtMesh::SetNormalsFromPrimitives()
{
	if (getPrimType() != osg::PrimitiveSet::TRIANGLES &&
		getPrimType() != osg::PrimitiveSet::QUADS &&
		getPrimType() != osg::PrimitiveSet::TRIANGLE_STRIP &&
		getPrimType() != osg::PrimitiveSet::POLYGON)
		return;

	osg::Vec3Array *norms = getNormals();
	norms->resize(getVerts()->size());
	osg::Vec3Array::iterator itr;
	for (itr = norms->begin(); itr != norms->end(); itr++)
		itr->set(0, 0, 0);

	switch (getPrimType())
	{
	case osg::PrimitiveSet::TRIANGLES:		_AddTriangleNormals(); break;
	case osg::PrimitiveSet::TRIANGLE_STRIP:	_AddStripNormals(); break;
	case osg::PrimitiveSet::QUADS:			_AddQuadNormals(); break;
	case osg::PrimitiveSet::POLYGON:		_AddPolyNormals(); break;
	default:	// Keep picky compilers quiet.
		break;
	}

	for (itr = norms->begin(); itr != norms->end(); itr++)
		itr->normalize();
}

void vtMesh::_AddStripNormals()
{
#ifdef VTP_AVOID_OSG_INDICES
	uint i, j, len;
	uint NumPrimitiveSets = getNumPrimitiveSets();
	unsigned short v0 = 0, v1 = 0, v2 = 0;
	osg::Vec3 p0, p1, p2, d0, d1, norm;
	osg::Vec3Array *norms = getNormals();

	for (i = 0; i < NumPrimitiveSets; i++)
	{
		osg::DrawElements *pDrawElements = getPrimitiveSet(i)->getDrawElements();
		len = pDrawElements->getNumIndices(); // This actually just returns the size of the element list in this case
		for (j = 0; j < len; j++)
		{
			v0 = v1; p0 = p1;
			v1 = v2; p1 = p2;
			v2 = pDrawElements->index(j);
			p2 = getVerts()->at(v2);
			if (j >= 2)
			{
				d0 = (p1 - p0);
				d1 = (p2 - p0);
				d0.normalize();
				d1.normalize();

				norm = d0^d1;

				norms->at(v0) += norm;
				norms->at(v1) += norm;
				norms->at(v2) += norm;
			}
		}
	}
#else
	osg::DrawArrayLengths *dal = getDrawArrayLengths();
	int prims = NumPrims();
	int i, j, len, idx;
	unsigned short v0 = 0, v1 = 0, v2 = 0;
	osg::Vec3 p0, p1, p2, d0, d1, norm;

	osg::UIntArray *uia = getIndices();
	osg::Vec3Array *norms = getNormals();

	idx = 0;
	for (i = 0; i < prims; i++)
	{
		len = dal->at(i);
		for (j = 0; j < len; j++)
		{
			v0 = v1; p0 = p1;
			v1 = v2; p1 = p2;
			v2 = uia->at(idx);
			p2 = getVerts()->at(v2);
			if (j >= 2)
			{
				d0 = (p1 - p0);
				d1 = (p2 - p0);
				d0.normalize();
				d1.normalize();

				norm = d0^d1;

				norms->at(v0) += norm;
				norms->at(v1) += norm;
				norms->at(v2) += norm;
			}
			idx++;
		}
	}
#endif
}

void vtMesh::_AddPolyNormals()
{
#ifdef VTP_AVOID_OSG_INDICES
	uint i, j, len;
	uint NumPrimitiveSets = getNumPrimitiveSets();
	unsigned short v0 = 0, v1 = 0, v2 = 0;
	osg::Vec3 p0, p1, p2, d0, d1, norm;
	osg::Vec3Array *norms = getNormals();

	for (i = 0; i < NumPrimitiveSets; i++)
	{
		osg::DrawElements *pDrawElements = getPrimitiveSet(i)->getDrawElements();
		len = pDrawElements->getNumIndices(); // This actually just returns the size of the element list in this case
		// ensure this poly has enough verts to define a surface
		if (len >= 3)
		{
			v0 = pDrawElements->index(0);
			v1 = pDrawElements->index(1);
			v2 = pDrawElements->index(2);
			p0 = getVerts()->at(v0);
			p1 = getVerts()->at(v1);
			p2 = getVerts()->at(v2);

			d0 = (p1 - p0);
			d1 = (p2 - p0);
			d0.normalize();
			d1.normalize();

			norm = d0^d1;

			for (j = 0; j < len; j++)
			{
				uint v = pDrawElements->index(j);
				getNormals()->at(v) += norm;
			}
		}
	}
#else
	osg::DrawArrayLengths *dal = getDrawArrayLengths();
	if (!dal)
		return;

	int prims = NumPrims();
	int i, j, len, idx;
	unsigned short v0 = 0, v1 = 0, v2 = 0;
	osg::Vec3 p0, p1, p2, d0, d1, norm;

	osg::UIntArray *uia = getIndices();

	idx = 0;
	for (i = 0; i < prims; i++)
	{
		len = dal->at(i);
		// ensure this poly has enough verts to define a surface
		if (len >= 3)
		{
			v0 = uia->at(idx);
			v1 = uia->at(idx+1);
			v2 = uia->at(idx+2);
			p0 = getVerts()->at(v0);
			p1 = getVerts()->at(v1);
			p2 = getVerts()->at(v2);

			d0 = (p1 - p0);
			d1 = (p2 - p0);
			d0.normalize();
			d1.normalize();

			norm = d0^d1;

			for (j = 0; j < len; j++)
			{
				int v = uia->at(idx + j);
				getNormals()->at(v) += norm;
			}
		}
		idx += len;
	}
#endif
}

void vtMesh::_AddTriangleNormals()
{
#ifdef VTP_AVOID_OSG_INDICES
	int tris = NumPrims();
	unsigned short v0, v1, v2;
	osg::Vec3 p0, p1, p2, d0, d1, norm;

	osg::DrawElements *pDrawElements = getPrimitiveSet(0)->getDrawElements();

	for (int i = 0; i < tris; i++)
	{
		v0 = pDrawElements->index(i*3);
		v1 = pDrawElements->index(i*3+1);
		v2 = pDrawElements->index(i*3+2);
		p0 = getVerts()->at(v0);
		p1 = getVerts()->at(v1);
		p2 = getVerts()->at(v2);

		d0 = (p1 - p0);
		d1 = (p2 - p0);
		d0.normalize();
		d1.normalize();

		norm = d0^d1;

		getNormals()->at(v0) += norm;
		getNormals()->at(v1) += norm;
		getNormals()->at(v2) += norm;
	}
#else
	int tris = NumPrims();
	unsigned short v0, v1, v2;
	osg::Vec3 p0, p1, p2, d0, d1, norm;

	osg::UIntArray *uia = getIndices();

	for (int i = 0; i < tris; i++)
	{
		v0 = uia->at(i*3);
		v1 = uia->at(i*3+1);
		v2 = uia->at(i*3+2);
		p0 = getVerts()->at(v0);
		p1 = getVerts()->at(v1);
		p2 = getVerts()->at(v2);

		d0 = (p1 - p0);
		d1 = (p2 - p0);
		d0.normalize();
		d1.normalize();

		norm = d0^d1;

		getNormals()->at(v0) += norm;
		getNormals()->at(v1) += norm;
		getNormals()->at(v2) += norm;
	}
#endif
}

void vtMesh::_AddQuadNormals()
{
#ifdef VTP_AVOID_OSG_INDICES
	int quads = NumPrims();
	unsigned short v0, v1, v2, v3;
	osg::Vec3 p0, p1, p2, d0, d1, norm;

	osg::Vec3Array *norms = getNormals();

	osg::DrawElements *pDrawElements = getPrimitiveSet(0)->getDrawElements();

	for (int i = 0; i < quads; i++)
	{
		v0 = pDrawElements->index(i*4);
		v1 = pDrawElements->index(i*4+1);
		v2 = pDrawElements->index(i*4+2);
		v3 = pDrawElements->index(i*4+3);
		p0 = getVerts()->at(v0);
		p1 = getVerts()->at(v1);
		p2 = getVerts()->at(v2);

		d0 = (p1 - p0);
		d1 = (p2 - p0);
		d0.normalize();
		d1.normalize();

		norm = d0^d1;

		norms->at(v0) += norm;
		norms->at(v1) += norm;
		norms->at(v2) += norm;
		norms->at(v3) += norm;
	}
#else
	int quads = NumPrims();
	unsigned short v0, v1, v2, v3;
	osg::Vec3 p0, p1, p2, d0, d1, norm;

	osg::UIntArray *uia = getIndices();
	osg::Vec3Array *norms = getNormals();

	for (int i = 0; i < quads; i++)
	{
		v0 = uia->at(i*4);
		v1 = uia->at(i*4+1);
		v2 = uia->at(i*4+2);
		v3 = uia->at(i*4+3);
		p0 = getVerts()->at(v0);
		p1 = getVerts()->at(v1);
		p2 = getVerts()->at(v2);

		d0 = (p1 - p0);
		d1 = (p2 - p0);
		d0.normalize();
		d1.normalize();

		norm = d0^d1;

		norms->at(v0) += norm;
		norms->at(v1) += norm;
		norms->at(v2) += norm;
		norms->at(v3) += norm;
	}
#endif
}

/////////////////////////////////////////////////////////////////////////////
// Text

/**
 * Construct a TextMesh object.
 *
 * \param font The font that will be used to draw the text.
 * \param fSize Size (height) in world units of the text rectangle.
 * \param bCenter If true, the origin of the text rectangle is at
 *			it's bottom center.  Otherwise, bottom left.
 */
vtTextMesh::vtTextMesh(osgText::Font *font, float fSize, bool bCenter)
{
	// Set the Font reference width and height resolution in texels.
	setFont(font);
	setFontResolution(32,32);

	// Set the rendered character size in object coordinates.
	setCharacterSize(fSize);

	if (bCenter)
		setAlignment(osgText::Text::CENTER_BOTTOM);

	// We'd like to turn off lighting for the text, but we can't, because
	//  the OSG Text object fiddles with its own StateSet.  Instead, we do
	//  it in vtGeode::AddTextMesh().
}

// Override with ability to get OSG bounding box
void vtTextMesh::GetBoundBox(FBox3 &box) const
{
	const osg::BoundingBox &osg_box = getBound();
	s2v(osg_box, box);
}

void vtTextMesh::SetText(const char *text)
{
	setText(text);
}

void vtTextMesh::SetText(const wchar_t *text)
{
	setText(text);
}

#if SUPPORT_WSTRING
void vtTextMesh::SetText(const std::wstring &text)
{
	setText(text.c_str());
}
#endif

void vtTextMesh::SetPosition(const FPoint3 &pos)
{
	osg::Vec3 s;
	v2s(pos, s);
	setPosition(s);
}

void vtTextMesh::SetRotation(const FQuat &rot)
{
	osg::Quat q(rot.x, rot.y, rot.z, rot.w);
	setRotation(q);
}

void vtTextMesh::SetAlignment(int align)
{
	osgText::Text::AxisAlignment osga;

	if (align == 0)
		osga = osgText::Text::XY_PLANE;
	else if (align == 1)
		osga = osgText::Text::XZ_PLANE;
	else if (align == 2)
		osga = osgText::Text::YZ_PLANE;
	else return;

	setAxisAlignment(osga);
}

void vtTextMesh::SetColor(const RGBAf &rgba)
{
	osg::Vec4 color = v2s(rgba);
	setColor(color);
}


text: console.log('Now');


text:
package marketmaker.application;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Set;

import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jms.annotation.JmsListener;

import com.ripple.core.types.known.tx.txns.OfferCreate;

import marketmaker.entities.AccountBalance;
import marketmaker.entities.AccountBalanceRepository;
import marketmaker.entities.AccountOffer;
import marketmaker.entities.AccountOfferRepository;
import marketmaker.entities.Avalanche;
import marketmaker.entities.AvalancheRepository;
import marketmaker.entities.Offer;
import marketmaker.entities.OfferCreateEntity;
import marketmaker.entities.OfferCreateEntityRepository;
import marketmaker.entities.OfferRepository;

/**
 * Created by bob on 09/01/15.
 */
public class RippleMessageStoreListener {

	private static Logger log = LoggerFactory.getLogger(RippleMessageStoreListener.class);
	private static SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");

	@Autowired
	private AccountOfferRepository accountOfferRepository;
	@Autowired
	private AccountBalanceRepository accountBalanceRepository;
	// @Autowired
	// private OfferBookRepository offerBookRepository;
	@Autowired
	private OfferRepository offerRepository;
	@Autowired
	private AvalancheRepository avalancheRepository;
	@Autowired
	private OfferCreateEntityRepository offerCreateEntityRepository;

	public RippleMessageStoreListener() {
	}

	@JmsListener(destination = "offer_create")
	public void onTransaction(String message) {
		try {
			JSONObject json = new JSONObject(message);
			OfferCreate offer = (OfferCreate) OfferCreate.fromJSONObject(json);
			OfferCreateEntity e = new OfferCreateEntity();
			e.setCreatedAt(Calendar.getInstance().getTime());
			if (offer.expiration() != null)
				e.setExpiration(offer.expiration().toString());
			if (offer.sequence() != null)
				e.setOfferSequence(offer.sequence().toString());
			if (offer.takerGets() != null) {
				e.setTakerGetsCurrency(offer.takerGets().currencyString());

				e.setTakerGetsIssuer(offer.takerGets().issuerString());
				e.setTakerGetsValue(offer.takerGets().value());
			}
			if (offer.takerPays() != null) {
				e.setTakerPaysCurrency(offer.takerPays().currencyString());
				e.setTakerPaysIssuer(offer.takerPays().issuerString());
				e.setTakerPaysValue(offer.takerPays().value());
			}
			offerCreateEntityRepository.save(e);

		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
	}

	@JmsListener(destination = "avalanche")
	public void onAvalanche(String message) {
		try {
			JSONObject json = new JSONObject(message);
			Avalanche avalanche = new Avalanche();
			avalanche.setCreatedAt(Calendar.getInstance().getTime());
			avalanche.setBaseAmount(new BigDecimal(json.getDouble("baseAmount")));
			avalanche.setBaseAsset(json.getString("baseAsset"));
			avalanche.setBaseExpo(new BigDecimal(json.getDouble("baseExpo")));
			avalanche.setCancelAllAccountOffersOnStart(json.getBoolean("cancelAllAccountOffersOnStart"));
			avalanche.setCounterAsset(json.getString("counterAsset"));
			avalanche.setCounterExpo(new BigDecimal(json.getDouble("counterExpo")));
			avalanche.setDegreeAsk(new BigDecimal(json.getDouble("degreeAsk")));
			avalanche.setDegreeBid(new BigDecimal(json.getDouble("degreeBid")));
			avalanche.setEnableOpportunityTaker(json.getBoolean("enableOpportunityTaker"));
			avalanche.setFilteredListAsks(json.get("filteredListAsks").toString());
			avalanche.setFilteredListBids(json.get("filteredListBids").toString());
			avalanche.setListAsks(json.get("listAsks").toString());
			avalanche.setListBids(json.get("listBids").toString());
			avalanche.setMarginAsk(new BigDecimal(json.getDouble("marginAsk")));
			avalanche.setMarginBid(new BigDecimal(json.getDouble("marginBid")));
			avalanche.setMaxOpenAsks(new BigDecimal(json.getDouble("maxOpenAsks")));
			avalanche.setMaxOpenBids(new BigDecimal(json.getDouble("maxOpenBids")));
			avalanche.setPathFrom(json.getString("pathFrom"));
			avalanche.setPathTo(json.getString("pathTo"));
			avalanche.setRangeAsks(json.get("rangeAsks").toString());
			avalanche.setRangeBids(json.get("rangeBids").toString());
			avalanche.setRangeCountBids(json.get("rangeCountBids").toString());
			avalanche.setRangeCountAsks(json.get("rangeCountAsks").toString());
			avalanche.setRefAsset(json.getString("refAsset"));
			avalanche.setRefCost(new BigDecimal(json.getDouble("refCost")));
			avalanche.setSlippage(new BigDecimal(json.getDouble("slippage")));

			avalancheRepository.save(avalanche);
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
	}

	@JmsListener(destination = "offerbook")
	public void onOfferBook(String message) {
//		try {
//			JSONObject o = new JSONObject(message);
//			OfferBook ob = new OfferBook();
//			ob.setCreated_at(Calendar.getInstance().getTime());
//			JSONObject payIssue = o.getJSONObject("payIssue");
//			JSONObject getIssue = o.getJSONObject("getIssue");
//			ob.setPayIssueCurrency(payIssue.optString("currency"));
//			ob.setPayIssueIssuer(payIssue.optString("issuer"));
//			ob.setGetIssueCurrency(getIssue.optString("currency"));
//			ob.setGetIssueIssuer(getIssue.optString("issuer"));
//			Set<Offer> offersAsks = new HashSet<>();
//			Set<Offer> offersBids = new HashSet<>();
//			JSONArray listAsks = o.getJSONArray("offersAsks");
//			JSONArray listBids = o.getJSONArray("offersBids");
//			addOffers(offersAsks, listAsks);
//			addOffers(offersBids, listBids);
//
//			ob.setOffersAsks(offersAsks);
//			ob.setOffersBids(offersBids);
//
//			offerBookRepository.save(ob);
//		} catch (Exception ex) {
//			log.error(ex.getMessage(), ex);
//		}
	}

	private void addOffers(Set<Offer> offers, JSONArray list) {
		Date now = Calendar.getInstance().getTime();
		for (int i = 0; i < list.length(); i++) {
			JSONObject ask = list.getJSONObject(i);
			Offer offer = new Offer();
			offer.setCreated_at(now);
			offer.setBookDirectory(ask.optString("bookDirectory"));
			offer.setAccount(ask.optString("account"));
			offer.setBookNode(ask.optString("bookNode"));
			offer.setFlags(ask.optString("flags"));
			offer.setIndex(ask.optString("index"));
			offer.setLedgerEntryType(ask.optString("ledgerEntryType"));
			// offer.setOwner_funds(new
			// BigDecimal(ask.getDouble("owner_funds")));
			offer.setOwnerNode(ask.optString("OwnerNode"));
			offer.setPreviousTxnID(ask.optString("PreviousTxnID"));
			offer.setPreviousTxnLgrSeq(ask.optString("PreviousTxnLgrSeq"));
			offer.setQuality(new BigDecimal(ask.getDouble("quality")));
			if (ask.optJSONObject("TakerPays") != null) {
				JSONObject takerPays = ask.optJSONObject("TakerPays");
				offer.setTakerPaysValue(new BigDecimal(takerPays.getDouble("value")));
				offer.setTakerPaysIssuer(takerPays.optString("issuer"));
				offer.setTakerPaysCurrency(takerPays.optString("currency"));
			} else {
				offer.setTakerPaysValue(new BigDecimal(ask.getDouble("TakerPays")));
			}
			if (ask.optJSONObject("TakerGets") != null) {
				JSONObject takerGets = ask.optJSONObject("TakerGets");
				offer.setTakerGetsValue(new BigDecimal(takerGets.getDouble("value")));
				offer.setTakerGetsIssuer(takerGets.optString("issuer"));
				offer.setTakerGetsCurrency(takerGets.optString("currency"));
			} else {
				offer.setTakerPaysValue(new BigDecimal(ask.getDouble("TakerGets")));
			}

			offerRepository.save(offer);
			offers.add(offer);
		}
	}

	@JmsListener(destination = "account_balance")
	public void onAccountBalance(String message) {
		try {
			JSONObject jsonObject = new JSONObject(message);
			JSONObject result = jsonObject.getJSONObject("result");
			JSONArray lines = result.getJSONArray("lines");
			Date now = Calendar.getInstance().getTime();
			for (int i = 0; i < lines.length(); i++) {
				JSONObject line = lines.getJSONObject(i);
				AccountBalance ab = new AccountBalance();
				ab.setAccount(line.optString("account"));
				ab.setBalance(new BigDecimal(line.getDouble("balance")));
				ab.setCreatedAt(now);
				ab.setCurrency(line.optString(("currency")));
				ab.setLimit_balance(new BigDecimal(line.getDouble("limit")));
				ab.setLimit_peer(new BigDecimal(line.getDouble("limit_peer")));
				ab.setQuality_in(new BigDecimal(line.getDouble("quality_in")));
				ab.setQuality_out(new BigDecimal(line.getDouble("quality_out")));
				accountBalanceRepository.save(ab);

			}
		} catch (Exception ex) {
			log.error(ex.getMessage(), ex);
		}
	}

	@JmsListener(destination = "account_offers")
	public void onAccountOffers(String message) {

		try {
			accountOfferRepository.updateStatus("inactive");
			JSONObject jsonObject = new JSONObject(message);
			JSONObject result = jsonObject.getJSONObject("result");
			JSONArray offers = result.getJSONArray("offers");
			Date now = Calendar.getInstance().getTime();
			for (int i = 0; i < offers.length(); i++) {
				JSONObject o = offers.getJSONObject(i);
				AccountOffer a = new AccountOffer();
				a.setStatus("active");
				a.setCreatedAt(now);
				a.setFlags(o.optString("flags"));
				a.setQuality(o.optString("quality"));
				a.setSeq(o.optString("seq"));
				a.setLedgerCurrentIndex(result.getLong("ledger_current_index"));

				if (o.optJSONObject("taker_gets") != null) {
					JSONObject takerGets = o.optJSONObject("taker_gets");
					a.setTakerGetsCurrency(takerGets.optString("currency"));
					a.setTakerGetsIssuer(takerGets.optString("issuer"));
					a.setTakerGetsValue(new BigDecimal(takerGets.getDouble("value")));
				} else {
					a.setTakerGetsValue(new BigDecimal(o.getDouble("taker_gets")));
				}

				if (o.optJSONObject("taker_pays") != null) {
					JSONObject takerPays = o.optJSONObject("taker_pays");
					a.setTakerPaysCurrency(takerPays.optString("currency"));
					a.setTakerPaysIssuer(takerPays.optString("issuer"));
					a.setTakerPaysValue(new BigDecimal(takerPays.getDouble("value")));
				} else {
					a.setTakerPaysValue(new BigDecimal(o.getDouble("taker_pays")));
				}

				accountOfferRepository.save(a);
			}

		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
	}
}


text:
using System.Diagnostics.CodeAnalysis;

namespace Umbraco.Cms.Core
{
    /// <remarks>
    /// Not intended for use in background threads where you should make use of <see cref="Umbraco.Cms.Core.Web.IUmbracoContextFactory.EnsureUmbracoContext"/>
    /// and instead resolve IPublishedContentQuery from a <see cref="Microsoft.Extensions.DependencyInjection.IServiceScope"/>
    /// e.g. using <see cref="Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.CreateScope"/>
    /// <example>
    /// <code>
    /// // Background thread example
    /// using UmbracoContextReference _ = _umbracoContextFactory.EnsureUmbracoContext();
    /// using IServiceScope serviceScope = _serviceProvider.CreateScope();
    /// IPublishedContentQuery query = serviceScope.ServiceProvider.GetRequiredService<IPublishedContentQuery>();
    /// </code>
    /// </example>
    /// </remarks>
    public interface IPublishedContentQueryAccessor
    {
        bool TryGetValue([MaybeNullWhen(false)]out IPublishedContentQuery publishedContentQuery);
    }
}


text:
require 'spec_helper'

describe Public::PlataformaController do

end


text:
class WorldMap {
public:
    WorldMap(const std::string &mapFile, float pixelSize, float threshold);
    float wallDistance(Eigen::Vector2f point) const;

    float directedWallDistance(Eigen::Vector2f point, Eigen::Vector2f direction, float maximum) const;

    Eigen::Vector2f mapSize() const;

    nav_msgs::OccupancyGrid const &occupancyGrid() const { return ogMap; }

private:
    float pixelSize;
    Eigen::ArrayXXf distanceMap;
    nav_msgs::OccupancyGrid ogMap;
};

#endif


text:
package com.combustiblelemons.thrillingtales;

import java.sql.SQLException;

import android.content.Context;
import android.database.Cursor;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckedTextView;
import android.widget.TextView;

import static com.combustiblelemons.thrillingtales.Values.SavedScript.TITLE;
import static com.combustiblelemons.thrillingtales.Values.SavedScript.DATE;

public class SavedAdapter extends BaseAdapter {

	Cursor cursor;
	Context context;
	SparseBooleanArray checked;

	public SavedAdapter(Context context) {
		this.context = context;
		this.checked = new SparseBooleanArray();
		try {
			this.cursor = Databases.getSavedScripts(this.context);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

	public void toggle(int position) {
		checked.put(position, !checked.get(position));
	}

	public void resetSelections() {
		for (int i = 0; i < checked.size(); i++) {
			checked.put(i, false);
		}
	}

	public SparseBooleanArray getSelections() {
		return this.checked;
	}

	@Override
	public int getCount() {
		return cursor != null ? cursor.getCount() : 0;
	}

	@Override
	public Object getItem(int arg0) {
		cursor.moveToPosition(arg0);
		return cursor.getString(cursor.getColumnIndex(DATE));
	}

	@Override
	public long getItemId(int arg0) {
		return 0;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View view;
		if (convertView == null) {
			view = LayoutInflater.from(context).inflate(R.layout.single_saved_item, null);
		} else {
			view = (View) convertView;
		}
		if (cursor.moveToPosition(position)) {
			TextView title = (TextView) view.findViewById(R.id.tv_single_saved_item_title);
			CheckedTextView checkedTitle = (CheckedTextView) view.findViewById(R.id.ctv_single_saved_item_title);
			checkedTitle.setChecked(checked.get(position));
			TextView date = (TextView) view.findViewById(R.id.tv_single_saved_item_date);
			String title_value = cursor.getString(cursor.getColumnIndex(TITLE));
			if (title_value != null) {
				title.setText(title_value);
				checkedTitle.setText(title_value);
			}
			date.setText(cursor.getString(cursor.getColumnIndex(DATE)));
		}
		return view;
	}
}


text:
<?php

// autoload_classmap.php @generated by Composer

$vendorDir = dirname(dirname(__FILE__));
$baseDir = dirname($vendorDir);

return array(
    'Upadd\\Bin\\Alias' => $vendorDir . '/Upadd/Bin/Alias.php',
    'Upadd\\Bin\\Application' => $vendorDir . '/Upadd/Bin/Application.php',
    'Upadd\\Bin\\Cache\\Cache' => $vendorDir . '/Upadd/Bin/Cache/Cache.php',
    'Upadd\\Bin\\Cache\\Mem\\Mem' => $vendorDir . '/Upadd/Bin/Cache/Mem.php',
    'Upadd\\Bin\\Config\\Configuration' => $vendorDir . '/Upadd/Bin/Config/Configuration.php',
    'Upadd\\Bin\\Config\\GetConfiguration' => $vendorDir . '/Upadd/Bin/Config/GetConfiguration.php',
    'Upadd\\Bin\\Db\\Db' => $vendorDir . '/Upadd/Bin/Db/Db.php',
    'Upadd\\Bin\\Db\\LinkPdoMysql' => $vendorDir . '/Upadd/Bin/Db/LinkPdoMysql.php',
    'Upadd\\Bin\\Db\\Mysql' => $vendorDir . '/Upadd/Bin/Db/Mysql.php',
    'Upadd\\Bin\\Factory' => $vendorDir . '/Upadd/Bin/Factory.php',
    'Upadd\\Bin\\Http\\Data' => $vendorDir . '/Upadd/Bin/Http/Data.php',
    'Upadd\\Bin\\Http\\Request' => $vendorDir . '/Upadd/Bin/Http/Request.php',
    'Upadd\\Bin\\Http\\Route' => $vendorDir . '/Upadd/Bin/Http/Route.php',
    'Upadd\\Bin\\Loader' => $vendorDir . '/Upadd/Bin/Loader.php',
    'Upadd\\Bin\\Package\\Config' => $vendorDir . '/Upadd/Bin/Package/Config.php',
    'Upadd\\Bin\\Package\\Data' => $vendorDir . '/Upadd/Bin/Package/Data.php',
    'Upadd\\Bin\\Package\\Log' => $vendorDir . '/Upadd/Bin/Package/Log.php',
    'Upadd\\Bin\\Package\\Routes' => $vendorDir . '/Upadd/Bin/Package/Routes.php',
    'Upadd\\Bin\\Package\\Session' => $vendorDir . '/Upadd/Bin/Package/Session.php',
    'Upadd\\Bin\\Session\\SessionFile' => $vendorDir . '/Upadd/Bin/Session/SessionFile.php',
    'Upadd\\Bin\\Session\\getSession' => $vendorDir . '/Upadd/Bin/Session/getSession.php',
    'Upadd\\Bin\\Tool\\Log' => $vendorDir . '/Upadd/Bin/Tool/Log.php',
    'Upadd\\Bin\\Tool\\PageData' => $vendorDir . '/Upadd/Bin/Tool/PageData.php',
    'Upadd\\Bin\\Tool\\Rbac' => $vendorDir . '/Upadd/Bin/Tool/Rbac.php',
    'Upadd\\Bin\\Tool\\Security' => $vendorDir . '/Upadd/Bin/Tool/Security.php',
    'Upadd\\Bin\\Tool\\Session' => $vendorDir . '/Upadd/Bin/Tool/Session.php',
    'Upadd\\Bin\\Tool\\Upload' => $vendorDir . '/Upadd/Bin/Tool/Upload.php',
    'Upadd\\Bin\\Tool\\Verify' => $vendorDir . '/Upadd/Bin/Tool/Verify.php',
    'Upadd\\Bin\\Tool\\View' => $vendorDir . '/Upadd/Bin/Tool/View.php',
    'Upadd\\Bin\\UpaddException' => $vendorDir . '/Upadd/Bin/UpaddException.php',
    'Upadd\\Bin\\View\\Tag' => $vendorDir . '/Upadd/Bin/View/Tag.php',
    'Upadd\\Bin\\View\\Templates' => $vendorDir . '/Upadd/Bin/View/Templates.php',
    'Upadd\\Frame\\Action' => $vendorDir . '/Upadd/Frame/Action.php',
    'Upadd\\Frame\\Check' => $vendorDir . '/Upadd/Frame/Check.php',
    'Upadd\\Frame\\Model' => $vendorDir . '/Upadd/Frame/Model.php',
    'Upadd\\Frame\\ProcessingSql' => $vendorDir . '/Upadd/Frame/ProcessingSql.php',
    'Upadd\\Frame\\Query' => $vendorDir . '/Upadd/Frame/Query.php',
    'Whoops\\Module' => $vendorDir . '/filp/whoops/src/deprecated/Zend/Module.php',
    'Whoops\\Provider\\Zend\\ExceptionStrategy' => $vendorDir . '/filp/whoops/src/deprecated/Zend/ExceptionStrategy.php',
    'Whoops\\Provider\\Zend\\RouteNotFoundStrategy' => $vendorDir . '/filp/whoops/src/deprecated/Zend/RouteNotFoundStrategy.php',
);


text:
Alerts and Notices

<form action="settings.php?t=alerts" method="post" id="save">
<?php csrf_token(); ?>
<input type="hidden" name="t" value="alerts" >

Alerts and Notices sent to staff on ticket "events"

New Ticket Alert:

            Status:
                <input type="radio" name="ticket_alert_active"  value="1"   <?php echo $config['ticket_alert_active']?'checked':''; ?> />Enable
                <input type="radio" name="ticket_alert_active"  value="0"   <?php echo !$config['ticket_alert_active']?'checked':''; ?> />Disable
                   <?php echo $errors['ticket_alert_active']; ?>

                <input type="checkbox" name="ticket_alert_admin" <?php echo $config['ticket_alert_admin']?'checked':''; ?>> Admin Email (<?php echo $cfg->getAdminEmail(); ?>)

                <input type="checkbox" name="ticket_alert_dept_manager" <?php echo $config['ticket_alert_dept_manager']?'checked':''; ?>> Department Manager

                <input type="checkbox" name="ticket_alert_dept_members" <?php echo $config['ticket_alert_dept_members']?'checked':''; ?>> Department Members (spammy)

New Message Alert:

            Status:
              <input type="radio" name="message_alert_active"  value="1"   <?php echo $config['message_alert_active']?'checked':''; ?> />Enable

              <input type="radio" name="message_alert_active"  value="0"   <?php echo !$config['message_alert_active']?'checked':''; ?> />Disable

              <input type="checkbox" name="message_alert_laststaff" <?php echo $config['message_alert_laststaff']?'checked':''; ?>> Last Respondent

              <input type="checkbox" name="message_alert_assigned" <?php echo $config['message_alert_assigned']?'checked':''; ?>> Assigned Staff

              <input type="checkbox" name="message_alert_dept_manager" <?php echo $config['message_alert_dept_manager']?'checked':''; ?>> Department Manager (spammy)

New Internal Note Alert:

            Status:
              <input type="radio" name="note_alert_active"  value="1"   <?php echo $config['note_alert_active']?'checked':''; ?> />Enable

              <input type="radio" name="note_alert_active"  value="0"   <?php echo !$config['note_alert_active']?'checked':''; ?> />Disable
                  <?php echo $errors['note_alert_active']; ?>

              <input type="checkbox" name="note_alert_laststaff" <?php echo $config['note_alert_laststaff']?'checked':''; ?>> Last Respondent

              <input type="checkbox" name="note_alert_assigned" <?php echo $config['note_alert_assigned']?'checked':''; ?>> Assigned Staff

              <input type="checkbox" name="note_alert_dept_manager" <?php echo $config['note_alert_dept_manager']?'checked':''; ?>> Department Manager (spammy)

Ticket Assignment Alert:

            Status:
              <input name="assigned_alert_active" value="1" checked="checked" type="radio">Enable

              <input name="assigned_alert_active" value="0" type="radio">Disable
                   <?php echo $errors['assigned_alert_active']; ?>

              <input type="checkbox" name="assigned_alert_staff" <?php echo $config['assigned_alert_staff']?'checked':''; ?>> Assigned Staff

              <input type="checkbox"name="assigned_alert_team_lead" <?php echo $config['assigned_alert_team_lead']?'checked':''; ?>>Team Lead (On team assignment)

              <input type="checkbox"name="assigned_alert_team_members" <?php echo $config['assigned_alert_team_members']?'checked':''; ?>>
                Team Members (spammy)

Ticket Transfer Alert:

            Status:
              <input type="radio" name="transfer_alert_active"  value="1"   <?php echo $config['transfer_alert_active']?'checked':''; ?> />Enable
              <input type="radio" name="transfer_alert_active"  value="0"   <?php echo !$config['transfer_alert_active']?'checked':''; ?> />Disable
                  <?php echo $errors['alert_alert_active']; ?>

              <input type="checkbox" name="transfer_alert_assigned" <?php echo $config['transfer_alert_assigned']?'checked':''; ?>> Assigned Staff/Team

              <input type="checkbox" name="transfer_alert_dept_manager" <?php echo $config['transfer_alert_dept_manager']?'checked':''; ?>> Department Manager

              <input type="checkbox" name="transfer_alert_dept_members" <?php echo $config['transfer_alert_dept_members']?'checked':''; ?>>
                Department Members (spammy)

Overdue Ticket Alert:

            Status:
              <input type="radio" name="overdue_alert_active"  value="1"   <?php echo $config['overdue_alert_active']?'checked':''; ?> />Enable
              <input type="radio" name="overdue_alert_active"  value="0"   <?php echo !$config['overdue_alert_active']?'checked':''; ?> />Disable
                  <?php echo $errors['overdue_alert_active']; ?>

              <input type="checkbox" name="overdue_alert_assigned" <?php echo $config['overdue_alert_assigned']?'checked':''; ?>> Assigned Staff/Team

              <input type="checkbox" name="overdue_alert_dept_manager" <?php echo $config['overdue_alert_dept_manager']?'checked':''; ?>> Department Manager

              <input type="checkbox" name="overdue_alert_dept_members" <?php echo $config['overdue_alert_dept_members']?'checked':''; ?>> Department Members (spammy)

System Alerts:

              <input type="checkbox" name="send_sys_errors" checked="checked" disabled="disabled">System Errors

              <input type="checkbox" name="send_sql_errors" <?php echo $config['send_sql_errors']?'checked':''; ?>>SQL errors

              <input type="checkbox" name="send_login_errors" <?php echo $config['send_login_errors']?'checked':''; ?>>Excessive Login attempts

    <input class="button" type="submit" name="submit" value="Save Changes">
    <input class="button" type="reset" name="reset" value="Reset Changes">

</form>