text:
file(REMOVE_RECURSE
  "CMakeFiles/pibench.dir/benchmark.cpp.o"
  "CMakeFiles/pibench.dir/benchmark.cpp.o.d"
  "CMakeFiles/pibench.dir/key_generator.cpp.o"
  "CMakeFiles/pibench.dir/key_generator.cpp.o.d"
  "CMakeFiles/pibench.dir/library_loader.cpp.o"
  "CMakeFiles/pibench.dir/library_loader.cpp.o.d"
  "CMakeFiles/pibench.dir/operation_generator.cpp.o"
  "CMakeFiles/pibench.dir/operation_generator.cpp.o.d"
  "CMakeFiles/pibench.dir/value_generator.cpp.o"
  "CMakeFiles/pibench.dir/value_generator.cpp.o.d"
  "libpibench.a"
  "libpibench.pdb"
)

# Per-language clean rules from dependency scanning.
foreach(lang CXX)
  include(CMakeFiles/pibench.dir/cmake_clean_${lang}.cmake OPTIONAL)
endforeach()

license: MIT

repository: gitzhqian/pibench-trees-hashing

repo_name: gitzhqian/pibench-trees-hashing

branch_name: refs/heads/main

extension: cmake


text:
package algorithm

import (
	"math"
)

// ALVNode alv tree node
type ALVNode struct {
	Data   int32
	LNode  *ALVNode
	RNode  *ALVNode
	Height int16
}

// PreorderTraversal preorder traver
func PreorderTraversal(root *ALVNode) []int32 {
	var list []int32
	if root.LNode != nil {
		list = append(list, PreorderTraversal(root.LNode)...)
	}
	list = append(list, root.Data)
	if root.RNode != nil {
		list = append(list, PreorderTraversal(root.RNode)...)
	}
	return list
}

// Insert insert node in alv tree
func Insert(data int32, root *ALVNode) *ALVNode {
	if root == nil {
		return &ALVNode{
			Data:   data,
			LNode:  nil,
			RNode:  nil,
			Height: 0,
		}
	}

	if data < root.Data {
		root.LNode = Insert(data, root.LNode)
		root.setHeight()
		rootBF := root.getNodeBF()
		lNodeBF := root.LNode.getNodeBF()
		if math.Abs(float64(rootBF)) > 1 {
			sumBF := rootBF + lNodeBF
			if sumBF > 2 || sumBF < -2 {
				if rootBF > 0 {
					root = rightRotate(root)
				} else {
					root = leftRotate(root)
				}
			} else {
				if rootBF > 0 {
					root.LNode = leftRotate(root.LNode)
					root = rightRotate(root)
				} else {
					root.LNode = rightRotate(root.LNode)
					root = leftRotate(root)
				}
			}
		}
	}
	if data > root.Data {
		root.RNode = Insert(data, root.RNode)
		rootBF := root.getNodeBF()
		rNodeBF := root.RNode.getNodeBF()
		if math.Abs(float64(rootBF)) > 1 {
			sumBF := rootBF + rNodeBF
			if sumBF > 2 || sumBF < -2 {
				if rootBF > 0 {
					root = rightRotate(root)
				} else {
					root = leftRotate(root)
				}
			} else {
				if rootBF > 0 {
					root.RNode = leftRotate(root.RNode)
					root = rightRotate(root)
				} else {
					root.RNode = rightRotate(root.RNode)
					root = leftRotate(root)
				}
			}
		}
	}

	root.setHeight()
	return root
}

func (n *ALVNode) getNodeBF() int16 {
	var l, r int16
	if n.LNode == nil {
		l = -1
	} else {
		l = n.LNode.Height
	}
	if n.RNode == nil {
		r = -1
	} else {
		r = n.RNode.Height
	}
	return l - r
}

func rightRotate(node *ALVNode) *ALVNode {
	var newNode *ALVNode

	newNode = node.LNode
	node.LNode = newNode.RNode
	newNode.RNode = node

	node.setHeight()
	newNode.setHeight()

	return newNode
}

func leftRotate(node *ALVNode) *ALVNode {
	var newNode *ALVNode

	newNode = node.RNode
	node.RNode = newNode.LNode
	newNode.LNode = node

	node.setHeight()
	newNode.setHeight()

	return newNode
}

func (n *ALVNode) setHeight() {
	if n.LNode == nil && n.RNode == nil {
		n.Height = 0
	} else if n.LNode == nil {
		n.Height = n.RNode.Height + 1
	} else if n.RNode == nil {
		n.Height = n.LNode.Height + 1
	} else {
		n.Height = int16(math.Max(float64(n.LNode.Height), float64(n.RNode.Height))) + 1
	}
}

repository: TedForV/goutil

license_type: permissive

repo_name: TedForV/goutil

branch_name: refs/heads/master

gha_license_id: MIT

gha_language: Go

extension: go


text:
#include "configuration.hpp"
#include "filesystem/path.h"
#include <cmath>
#include <cstdlib>
#include <sstream>
#include <fstream>

namespace mctl
{
    // Configuration public methods
    // ----------------------------------------------------------------------------------
    Configuration::Configuration()
    {
        homing_enabled_map_ = DefaultHomingEnabledMap;
        homing_backoff_map_ = DefaultHomingBackoffMap;
        axis_to_unit_map_ = DefaultAxisToUnitMap;
        axis_to_unit_conversion_map_ = DefaultAxisToUnitConversionMap;

        gain_ = DefaultGain;
        outscan_start_delay_ = DefaultOutscanStartDelay_ms;
        outscan_num_bias_samples_ = DefaultOutscanNumBiasSamples;

        analog_input_scale_ = DefaultAnalogInputScale;
        analog_input_offset_ = DefaultAnalogInputOffset;
        analog_input_unit_ = DefaultAnalogInputUnit;

        config_dir_ = std::string("");
        config_file_ = std::string("");

        joystick_device_ = DefaultJoystickDevice;
        axis_to_joystick_map_ = DefaultAxisToJoystickMap;
        axis_to_joystick_invert_map_ = DefaultAxisToJoystickInvertMap;
        axis_to_joystick_speed_map_ = DefaultAxisToJoystickSpeedMap;

        for (auto stepper : StepperList)
        {
            min_position_map_[stepper] = DefaultStepperMinimumPosition[stepper];
            max_position_map_[stepper] = DefaultStepperMaximumPosition[stepper];
            max_speed_map_[stepper] = DefaultStepperMaximumSpeed[stepper];
            max_accel_map_[stepper] = DefaultStepperMaximumAccel[stepper];
            homing_direction_map_[stepper] = DefaultStepperHomingDirection[stepper];
        }
    }

    RtnStatus Configuration::load()
    {
        std::ostringstream path_oss;
        path_oss << std::getenv("HOME") << filesep() ;
        path_oss << DefaultConfigurationDir << filesep();
        path_oss << DefaultConfigurationFile;
        return load(path_oss.str());
    }

    RtnStatus Configuration::load(std::string filename)
    {
        RtnStatus rtn_status;

        std::ifstream config_ifs;
        rtn_status = get_config_file_ifstream(filename, config_ifs);
        if (!rtn_status.success())
        {
            return rtn_status;
        }

        json config_json;
        try
        {
            config_ifs >> config_json;
        }
        catch (std::invalid_argument &err)
        {
            std::ostringstream oss;
            oss << "error: unable to load configuration, " << err.what();
            rtn_status.set_success(false);
            rtn_status.set_error_msg(oss.str());
            return rtn_status;
        }

        filesystem::path config_path(filename);
        config_dir_  = config_path.parent_path().str();
        config_file_ = config_path.str();

        rtn_status = load(config_json);
        if (!rtn_status.success())
        {
            config_dir_ = std::string("");
            config_file_ = std::string("");
        }
        return rtn_status;
    }

    RtnStatus Configuration::load(json config_json)
    {
        RtnStatus rtn_status;

        if (!config_json.is_object())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: json configuration root must be object");
            return rtn_status;
        }

        rtn_status = load_homing_enabled(config_json);
        if (!rtn_status.success())
        {
            return rtn_status;
        }

        rtn_status = load_outscan_config(config_json);
        if (!rtn_status.success())
        {
            return rtn_status;
        }

        rtn_status = load_ft_sensor_cal(config_json);
        if (!rtn_status.success())
        {
            return rtn_status;
        }

        rtn_status = load_min_position(config_json);
        if (!rtn_status.success())
        {
            return rtn_status;
        }

        rtn_status = load_max_position(config_json);
        if (!rtn_status.success())
        {
            return rtn_status;
        }

        rtn_status = load_home_direction(config_json);
        if (!rtn_status.success())
        {
            return rtn_status;
        }

        rtn_status = load_max_speed(config_json);
        if (!rtn_status.success())
        {
            return rtn_status;
        }

        rtn_status = load_max_accel(config_json);
        if (!rtn_status.success())
        {
            return rtn_status;
        }

        rtn_status = load_outscan_config(config_json);
        if (!rtn_status.success())
        {
            return rtn_status;
        }

        rtn_status = load_gain(config_json);
        if (!rtn_status.success())
        {
            return rtn_status;
        }

        rtn_status = load_axis_to_unit_conversion(config_json);
        if (!rtn_status.success())
        {
            return rtn_status;
        }

        rtn_status = load_joystick_config(config_json);

        return rtn_status;
    }

    std::string Configuration::file()
    {
        return config_file_;
    }

    std::string Configuration::dir()
    {
        return config_dir_;
    }

    std::string Configuration::file_contents()
    {
        std::stringstream ss;

        std::ifstream config_ifs;
        RtnStatus rtn_status = get_config_file_ifstream(config_file_, config_ifs);
        if (rtn_status.success())
        {
            std::string line;
            while (std::getline(config_ifs,line))
            {
                ss << line << std::endl;
            }
        }
        return ss.str();
    }

    std::string Configuration::info_string()
    {
        std::string pad(" ");
        std::stringstream ss;
        ss << std::setprecision(8) << std::fixed;

        ss << "axis units: " << std::endl;
        for (auto kv : axis_to_unit_map_)
        {
            std::string name = AxisToStringMap[kv.first];
            std::string unit = UnitToStringMap[kv.second];
            ss << pad << name << " = " << unit << std::endl;
        }

        ss << std::endl;
        ss << "axis to unit conversion: " << std::endl;
        for (auto kv : axis_to_unit_conversion_map_)
        {
            std::string name = AxisToStringMap[kv.first];
            ss << pad << name << " = " << kv.second << std::endl;
        }

        ss << std::endl;
        ss << "homing enabled: " << std::endl;
        ss << std::boolalpha;
        for (auto kv : homing_enabled_map_)
        {
            std::string name = AxisToStringMap[kv.first];
            ss << pad << name << " = " << kv.second << std::endl;
        }
        ss << std::noboolalpha;

        ss << std::endl;
        ss << "homing backoff: " << std::endl;
        for (auto kv : homing_backoff_map_)
        {
            std::string name = AxisToStringMap[kv.first];
            ss << pad << name << " = " << kv.second << std::endl;
        }

        ss << std::endl;
        ss << "min position: " << std::endl;
        for (auto kv : min_position_map_)
        {
            std::string name = AxisToStringMap[kv.first];
            ss << pad << name << " = " << kv.second << std::endl;
        }

        ss << std::endl;
        ss << "max position: " << std::endl;
        for (auto kv : max_position_map_)
        {
            std::string name = AxisToStringMap[kv.first];
            ss << pad << name << " = " << kv.second << std::endl;
        }

        ss << std::endl;
        ss << "home direction: " << std::endl;
        for (auto kv : homing_direction_map_)
        {
            std::string name = AxisToStringMap[kv.first];
            ss << pad << name << " = " << kv.second << std::endl;
        }

        ss << std::endl;
        ss << "max speed: " << std::endl;
        for (auto kv : max_speed_map_)
        {
            std::string name = AxisToStringMap[kv.first];
            ss << pad << name << " = " << kv.second << std::endl;
        }

        ss << std::endl;
        ss << "max accel: " << std::endl;
        for (auto kv : max_accel_map_)
        {
            std::string name = AxisToStringMap[kv.first];
            ss << pad << name << " = " << kv.second << std::endl;
        }

        ss << std::endl;
        ss << "axis to joystick map:" << std::endl;
        for (auto kv : axis_to_joystick_map_)
        {
            if (kv.second >= 0)
            {
                std::string name = AxisToStringMap[kv.first];
                ss << pad << name << " = " << kv.second << std::endl;
            }
        }

        ss << std::endl;
        ss << "axis to joystick invert map:" << std::endl;
        ss << std::boolalpha;
        for (auto kv : axis_to_joystick_invert_map_)
        {
            if (axis_to_joystick_map_[kv.first] >= 0)
            {
                std::string name = AxisToStringMap[kv.first];
                ss << pad << name << " = " << kv.second << std::endl;
            }
        }
        ss << std::noboolalpha;

        ss << std::endl;
        ss << "axis to joystick speed map:" << std::endl;
        for (auto kv : axis_to_joystick_speed_map_)
        {
            if (axis_to_joystick_map_[kv.first] >= 0)
            {
                std::string name = AxisToStringMap[kv.first];
                ss << pad << name << " = " << kv.second << std::endl;
            }
        }

        ss << std::endl;
        ss << "config file:             " << config_file_ << std::endl;
        std::string ft_cal_file;
        RtnStatus rtn_status = ft_sensor_cal_.get_filename(ft_cal_file);
        ss << "ft_calibration:          ";
        if (rtn_status.success())
        {
            ss << ft_cal_file;
        }
        else
        {
            ss << "none";
        }
        ss << std::endl;
        ss << "joystick device:         " << joystick_device_ << std::endl;
        ss << "outscan start delay:     " << outscan_start_delay_ << " (ms)" << std::endl;
        ss << "outscan # bias samples:  " << outscan_num_bias_samples_ << std::endl;
        ss << "gain:                    " << gain_ << std::endl;
        return ss.str();
    }

    // Configuration protected methods
    // ----------------------------------------------------------------------------------
    bool Configuration::homing_enabled(Axis axis)
    {
        bool rval = false;
        if (homing_enabled_map_.count(axis) > 0)
        {
            rval = homing_enabled_map_[axis];
        }
        return rval;
    }

    void Configuration::set_homing_enabled(Axis axis, bool value)
    {
        if (homing_enabled_map_.count(axis) > 0)
        {
            homing_enabled_map_[axis] = value;
        }
    }

    Unit Configuration::axis_unit(Axis axis)
    {
        Unit unit = NoUnit;
        if (axis_to_unit_map_.count(axis) > 0)
        {
            unit = axis_to_unit_map_[axis];
        }
        return unit;
    }

    void Configuration::set_axis_unit(Axis axis, Unit unit)
    {
        if (axis_to_unit_map_.count(axis) > 0)
        {
            axis_to_unit_map_[axis] = unit;
        }
    }

    std::string Configuration::axis_unit_string(Axis axis)
    {
        Unit unit = axis_unit(axis);
        return unit_to_string(unit);
    }

    std::string Configuration::axis_name(Axis axis)
    {
        std::string name = axis_to_string(axis);
        return name;
    }

    double Configuration::axis_conversion(Axis axis)
    {
        double value = 1.0;
        if (axis_to_unit_conversion_map_.count(axis) > 0)
        {
            value = axis_to_unit_conversion_map_[axis];
        }
        return value;
    }

    Unit Configuration::analog_input_unit()
    {
        return analog_input_unit_;
    }

    void Configuration::set_analog_input_unit(Unit unit)
    {
        analog_input_unit_ = unit;
    }

    std::string Configuration::analog_input_unit_string()
    {
        return unit_to_string(analog_input_unit_);
    }

    double Configuration::axis_conversion_inv(Axis axis)
    {
        double scale_fact = axis_conversion(axis);
        double scale_fact_inv = 1.0;
        if (scale_fact > 0.0)
        {
            scale_fact_inv = 1.0/scale_fact;
        }
        return scale_fact_inv;
    }

    void Configuration::set_axis_conversion(Axis axis, double value)
    {
        if (axis_to_unit_conversion_map_.count(axis) > 0)
        {
            axis_to_unit_conversion_map_[axis] = value;
        }
    }

    double Configuration::index_to_unit(Axis axis, int32_t index)
    {
        return axis_conversion(axis)*index;
    }

    std::vector<double> Configuration::index_to_unit(std::vector<int32_t> index_vec)
    {
        std::vector<double> value_vec(index_vec.size());
        for (int i=0; i<index_vec.size(); i++)
        {
            value_vec[i] = index_to_unit(Axis(i),index_vec[i]);
        }
        return value_vec;
    }

    std::map<Axis,double> Configuration::index_to_unit(std::map<Axis,int32_t> index_map)
    {
        std::map<Axis,double> value_map;
        for (auto kv : index_map)
        {
            double value = index_to_unit(kv.first,kv.second);
            std::pair<Axis,double> kv_new(kv.first,value);
            value_map.insert(kv_new);
        }
        return value_map;
    }

    arma::Row<double> Configuration::index_to_unit(arma::Row<int32_t> index_vec)
    {
        arma::Row<double> value_vec(index_vec.size());
        for (int i=0; i<index_vec.size(); i++)
        {
            value_vec(i) = index_to_unit(Axis(i),index_vec(i));
        }
        return value_vec;
    }

    arma::Mat<double> Configuration::index_to_unit(arma::Mat<int32_t> index_mat)
    {
        arma::Mat<double> value_mat = arma::conv_to<arma::Mat<double>>::from(index_mat);
        for (int i=0; i<value_mat.n_cols; i++)
        {
            value_mat.col(i) = axis_conversion(Axis(i))*value_mat.col(i);
        }
        return value_mat;
    }

    int32_t Configuration::unit_to_index(Axis axis, double  value)
    {
        return int32_t(axis_conversion_inv(axis)*value);
    }

    std::vector<int32_t> Configuration::unit_to_index(std::vector<double> value_vec)
    {
        std::vector<int32_t> index_vec(value_vec.size());
        for (int i=0; i<value_vec.size(); i++)
        {
            index_vec[i] = unit_to_index(Axis(i),value_vec[i]);
        }
        return index_vec;
    }

    std::map<Axis,int32_t> Configuration::unit_to_index(std::map<Axis,double> value_map)
    {
        std::map<Axis,int32_t> index_map;
        for (auto kv : value_map)
        {
            int32_t index = unit_to_index(kv.first,kv.second);
            std::pair<Axis,int32_t> kv_new(kv.first,index);
            index_map.insert(kv_new);
        }
        return index_map;
    }

    arma::Row<int32_t> Configuration::unit_to_index(arma::Row<double> index_vec)
    {
        arma::Row<int32_t> value_vec(index_vec.size());
        for (int i=0; i<index_vec.size(); i++)
        {
            value_vec(i) = unit_to_index(Axis(i),index_vec(i));
        }
        return value_vec;
    }

    arma::Mat<int32_t> Configuration::unit_to_index(arma::Mat<double> value_mat)
    {
        arma::Mat<int32_t> index_mat(value_mat.n_rows,value_mat.n_cols);
        for (int i=0; i<index_mat.n_cols; i++)
        {
            arma::Col<double> index_col_dbl = axis_conversion_inv(Axis(i))*value_mat.col(i);
            index_mat.col(i) = arma::conv_to<arma::Mat<int32_t>>::from(index_col_dbl);
        }
        return index_mat;
    }

    double Configuration::analog_int_to_volt(uint16_t value_int)
    {
        return analog_input_scale_*value_int + analog_input_offset_;
    }

    std::vector<double> Configuration::analog_int_to_volt(std::vector<uint16_t> int_vec)
    {
        std::vector<double> volt_vec(int_vec.size());
        for (int i=0; i<volt_vec.size(); i++)
        {
            volt_vec[i] = analog_int_to_volt(int_vec[i]);
        }
        return volt_vec;
    }

    arma::Row<double> Configuration::analog_int_to_volt(arma::Row<uint16_t> int_vec)
    {
        arma::Row<double> volt_vec(int_vec.size());
        for (int i=0; i<volt_vec.size(); i++)
        {
            volt_vec(i) = analog_int_to_volt(int_vec(i));
        }
        return volt_vec;
    }

    arma::Mat<double> Configuration::analog_int_to_volt(arma::Mat<uint16_t> int_mat)
    {
        arma::Mat<double> volt_mat(int_mat.n_rows, int_mat.n_cols);
        for (int i=0;i<volt_mat.n_rows; i++)
        {
            for (int j=0; j<volt_mat.n_cols; i++)
            {
                volt_mat(i,j) = analog_int_to_volt(int_mat(i,j));
            }
        }
        return volt_mat;
    }

    uint16_t Configuration::analog_volt_to_int(double value_volt)
    {
        return uint16_t((value_volt - analog_input_offset_)/analog_input_scale_);
    }

    std::vector<uint16_t> Configuration::analog_volt_to_int(std::vector<double> volt_vec)
    {
        std::vector<uint16_t> int_vec(volt_vec.size());
        for (int i=0; i<int_vec.size(); i++)
        {
            int_vec[i] = analog_volt_to_int(volt_vec[i]);
        }
        return int_vec;
    }

    arma::Row<uint16_t> Configuration::analog_volt_to_int(arma::Row<double> volt_vec)
    {
        arma::Row<uint16_t> int_vec(volt_vec.size());
        for (int i=0; i<int_vec.size(); i++)
        {
            int_vec(i) = analog_volt_to_int(volt_vec(i));
        }
        return int_vec;
    }

    arma::Mat<uint16_t> Configuration::analog_volt_to_int(arma::Mat<double> volt_mat)
    {
        arma::Mat<uint16_t> int_mat(volt_mat.n_rows,volt_mat.n_cols);
        for (int i=0; i<int_mat.n_rows; i++)
        {
            for (int j=0; j<int_mat.n_cols; j++)
            {
                int_mat(i,j) = analog_volt_to_int(volt_mat(i,j));
            }
        }
        return int_mat;
    }

    bool Configuration::have_ft_sensor_cal()
    {
        return ft_sensor_cal_.is_initialized();
    }

    std::string Configuration::ft_sensor_cal_info()
    {
        std::string info;
        RtnStatus rtn_status = ft_sensor_cal_.get_info_string(info);
        if (!rtn_status.success())
        {
            info = std::string("ft_senosr_cal: none");
        }
        return info;
    }

    RtnStatus Configuration::get_force_and_torque_units(std::vector<std::string> &units_vec)
    {
        return ft_sensor_cal_.get_units(units_vec);
    }

    RtnStatus Configuration::get_force_and_torque(std::vector<double> ain_vec, std::vector<double> &ft_vec)
    {
        RtnStatus rtn_status;
        if (ain_vec.size() < FT_SensorCal::AinVectorSize)
        {
            std::ostringstream oss;
            oss << "error:  analog input vector size must >= " << FT_SensorCal::AinVectorSize;
            rtn_status.set_success(false);
            rtn_status.set_error_msg(oss.str());
        }
        else
        {
            rtn_status = ft_sensor_cal_.convert(ain_vec, ft_vec);
        }

        if (!rtn_status.success())
        {
            ft_vec = std::vector<double>(FT_SensorCal::FT_VectorSize,0.0); // fill with zeros
        }
        return rtn_status;
    }

    RtnStatus Configuration::get_force_and_torque(arma::Row<double> ain_vec, arma::Row<double> &ft_vec)
    {
        RtnStatus rtn_status;
        if (ain_vec.size() < FT_SensorCal::AinVectorSize)
        {
            std::ostringstream oss;
            oss << "error:  analog input vector size must >= " << FT_SensorCal::AinVectorSize;
            rtn_status.set_success(false);
            rtn_status.set_error_msg(oss.str());
        }
        else
        {
            rtn_status = ft_sensor_cal_.convert(ain_vec,ft_vec);
        }
        if (!rtn_status.success())
        {
            ft_vec = arma::Row<double>(FT_SensorCal::FT_VectorSize,arma::fill::zeros); // fill with zeros
        }
        return rtn_status;
    }

    RtnStatus Configuration::get_force_and_torque(arma::Mat<double> ain_mat, arma::Mat<double> &ft_mat)
    {
        RtnStatus rtn_status;
        if (ain_mat.n_cols < FT_SensorCal::AinVectorSize)
        {
            std::ostringstream oss;
            oss << "error:  analog input matrix n_cols must >= " << FT_SensorCal::AinVectorSize;
            rtn_status.set_success(false);
            rtn_status.set_error_msg(oss.str());
        }
        else
        {
            rtn_status = ft_sensor_cal_.convert(ain_mat,ft_mat);
        }
        if (!rtn_status.success())
        {
            ft_mat = arma::Mat<double>(ain_mat.n_rows,FT_SensorCal::FT_VectorSize,arma::fill::zeros);
        }
        return rtn_status;
    }

    // -------------------------------------------------------------------------

    double Configuration::homing_backoff(Axis axis)
    {
        double backoff = 0.0;
        double direction = 1.0;

        if (homing_backoff_map_.count(axis) > 0)
        {
            backoff = homing_backoff_map_[axis];
        }

        if (axis < NumStepper)
        {
            if (homing_direction_map_[axis] > 0)
            {
                direction = -1.0;
            }
        }
        return direction*backoff;
    }

    void Configuration::set_homing_backoff(Axis axis, double value)
    {
        if (homing_backoff_map_.count(axis) > 0)
        {
            homing_backoff_map_[axis] = fabs(value);
        }
    }

    int32_t Configuration::gain()
    {
        return gain_;
    }

    void Configuration::set_gain(int32_t gain)
    {
        gain_ = gain;
    }

    int Configuration::outscan_start_delay()
    {
        return outscan_start_delay_;
    }

    void Configuration::set_outscan_start_delay(int value)
    {
        outscan_start_delay_ = value;
    }

    int Configuration::outscan_num_bias_samples()
    {
        return outscan_num_bias_samples_;
    }

    void Configuration::set_outscan_num_bias_samples(int value)
    {
        outscan_num_bias_samples_ = value;
    }

    double Configuration::analog_input_scale()
    {
        return analog_input_scale_;
    }

    void Configuration::set_analog_input_scale(double value)
    {
        analog_input_scale_ = value;
    }

    double Configuration::analog_input_offset()
    {
        return analog_input_offset_;
    }

    void Configuration::set_analog_input_offset(double value)
    {
        analog_input_offset_ = value;
    }

    std::map<Axis,double> Configuration::min_position_map()
    {
        return min_position_map_;
    }

    std::map<Axis,double> Configuration::max_position_map()
    {
        return max_position_map_;
    }

    std::map<Axis,double> Configuration::max_speed_map()
    {
        return max_speed_map_;
    }

    std::map<Axis,double> Configuration::max_accel_map()
    {
        return max_accel_map_;
    }

    std::map<Axis,int> Configuration::homing_direction_map()
    {
        return homing_direction_map_;
    }

    std::string Configuration::joystick_device()
    {
        return joystick_device_;
    }

    std::map<Axis,int> Configuration::axis_to_joystick_map()
    {
        return axis_to_joystick_map_;
    }

    std::map<Axis,bool> Configuration::axis_to_joystick_invert_map()
    {
        return axis_to_joystick_invert_map_;
    }

    std::map<Axis,double> Configuration::axis_to_joystick_speed_map()
    {
        return axis_to_joystick_speed_map_;
    }

    // Protected methods
    // --------------------------------------------------------------------------------------
    RtnStatus Configuration::load_homing_enabled(json config_json)
    {
        RtnStatus rtn_status;
        if (!config_json.is_object())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: json configuration root must be object");
            return rtn_status;
        }

        if (!config_json.count("homing_enabled"))
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: json configuration does not contain homing_enabled");
            return rtn_status;
        }

        json enabled_json = config_json["homing_enabled"];
        if (!enabled_json.is_object())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: json configuration homing_enabled is not object");
            return rtn_status;
        }

        for (auto axis : StepperList)
        {
            std::string axis_name = AxisToStringMap[axis];
            if (!enabled_json.count(axis_name))
            {
                std::ostringstream oss;
                oss << "error: json configuration homing_enabled missing " << axis_name << " axis";
                rtn_status.set_success(false);
                rtn_status.set_error_msg(oss.str());
                return rtn_status;
            }
            if (!enabled_json[axis_name].is_boolean())
            {
                std::ostringstream oss;
                oss << "error: json configuration homing_enabled " << axis_name << " axis is not boolean";
                rtn_status.set_success(false);
                rtn_status.set_error_msg(oss.str());
                return rtn_status;
            }
            homing_enabled_map_[axis] = enabled_json[axis_name];
        }
        return rtn_status;
    }

    RtnStatus Configuration::load_ft_sensor_cal(json config_json)
    {
        RtnStatus rtn_status;
        if (!config_json.is_object())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: json configuration root must be object");
            return rtn_status;
        }

        if (!config_json.count("ft_calibration"))
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: configuration does not contain ft_calibration");
            return rtn_status;
        }
        if (!config_json["ft_calibration"].is_string())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: ft_calibration must be string");
            return rtn_status;
        }

        std::string ft_calibration_file = config_json["ft_calibration"];
        std::ostringstream cal_file_oss;
        cal_file_oss << config_dir_ << filesep() << ft_calibration_file;
        rtn_status = ft_sensor_cal_.load(cal_file_oss.str());
        return rtn_status;
    }

    RtnStatus Configuration::load_min_position(json config_json)
    {
        return load_stepper_values(config_json,"min_position", min_position_map_);
    }

    RtnStatus Configuration::load_max_position(json config_json)
    {
        return load_stepper_values(config_json,"max_position",max_position_map_);
    }

    RtnStatus Configuration::load_home_direction(json config_json)
    {
        std::map<Axis,double> map_tmp;
        RtnStatus rtn_status = load_stepper_values(config_json,"home_direction", map_tmp);
        if (rtn_status.success())
        {
            for (auto kv : map_tmp)
            {
                if (kv.second == 0)
                {
                    rtn_status.set_success(false);
                    rtn_status.set_error_msg("error: home direction must be nonzero");
                    return rtn_status;
                }
            }

            homing_direction_map_.clear();
            for (auto kv : map_tmp)
            {
                if (kv.second > 0)
                {
                    homing_direction_map_.emplace(kv.first,1);
                }
                else
                {
                    homing_direction_map_.emplace(kv.first,-1);
                }
            }
        }
        return rtn_status;
    }

    RtnStatus Configuration::load_max_speed(json config_json)
    {
        return load_stepper_values(config_json,"max_speed", max_speed_map_);
    }

    RtnStatus Configuration::load_max_accel(json config_json)
    {
        return load_stepper_values(config_json,"max_accel", max_accel_map_);
    }

    RtnStatus Configuration::load_stepper_values(json config_json, std::string key, std::map<Axis,double> &value_map)
    {
        RtnStatus rtn_status;
        if (!config_json.is_object())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: json configuration root must be object");
            return rtn_status;
        }

        if (config_json.count(key))
        {
            value_map.clear();
            json key_json = config_json[key];
            for (auto stepper : StepperList)
            {
                std::string stepper_name = AxisToStringMap[stepper];
                if (key_json.count(stepper_name))
                {
                    if (key_json[stepper_name].is_number())
                    {
                        double value = key_json[stepper_name];
                        value_map.emplace(stepper, value);
                    }
                    else
                    {
                        std::ostringstream oss;
                        oss << "error: " << stepper_name << " value for " << key << " is not a number";
                        rtn_status.set_success(false);
                        rtn_status.set_error_msg(oss.str());
                        break;
                    }
                }
            }
        }
        return rtn_status;
    }

    RtnStatus Configuration::load_axis_values(json config_json, std::string key, std::map<Axis,double> &value_map)
    {
        RtnStatus rtn_status;
        if (!config_json.is_object())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: json configuration root must be object");
            return rtn_status;
        }

        if (config_json.count(key))
        {
            value_map.clear();
            json key_json = config_json[key];
            for (auto axis : AxisList)
            {
                std::string axis_name = AxisToStringMap[axis];
                if (key_json.count(axis_name))
                {
                    if (key_json[axis_name].is_number())
                    {
                        double value = key_json[axis_name];
                        value_map.emplace(axis, value);
                    }
                    else
                    {
                        std::ostringstream oss;
                        oss << "error: " << axis_name << " value for " << key << " is not a number";
                        rtn_status.set_success(false);
                        rtn_status.set_error_msg(oss.str());
                        break;
                    }
                }
            }
        }
        return rtn_status;
    }

    RtnStatus Configuration::load_outscan_config(json config_json)
    {
        RtnStatus rtn_status;
        if (!config_json.is_object())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: json configuration root must be object");
            return rtn_status;
        }
        if (config_json.count("outscan"))
        {
            if (!config_json.is_object())
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: json configuration outscan must be object");
                return rtn_status;
            }

            json outscan_json = config_json["outscan"];

            // Get start delay
            if (!outscan_json.count("start_delay_ms"))
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: json configuration outscan must contian start_delay");
                return rtn_status;
            }
            if (!outscan_json["start_delay_ms"].is_number())
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: json configuration outscan start_delay_ms must be number");
                return rtn_status;
            }
            int start_delay_tmp = int(outscan_json["start_delay_ms"]);
            if (start_delay_tmp < 0)
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: json configuration outscan start_delay_ms must be >=0");
                return rtn_status;
            }
            outscan_start_delay_ = start_delay_tmp;

            // get number of bias samples
            if(!outscan_json.count("num_bias_samples"))
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: json configuration outscan must contain num_bias_samples");
                return rtn_status;
            }
            if (!outscan_json["num_bias_samples"].is_number())
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: json configuration outscan num_bias_samples must be number");
                return rtn_status;
            }
            int num_bias_samples_tmp = int(outscan_json["num_bias_samples"]);
            if (num_bias_samples_tmp < 0)
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: json configuration outscan bias_samples must be >=0");
                return rtn_status;
            }
            outscan_num_bias_samples_ = num_bias_samples_tmp;
        }
        return rtn_status;
    }

    RtnStatus Configuration::load_joystick_config(json config_json)
    {
        RtnStatus rtn_status;
        if (!config_json.is_object())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: json configuration root must be object");
            return rtn_status;
        }
        if (config_json.count("joystick"))
        {
            json joy_json = config_json["joystick"];

            // Get device string
            if (!joy_json.count("device"))
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: joystick device not specified");
                return rtn_status;
            }
            if (!joy_json["device"].is_string())
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: joystick device is not string");
                return rtn_status;
            }
            joystick_device_ = joy_json["device"];

            // Get axis to joystick mapping
            if (!joy_json.count("mapping"))
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: axis to joystick mapping is missing ");
                return rtn_status;
            }

            json axis_map_json = joy_json["mapping"];
            if (!axis_map_json.is_object())
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: joystick mapping is not object");
                return rtn_status;
            }

            for (auto axis : AxisList)
            {
                std::string axis_name = AxisToStringMap[axis];
                if (axis_map_json.count(axis_name))
                {
                    if (!axis_map_json[axis_name].is_number())
                    {
                        rtn_status.set_success(false);
                        rtn_status.set_error_msg("error: axis to joystick map value must integer");
                        return rtn_status;
                    }
                    else
                    {
                        int value = int(axis_map_json[axis_name]);
                        if (value < 0)
                        {
                            axis_to_joystick_map_[axis] = -1;
                        }
                        else
                        {
                            axis_to_joystick_map_[axis] = value;
                        }
                    }
                }
                else
                {
                    axis_to_joystick_map_[axis] = -1;
                }
            }

            // Get joystick invert mapping
            if (!joy_json.count("invert"))
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: axis to joystick invert assignment is missing ");
                return rtn_status;
            }
            if (!joy_json["invert"].is_object())
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: joystick invert is not object");
                return rtn_status;
            }

            json invert_json = joy_json["invert"];
            for (auto axis : AxisList)
            {
                std::string axis_name = AxisToStringMap[axis];
                if (invert_json.count(axis_name))
                {
                    if (!invert_json[axis_name].is_boolean())
                    {
                        rtn_status.set_success(false);
                        rtn_status.set_error_msg("error: axis to joystick invert value must be boolean");
                        return rtn_status;
                    }
                    axis_to_joystick_invert_map_[axis] = bool(invert_json[axis_name]);
                }
                else
                {
                    axis_to_joystick_invert_map_[axis] = false;
                }
            }

            // Get joystick speed mapping
            if (!joy_json.count("speed"))
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: axis to joystick speed assignment is missing ");
                return rtn_status;
            }
            if (!joy_json["speed"].is_object())
            {
                rtn_status.set_success(false);
                rtn_status.set_error_msg("error: joystick speed is not object");
                return rtn_status;
            }

            json speed_json = joy_json["speed"];
            for (auto axis : AxisList)
            {
                std::string axis_name = AxisToStringMap[axis];
                if (speed_json.count(axis_name))
                {
                    if (!speed_json[axis_name].is_number())
                    {
                        rtn_status.set_success(false);
                        rtn_status.set_error_msg("error: axis to joystick speed value must be double ");
                        return rtn_status;
                    }
                    double speed = double(speed_json[axis_name]);
                    if (speed >= 0.0)
                    {
                        axis_to_joystick_speed_map_[axis] = double(speed_json[axis_name]);
                    }
                    else
                    {
                        rtn_status.set_success(false);
                        rtn_status.set_error_msg("error: joystick speed must be >= 0.0");
                        return rtn_status;
                    }
                }
                else
                {
                    axis_to_joystick_speed_map_[axis] = false;
                }
            }

        } // if (config_json.count("joystick"))
        return rtn_status;
    }

    RtnStatus Configuration::load_gain(json config_json)
    {
        RtnStatus rtn_status;

        if (!config_json.is_object())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: json configuration root must be object");
            return rtn_status;
        }

        if (!config_json.count("gain"))
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: configuration does not contain gain");
            return rtn_status;
        }

        if (!config_json["gain"].is_number())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: json configuration gain must be number");
            return rtn_status;
        }

        int gain_tmp = int(config_json["gain"]);
        if (gain_tmp < 0)
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: json configuration gain must be >=0");
            return rtn_status;
        }
        gain_ = gain_tmp;

        return rtn_status;
    }

    RtnStatus Configuration::load_axis_to_unit_conversion(json config_json)
    {
        RtnStatus rtn_status;
        rtn_status = load_axis_values(config_json,"axis_to_unit_conversion", axis_to_unit_conversion_map_);
        if (rtn_status.success())
        {
            for (auto kv : axis_to_unit_conversion_map_)
            {
                if (kv.second <= 0.0)
                {
                    rtn_status.set_success(false);
                    std::ostringstream oss;
                    oss << "error: axis to unit conversion for axis=";
                    oss << AxisToStringMap[kv.first] << " ";
                    oss << "must be > 0";
                    rtn_status.set_error_msg(oss.str());
                    break;
                }
            }
        }
        return rtn_status;
    }

    RtnStatus Configuration::get_config_file_ifstream(std::string filename, std::ifstream &config_ifs)
    {
        RtnStatus rtn_status;

        filesystem::path config_path(filename);

        // Check that configuration directory and file exist
        if (!config_path.parent_path().exists())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: configuration directory does not exist");
            return rtn_status;
        }

        if (!config_path.exists())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: configuration file does not exist");
            return rtn_status;

        }

        // Open configuration file and read json
        config_ifs.open(config_path.str(), std::ifstream::in);
        if (!config_ifs.is_open())
        {
            rtn_status.set_success(false);
            rtn_status.set_error_msg("error: unable to open configuration file");
            return rtn_status;
        }
        return rtn_status;
    }

    // Utility functions
    // ----------------------------------------------------------------------------------
    std::string operating_mode_to_string(OperatingMode mode)
    {
        if (OperatingModeToStringMap.count(mode) > 0)
        {
            return OperatingModeToStringMap[mode];
        }
        else
        {
            return std::string("mode not found");
        }
    }

    std::string axis_to_string(Axis axis)
    {
        if (AxisToStringMap.count(axis) > 0)
        {
            return AxisToStringMap[axis];
        }
        else
        {
            return std::string("axis not found");
        }
    }

    std::string unit_to_string(Unit unit)
    {
        if (UnitToStringMap.count(unit) > 0)
        {
            return UnitToStringMap[unit];
        }
        else
        {
            return std::string("unit not found");
        }
    }

    std::string filesep()
    {
#ifdef _WIN32
        return std::string("\\");
#else
        return std::string("/");
#endif
    }

}

extension: cpp


text:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE eagle SYSTEM "eagle.dtd">
<eagle version="6.5.0">
<drawing>
<settings>
<setting alwaysvectorfont="no"/>
<setting verticaltext="up"/>
</settings>
<grid distance="0.000000123031" unitdist="inch" unit="inch" style="lines" multiple="1" display="no" altdistance="0.000000123031" altunitdist="inch" altunit="inch"/>
<layers>
<layer number="1" name="Top" color="4" fill="1" visible="yes" active="yes"/>
<layer number="16" name="Bottom" color="1" fill="1" visible="yes" active="yes"/>
<layer number="17" name="Pads" color="2" fill="1" visible="yes" active="yes"/>
<layer number="18" name="Vias" color="2" fill="1" visible="yes" active="yes"/>
<layer number="19" name="Unrouted" color="6" fill="1" visible="yes" active="yes"/>
<layer number="20" name="Dimension" color="15" fill="1" visible="yes" active="yes"/>
<layer number="21" name="tPlace" color="7" fill="1" visible="yes" active="yes"/>
<layer number="22" name="bPlace" color="7" fill="1" visible="yes" active="yes"/>
<layer number="23" name="tOrigins" color="15" fill="1" visible="yes" active="yes"/>
<layer number="24" name="bOrigins" color="15" fill="1" visible="yes" active="yes"/>
<layer number="25" name="tNames" color="7" fill="1" visible="yes" active="yes"/>
<layer number="26" name="bNames" color="7" fill="1" visible="yes" active="yes"/>
<layer number="27" name="tValues" color="7" fill="1" visible="yes" active="yes"/>
<layer number="28" name="bValues" color="7" fill="1" visible="yes" active="yes"/>
<layer number="29" name="tStop" color="7" fill="3" visible="no" active="yes"/>
<layer number="30" name="bStop" color="7" fill="6" visible="no" active="yes"/>
<layer number="31" name="tCream" color="7" fill="4" visible="no" active="yes"/>
<layer number="32" name="bCream" color="7" fill="5" visible="no" active="yes"/>
<layer number="33" name="tFinish" color="6" fill="3" visible="no" active="yes"/>
<layer number="34" name="bFinish" color="6" fill="6" visible="no" active="yes"/>
<layer number="35" name="tGlue" color="7" fill="4" visible="no" active="yes"/>
<layer number="36" name="bGlue" color="7" fill="5" visible="no" active="yes"/>
<layer number="37" name="tTest" color="7" fill="1" visible="no" active="yes"/>
<layer number="38" name="bTest" color="7" fill="1" visible="no" active="yes"/>
<layer number="39" name="tKeepout" color="4" fill="11" visible="yes" active="yes"/>
<layer number="40" name="bKeepout" color="1" fill="11" visible="yes" active="yes"/>
<layer number="41" name="tRestrict" color="4" fill="10" visible="yes" active="yes"/>
<layer number="42" name="bRestrict" color="1" fill="10" visible="yes" active="yes"/>
<layer number="43" name="vRestrict" color="2" fill="10" visible="yes" active="yes"/>
<layer number="44" name="Drills" color="7" fill="1" visible="no" active="yes"/>
<layer number="45" name="Holes" color="7" fill="1" visible="no" active="yes"/>
<layer number="46" name="Milling" color="3" fill="1" visible="no" active="yes"/>
<layer number="47" name="Measures" color="7" fill="1" visible="no" active="yes"/>
<layer number="48" name="Document" color="7" fill="1" visible="yes" active="yes"/>
<layer number="49" name="Reference" color="7" fill="1" visible="yes" active="yes"/>
<layer number="50" name="dxf" color="7" fill="1" visible="no" active="no"/>
<layer number="51" name="tDocu" color="7" fill="1" visible="yes" active="yes"/>
<layer number="52" name="bDocu" color="7" fill="1" visible="yes" active="yes"/>
<layer number="53" name="tGND_GNDA" color="7" fill="9" visible="no" active="no"/>
<layer number="54" name="bGND_GNDA" color="1" fill="9" visible="no" active="no"/>
<layer number="56" name="wert" color="7" fill="1" visible="no" active="no"/>
<layer number="57" name="tCAD" color="7" fill="1" visible="no" active="no"/>
<layer number="59" name="tCarbon" color="7" fill="1" visible="no" active="no"/>
<layer number="60" name="bCarbon" color="7" fill="1" visible="no" active="no"/>
<layer number="90" name="Modules" color="5" fill="1" visible="yes" active="yes"/>
<layer number="91" name="Nets" color="2" fill="1" visible="no" active="no"/>
<layer number="92" name="Busses" color="1" fill="1" visible="no" active="no"/>
<layer number="93" name="Pins" color="2" fill="1" visible="no" active="no"/>
<layer number="94" name="Symbols" color="4" fill="1" visible="no" active="no"/>
<layer number="95" name="Names" color="7" fill="1" visible="no" active="no"/>
<layer number="96" name="Values" color="7" fill="1" visible="no" active="no"/>
<layer number="97" name="Info" color="7" fill="1" visible="no" active="no"/>
<layer number="98" name="Guide" color="6" fill="1" visible="no" active="no"/>
<layer number="99" name="SpiceOrder" color="7" fill="1" visible="no" active="no"/>
<layer number="100" name="Muster" color="7" fill="1" visible="no" active="no"/>
<layer number="101" name="Patch_Top" color="12" fill="4" visible="yes" active="yes"/>
<layer number="102" name="Vscore" color="7" fill="1" visible="yes" active="yes"/>
<layer number="103" name="fp3" color="7" fill="1" visible="no" active="yes"/>
<layer number="104" name="Name" color="7" fill="1" visible="yes" active="yes"/>
<layer number="105" name="Beschreib" color="9" fill="1" visible="yes" active="yes"/>
<layer number="106" name="BGA-Top" color="4" fill="1" visible="yes" active="yes"/>
<layer number="107" name="BD-Top" color="5" fill="1" visible="yes" active="yes"/>
<layer number="108" name="fp8" color="7" fill="1" visible="no" active="yes"/>
<layer number="109" name="fp9" color="7" fill="1" visible="no" active="yes"/>
<layer number="110" name="fp0" color="7" fill="1" visible="no" active="yes"/>
<layer number="111" name="LPC17xx" color="7" fill="1" visible="yes" active="yes"/>
<layer number="112" name="tSilk" color="7" fill="1" visible="yes" active="yes"/>
<layer number="113" name="IDFDebug" color="4" fill="1" visible="no" active="yes"/>
<layer number="116" name="Patch_BOT" color="9" fill="4" visible="yes" active="yes"/>
<layer number="118" name="Rect_Pads" color="7" fill="1" visible="yes" active="yes"/>
<layer number="121" name="_tsilk" color="7" fill="1" visible="yes" active="yes"/>
<layer number="122" name="_bsilk" color="7" fill="1" visible="yes" active="yes"/>
<layer number="123" name="tTestmark" color="7" fill="1" visible="no" active="yes"/>
<layer number="124" name="bTestmark" color="7" fill="1" visible="no" active="yes"/>
<layer number="125" name="_tNames" color="7" fill="1" visible="yes" active="yes"/>
<layer number="126" name="_bNames" color="7" fill="1" visible="yes" active="yes"/>
<layer number="127" name="_tValues" color="7" fill="1" visible="yes" active="yes"/>
<layer number="128" name="_bValues" color="7" fill="1" visible="yes" active="yes"/>
<layer number="129" name="Mask" color="7" fill="1" visible="yes" active="yes"/>
<layer number="131" name="tAdjust" color="7" fill="1" visible="no" active="yes"/>
<layer number="132" name="bAdjust" color="7" fill="1" visible="no" active="yes"/>
<layer number="144" name="Drill_legend" color="7" fill="1" visible="yes" active="yes"/>
<layer number="150" name="Notes" color="7" fill="1" visible="no" active="yes"/>
<layer number="151" name="HeatSink" color="7" fill="1" visible="yes" active="yes"/>
<layer number="152" name="_bDocu" color="7" fill="1" visible="yes" active="yes"/>
<layer number="153" name="FabDoc1" color="6" fill="1" visible="no" active="no"/>
<layer number="154" name="FabDoc2" color="2" fill="1" visible="no" active="no"/>
<layer number="155" name="FabDoc3" color="7" fill="15" visible="no" active="no"/>
<layer number="199" name="Contour" color="7" fill="1" visible="yes" active="yes"/>
<layer number="200" name="200bmp" color="1" fill="10" visible="yes" active="yes"/>
<layer number="201" name="201bmp" color="2" fill="1" visible="no" active="no"/>
<layer number="202" name="202bmp" color="3" fill="1" visible="no" active="no"/>
<layer number="203" name="203bmp" color="4" fill="10" visible="yes" active="yes"/>
<layer number="204" name="204bmp" color="5" fill="10" visible="yes" active="yes"/>
<layer number="205" name="205bmp" color="6" fill="10" visible="yes" active="yes"/>
<layer number="206" name="206bmp" color="7" fill="10" visible="yes" active="yes"/>
<layer number="207" name="207bmp" color="8" fill="10" visible="yes" active="yes"/>
<layer number="208" name="208bmp" color="9" fill="10" visible="yes" active="yes"/>
<layer number="209" name="209bmp" color="7" fill="1" visible="no" active="yes"/>
<layer number="210" name="210bmp" color="7" fill="1" visible="no" active="yes"/>
<layer number="211" name="211bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="212" name="212bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="213" name="213bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="214" name="214bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="215" name="215bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="216" name="216bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="217" name="217bmp" color="18" fill="1" visible="no" active="no"/>
<layer number="218" name="218bmp" color="19" fill="1" visible="no" active="no"/>
<layer number="219" name="219bmp" color="20" fill="1" visible="no" active="no"/>
<layer number="220" name="220bmp" color="21" fill="1" visible="no" active="no"/>
<layer number="221" name="221bmp" color="22" fill="1" visible="no" active="no"/>
<layer number="222" name="222bmp" color="23" fill="1" visible="no" active="no"/>
<layer number="223" name="223bmp" color="24" fill="1" visible="no" active="no"/>
<layer number="224" name="224bmp" color="25" fill="1" visible="no" active="no"/>
<layer number="225" name="225bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="226" name="226bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="227" name="227bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="228" name="228bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="229" name="229bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="230" name="230bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="231" name="231bmp" color="7" fill="1" visible="yes" active="yes"/>
<layer number="248" name="Housing" color="7" fill="1" visible="yes" active="yes"/>
<layer number="249" name="Edge" color="7" fill="1" visible="yes" active="yes"/>
<layer number="250" name="Descript" color="7" fill="1" visible="no" active="no"/>
<layer number="251" name="SMDround" color="7" fill="1" visible="no" active="no"/>
<layer number="254" name="cooling" color="7" fill="1" visible="yes" active="yes"/>
<layer number="255" name="routoute" color="7" fill="1" visible="yes" active="yes"/>
</layers>
<board>
<plain>
<wire x1="76.65699375" y1="67.220846875" x2="94.7181875" y2="67.231765625" width="0" layer="20"/>
<wire x1="94.7181875" y1="67.231765625" x2="94.716378125" y2="80.016825" width="0" layer="20"/>
<wire x1="94.716378125" y1="80.016825" x2="76.65699375" y2="80.025565625" width="0" layer="20"/>
<wire x1="76.65699375" y1="80.025565625" x2="76.65699375" y2="67.220846875" width="0" layer="20"/>
<text x="93.936471875" y="79.698971875" size="0.6096" layer="25" rot="R180">GND</text>
<text x="91.4152875" y="79.810303125" size="0.6096" layer="25" rot="R180">VGND</text>
<text x="86.409996875" y="74.225071875" size="0.6096" layer="25" rot="R180">VCH</text>
<text x="85.88303125" y="73.325659375" size="0.3048" layer="122" rot="MR0">Copyright (C) Roger J Parkinson
Connector for Beaglebone to Chime</text>
</plain>
<libraries>
<library name="adafruit">
<packages>
<package name="CHIP-LED0603">
<description>Hyper CHIPLED Hyper-Bright LED

LB Q993

Source: http://www.osram.convergy.de/ ... Lb_q993.pdf</description>
<wire x1="-0.4" y1="0.45" x2="-0.4" y2="-0.45" width="0.1016" layer="51"/>
<wire x1="0.4" y1="0.45" x2="0.4" y2="-0.45" width="0.1016" layer="51"/>
<smd name="C" x="0" y="0.75" dx="0.8" dy="0.8" layer="1"/>
<smd name="A" x="0" y="-0.75" dx="0.8" dy="0.8" layer="1"/>
<text x="-0.635" y="-0.635" size="1.27" layer="25" rot="R90">>NAME</text>
<text x="1.905" y="-0.635" size="1.27" layer="27" rot="R90">>VALUE</text>
<rectangle x1="-0.45" y1="0.45" x2="0.45" y2="0.85" layer="51"/>
<rectangle x1="-0.45" y1="-0.85" x2="0.45" y2="-0.45" layer="51"/>
<rectangle x1="-0.45" y1="0" x2="-0.3" y2="0.3" layer="21"/>
<rectangle x1="0.3" y1="0" x2="0.45" y2="0.3" layer="21"/>
<rectangle x1="-0.15" y1="0" x2="0.15" y2="0.3" layer="21"/>
</package>
<package name="R0603">
<description>RESISTOR

chip</description>
<wire x1="-0.432" y1="-0.356" x2="0.432" y2="-0.356" width="0.1524" layer="51"/>
<wire x1="0.432" y1="0.356" x2="-0.432" y2="0.356" width="0.1524" layer="51"/>
<wire x1="-1.473" y1="0.983" x2="1.473" y2="0.983" width="0.0508" layer="39"/>
<wire x1="1.473" y1="0.983" x2="1.473" y2="-0.983" width="0.0508" layer="39"/>
<wire x1="1.473" y1="-0.983" x2="-1.473" y2="-0.983" width="0.0508" layer="39"/>
<wire x1="-1.473" y1="-0.983" x2="-1.473" y2="0.983" width="0.0508" layer="39"/>
<smd name="1" x="-0.85" y="0" dx="1" dy="1.1" layer="1"/>
<smd name="2" x="0.85" y="0" dx="1" dy="1.1" layer="1"/>
<text x="-0.889" y="0.889" size="1.27" layer="25">>NAME</text>
<text x="-0.889" y="-2.032" size="1.27" layer="27">>VALUE</text>
<rectangle x1="0.4318" y1="-0.4318" x2="0.8382" y2="0.4318" layer="51"/>
<rectangle x1="-0.8382" y1="-0.4318" x2="-0.4318" y2="0.4318" layer="51"/>
<rectangle x1="-0.1999" y1="-0.4001" x2="0.1999" y2="0.4001" layer="35"/>
</package>
<package name="TO92-EBC-OVAL">
<description>TO-92

grid 5.08 mm</description>
<wire x1="-2.095" y1="-2.921" x2="2.095" y2="-2.921" width="0.127" layer="21"/>
<wire x1="-2.413" y1="-0.1341" x2="2.413" y2="-0.1341" width="0.127" layer="21" curve="-129.583345" cap="flat"/>
<wire x1="1.136" y1="-1.397" x2="-1.136" y2="-1.397" width="0.127" layer="51"/>
<wire x1="-2.413" y1="-0.1341" x2="-2.413" y2="-2.4059" width="0.127" layer="51" curve="50.416655" cap="flat"/>
<wire x1="-1.404" y1="-1.397" x2="-2.664" y2="-1.397" width="0.127" layer="51"/>
<wire x1="-2.4135" y1="-2.4059" x2="-2.095" y2="-2.921" width="0.127" layer="21" curve="13.038528" cap="flat"/>
<wire x1="-1.136" y1="-1.397" x2="-1.404" y2="-1.397" width="0.127" layer="21"/>
<wire x1="2.413" y1="-2.4059" x2="2.413" y2="-0.1341" width="0.127" layer="51" curve="50.416655" cap="flat"/>
<wire x1="2.664" y1="-1.397" x2="1.404" y2="-1.397" width="0.127" layer="51"/>
<wire x1="1.404" y1="-1.397" x2="1.136" y2="-1.397" width="0.127" layer="21"/>
<wire x1="2.095" y1="-2.921" x2="2.4247" y2="-2.3818" width="0.127" layer="21" curve="13.609443" cap="flat"/>
<pad name="E" x="-2.54" y="-1.27" drill="0.8128" shape="long" rot="R90"/>
<pad name="C" x="2.54" y="-1.27" drill="0.8128" shape="long" rot="R90"/>
<pad name="B" x="0" y="-1.27" drill="0.8128" shape="long" rot="R90"/>
<text x="-2.54" y="1.778" size="1.27" layer="25" ratio="10">>NAME</text>
<text x="-2.54" y="-4.572" size="1.27" layer="27" ratio="10">>VALUE</text>
</package>
</packages>
</library>
<library name="SparkFun-Connectors">
<description>
SparkFun Electronics' preferred foot prints

In this library you'll find connectors and sockets- basically anything that can be plugged into or onto.

We've spent an enormous amount of time creating and checking these footprints and parts, but it is the end user's responsibility to ensure correctness and suitablity for a given componet or application. If you enjoy using this library, please buy one of our products at www.sparkfun.com.

Licensing: Creative Commons ShareAlike 4.0 International - https://creativecommons.org/licenses/by-sa/4.0/

You are welcome to use this library for commercial purposes. For attribution, we ask that when you begin to sell your device using our footprint, you email us with a link to the product being sold. We want bragging rights that we helped (in a very small part) to create your 8th world wonder. We would like the opportunity to feature your device on our homepage.</description>
<packages>
<package name="1X06_NO_SILK_YES_STOP">
<pad name="1" x="0" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<pad name="2" x="2.54" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<pad name="3" x="5.08" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<pad name="4" x="7.62" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<pad name="5" x="10.16" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<pad name="6" x="12.7" y="0" drill="1.016" diameter="1.8796" rot="R90"/>
<text x="-1.3462" y="1.8288" size="1.27" layer="25" ratio="10">>NAME</text>
<text x="-1.27" y="-3.175" size="1.27" layer="27">>VALUE</text>
<rectangle x1="12.446" y1="-0.254" x2="12.954" y2="0.254" layer="51"/>
<rectangle x1="9.906" y1="-0.254" x2="10.414" y2="0.254" layer="51"/>
<rectangle x1="7.366" y1="-0.254" x2="7.874" y2="0.254" layer="51"/>
<rectangle x1="4.826" y1="-0.254" x2="5.334" y2="0.254" layer="51"/>
<rectangle x1="2.286" y1="-0.254" x2="2.794" y2="0.254" layer="51"/>
<rectangle x1="-0.254" y1="-0.254" x2="0.254" y2="0.254" layer="51"/>
</package>
</packages>
</library>
</libraries>
<attributes>
</attributes>
<variantdefs>
</variantdefs>
<classes>
<class number="0" name="default" width="0" drill="0">
</class>
</classes>
<designrules name="default">
<description language="de">EAGLE Design Rules

Die Standard-Design-Rules sind so gewählt, dass sie für
die meisten Anwendungen passen. Sollte ihre Platine
besondere Anforderungen haben, treffen Sie die erforderlichen
Einstellungen hier und speichern die Design Rules unter
einem neuen Namen ab.</description>
<description language="en">EAGLE Design Rules

The default Design Rules have been set to cover
a wide range of applications. Your particular design
may have different requirements, so please make the
necessary adjustments and save your customized
design rules under a new name.</description>
<param name="layerSetup" value="(1*16)"/>
<param name="mtCopper" value="0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm 0.035mm"/>
<param name="mtIsolate" value="1.5mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm 0.15mm 0.2mm"/>
<param name="mdWireWire" value="8mil"/>
<param name="mdWirePad" value="8mil"/>
<param name="mdWireVia" value="8mil"/>
<param name="mdPadPad" value="8mil"/>
<param name="mdPadVia" value="8mil"/>
<param name="mdViaVia" value="8mil"/>
<param name="mdSmdPad" value="8mil"/>
<param name="mdSmdVia" value="8mil"/>
<param name="mdSmdSmd" value="8mil"/>
<param name="mdViaViaSameLayer" value="8mil"/>
<param name="mnLayersViaInSmd" value="2"/>
<param name="mdCopperDimension" value="40mil"/>
<param name="mdDrill" value="8mil"/>
<param name="mdSmdStop" value="0mil"/>
<param name="msWidth" value="10mil"/>
<param name="msDrill" value="24mil"/>
<param name="msMicroVia" value="9.99mm"/>
<param name="msBlindViaRatio" value="0.5"/>
<param name="rvPadTop" value="0.25"/>
<param name="rvPadInner" value="0.25"/>
<param name="rvPadBottom" value="0.25"/>
<param name="rvViaOuter" value="0.25"/>
<param name="rvViaInner" value="0.25"/>
<param name="rvMicroViaOuter" value="0.25"/>
<param name="rvMicroViaInner" value="0.25"/>
<param name="rlMinPadTop" value="10mil"/>
<param name="rlMaxPadTop" value="20mil"/>
<param name="rlMinPadInner" value="10mil"/>
<param name="rlMaxPadInner" value="20mil"/>
<param name="rlMinPadBottom" value="10mil"/>
<param name="rlMaxPadBottom" value="20mil"/>
<param name="rlMinViaOuter" value="8mil"/>
<param name="rlMaxViaOuter" value="20mil"/>
<param name="rlMinViaInner" value="8mil"/>
<param name="rlMaxViaInner" value="20mil"/>
<param name="rlMinMicroViaOuter" value="4mil"/>
<param name="rlMaxMicroViaOuter" value="20mil"/>
<param name="rlMinMicroViaInner" value="4mil"/>
<param name="rlMaxMicroViaInner" value="20mil"/>
<param name="psTop" value="-1"/>
<param name="psBottom" value="-1"/>
<param name="psFirst" value="-1"/>
<param name="psElongationLong" value="100"/>
<param name="psElongationOffset" value="100"/>
<param name="mvStopFrame" value="1"/>
<param name="mvCreamFrame" value="0"/>
<param name="mlMinStopFrame" value="4mil"/>
<param name="mlMaxStopFrame" value="4mil"/>
<param name="mlMinCreamFrame" value="0mil"/>
<param name="mlMaxCreamFrame" value="0mil"/>
<param name="mlViaStopLimit" value="0mil"/>
<param name="srRoundness" value="0"/>
<param name="srMinRoundness" value="0mil"/>
<param name="srMaxRoundness" value="0mil"/>
<param name="slThermalIsolate" value="10mil"/>
<param name="slThermalsForVias" value="0"/>
<param name="dpMaxLengthDifference" value="10mm"/>
<param name="dpGapFactor" value="2.5"/>
<param name="checkGrid" value="0"/>
<param name="checkAngle" value="0"/>
<param name="checkFont" value="1"/>
<param name="checkRestrict" value="1"/>
<param name="useDiameter" value="13"/>
<param name="maxErrors" value="50"/>
</designrules>
<autorouter>
<pass name="Default">
<param name="RoutingGrid" value="3.93700787mil"/>
<param name="tpViaShape" value="round"/>
<param name="PrefDir.1" value="|"/>
<param name="PrefDir.2" value="0"/>
<param name="PrefDir.3" value="0"/>
<param name="PrefDir.4" value="0"/>
<param name="PrefDir.5" value="0"/>
<param name="PrefDir.6" value="0"/>
<param name="PrefDir.7" value="0"/>
<param name="PrefDir.8" value="0"/>
<param name="PrefDir.9" value="0"/>
<param name="PrefDir.10" value="0"/>
<param name="PrefDir.11" value="0"/>
<param name="PrefDir.12" value="0"/>
<param name="PrefDir.13" value="0"/>
<param name="PrefDir.14" value="0"/>
<param name="PrefDir.15" value="0"/>
<param name="PrefDir.16" value="-"/>
<param name="cfVia" value="8"/>
<param name="cfNonPref" value="5"/>
<param name="cfChangeDir" value="2"/>
<param name="cfOrthStep" value="2"/>
<param name="cfDiagStep" value="3"/>
<param name="cfExtdStep" value="0"/>
<param name="cfBonusStep" value="1"/>
<param name="cfMalusStep" value="1"/>
<param name="cfPadImpact" value="4"/>
<param name="cfSmdImpact" value="4"/>
<param name="cfBusImpact" value="0"/>
<param name="cfHugging" value="3"/>
<param name="cfAvoid" value="4"/>
<param name="cfPolygon" value="10"/>
<param name="cfBase.1" value="0"/>
<param name="cfBase.2" value="1"/>
<param name="cfBase.3" value="1"/>
<param name="cfBase.4" value="1"/>
<param name="cfBase.5" value="1"/>
<param name="cfBase.6" value="1"/>
<param name="cfBase.7" value="1"/>
<param name="cfBase.8" value="1"/>
<param name="cfBase.9" value="1"/>
<param name="cfBase.10" value="1"/>
<param name="cfBase.11" value="1"/>
<param name="cfBase.12" value="1"/>
<param name="cfBase.13" value="1"/>
<param name="cfBase.14" value="1"/>
<param name="cfBase.15" value="1"/>
<param name="cfBase.16" value="0"/>
<param name="mnVias" value="20"/>
<param name="mnSegments" value="9999"/>
<param name="mnExtdSteps" value="9999"/>
<param name="mnRipupLevel" value="10"/>
<param name="mnRipupSteps" value="100"/>
<param name="mnRipupTotal" value="100"/>
</pass>
<pass name="Follow-me" refer="Default" active="yes">
</pass>
<pass name="Busses" refer="Default" active="yes">
<param name="cfNonPref" value="4"/>
<param name="cfBusImpact" value="4"/>
<param name="cfHugging" value="0"/>
<param name="mnVias" value="0"/>
</pass>
<pass name="Route" refer="Default" active="yes">
</pass>
<pass name="Optimize1" refer="Default" active="yes">
<param name="cfVia" value="99"/>
<param name="cfExtdStep" value="10"/>
<param name="cfHugging" value="1"/>
<param name="mnExtdSteps" value="1"/>
<param name="mnRipupLevel" value="0"/>
</pass>
<pass name="Optimize2" refer="Optimize1" active="yes">
<param name="cfNonPref" value="0"/>
<param name="cfChangeDir" value="6"/>
<param name="cfExtdStep" value="0"/>
<param name="cfBonusStep" value="2"/>
<param name="cfMalusStep" value="2"/>
<param name="cfPadImpact" value="2"/>
<param name="cfSmdImpact" value="2"/>
<param name="cfHugging" value="0"/>
</pass>
<pass name="Optimize3" refer="Optimize2" active="yes">
<param name="cfChangeDir" value="8"/>
<param name="cfPadImpact" value="0"/>
<param name="cfSmdImpact" value="0"/>
</pass>
<pass name="Optimize4" refer="Optimize3" active="yes">
<param name="cfChangeDir" value="25"/>
</pass>
</autorouter>
<elements>
<element name="LED1" library="adafruit" package="CHIP-LED0603" value="-ve" x="78.128803125" y="76.69393125" smashed="yes">
<attribute name="VALUE" x="78.640296875" y="78.711984375" size="0.6096" layer="25" rot="R180"/>
</element>
<element name="JP5" library="SparkFun-Connectors" package="1X06_NO_SILK_YES_STOP" value="" x="93.083359375" y="75.417115625" smashed="yes" rot="R180">
<attribute name="VALUE" x="94.353359375" y="78.592115625" size="1.27" layer="27" rot="R180"/>
</element>
<element name="JP6" library="SparkFun-Connectors" package="1X06_NO_SILK_YES_STOP" value="" x="93.083359375" y="78.030871875" smashed="yes" rot="R180">
<attribute name="VALUE" x="94.353359375" y="81.205871875" size="1.27" layer="27" rot="R180"/>
</element>
<element name="R5" library="adafruit" package="R0603" value="47" x="84.399428125" y="71.731540625" smashed="yes">
<attribute name="VALUE" x="84.385003125" y="69.95374375" size="0.6096" layer="25"/>
</element>
<element name="R6" library="adafruit" package="R0603" value="4.7K" x="79.860775" y="71.7191875" smashed="yes">
<attribute name="VALUE" x="78.79060625" y="69.977396875" size="0.6096" layer="25"/>
</element>
<element name="CTBC547BJS" library="adafruit" package="TO92-EBC-OVAL" value="" x="90.74181875" y="69.237996875" smashed="yes" rot="R180">
<attribute name="NAME" x="93.10345" y="73.4783375" size="0.6096" layer="25" ratio="10" rot="R180"/>
<attribute name="VALUE" x="93.28181875" y="73.809996875" size="1.27" layer="27" ratio="10" rot="R180"/>
</element>
<element name="R1" library="adafruit" package="R0603" value="12" x="84.44975" y="68.59291875" smashed="yes">
<attribute name="VALUE" x="81.901909375" y="68.2049625" size="0.6096" layer="25"/>
</element>
</elements>
<signals>
<signal name="GND">
<contactref element="JP6" pad="1"/>
<contactref element="CTBC547BJS" pad="E"/>
<contactref element="R1" pad="2"/>
<wire x1="93.199996875" y1="68.599996875" x2="85.299996875" y2="68.599996875" width="0.254" layer="1"/>
<wire x1="93.199996875" y1="70.499996875" x2="93.199996875" y2="68.599996875" width="0.254" layer="1"/>
<wire x1="85.299996875" y1="68.599996875" x2="85.29975" y2="68.59291875" width="0.254" layer="1"/>
<wire x1="93.199996875" y1="70.499996875" x2="93.28181875" y2="70.507996875" width="0.254" layer="1"/>
<wire x1="91.699996875" y1="76.699996875" x2="92.999996875" y2="77.999996875" width="0.254" layer="16"/>
<wire x1="79.799996875" y1="76.699996875" x2="91.699996875" y2="76.699996875" width="0.254" layer="16"/>
<wire x1="79.099996875" y1="75.999996875" x2="79.799996875" y2="76.699996875" width="0.254" layer="16"/>
<wire x1="79.099996875" y1="72.099996875" x2="79.099996875" y2="75.999996875" width="0.254" layer="16"/>
<wire x1="87.699996875" y1="72.099996875" x2="79.099996875" y2="72.099996875" width="0.254" layer="16"/>
<wire x1="87.799996875" y1="72.199996875" x2="87.699996875" y2="72.099996875" width="0.254" layer="16"/>
<wire x1="91.599996875" y1="72.199996875" x2="87.799996875" y2="72.199996875" width="0.254" layer="16"/>
<wire x1="93.199996875" y1="70.599996875" x2="91.599996875" y2="72.199996875" width="0.254" layer="16"/>
<wire x1="92.999996875" y1="77.999996875" x2="93.083359375" y2="78.030871875" width="0.254" layer="16"/>
<wire x1="93.199996875" y1="70.599996875" x2="93.28181875" y2="70.507996875" width="0.254" layer="16"/>
</signal>
<signal name="CHIME_V">
<contactref element="JP5" pad="4"/>
<contactref element="R6" pad="2"/>
<wire x1="81.099996875" y1="72.099996875" x2="80.799996875" y2="71.799996875" width="0.254" layer="1"/>
<wire x1="81.099996875" y1="72.999996875" x2="81.099996875" y2="72.099996875" width="0.254" layer="1"/>
<wire x1="82.199996875" y1="74.099996875" x2="81.099996875" y2="72.999996875" width="0.254" layer="16"/>
<wire x1="84.099996875" y1="74.099996875" x2="82.199996875" y2="74.099996875" width="0.254" layer="16"/>
<wire x1="85.399996875" y1="75.399996875" x2="84.099996875" y2="74.099996875" width="0.254" layer="16"/>
<wire x1="80.799996875" y1="71.799996875" x2="80.710775" y2="71.7191875" width="0.254" layer="1"/>
<wire x1="85.399996875" y1="75.399996875" x2="85.463359375" y2="75.417115625" width="0.254" layer="16"/>
<via x="81.099996875" y="72.999996875" extent="1-16" drill="0.6096"/>
</signal>
<signal name="N$1">
<contactref element="JP5" pad="6"/>
<contactref element="R5" pad="1"/>
<contactref element="R1" pad="1"/>
<wire x1="83.599996875" y1="71.699996875" x2="83.599996875" y2="68.599996875" width="0.254" layer="1"/>
<wire x1="83.599996875" y1="68.599996875" x2="83.59975" y2="68.59291875" width="0.254" layer="1"/>
<wire x1="83.599996875" y1="71.699996875" x2="83.549428125" y2="71.731540625" width="0.254" layer="1"/>
<wire x1="80.399996875" y1="74.899996875" x2="83.499996875" y2="71.799996875" width="0.254" layer="1"/>
<wire x1="80.399996875" y1="75.399996875" x2="80.399996875" y2="74.899996875" width="0.254" layer="1"/>
<wire x1="83.499996875" y1="71.799996875" x2="83.549428125" y2="71.731540625" width="0.254" layer="1"/>
<wire x1="80.399996875" y1="75.399996875" x2="80.383359375" y2="75.417115625" width="0.254" layer="1"/>
</signal>
<signal name="N$2">
<contactref element="LED1" pad="A"/>
<contactref element="R6" pad="1"/>
<wire x1="78.999996875" y1="75.099996875" x2="78.199996875" y2="75.899996875" width="0.254" layer="1"/>
<wire x1="78.999996875" y1="71.799996875" x2="78.999996875" y2="75.099996875" width="0.254" layer="1"/>
<wire x1="78.199996875" y1="75.899996875" x2="78.128803125" y2="75.94393125" width="0.254" layer="1"/>
<wire x1="78.999996875" y1="71.799996875" x2="79.010775" y2="71.7191875" width="0.254" layer="1"/>
</signal>
<signal name="CHIME_G">
<contactref element="JP6" pad="2"/>
<contactref element="LED1" pad="C"/>
<contactref element="CTBC547BJS" pad="C"/>
<wire x1="79.199996875" y1="77.399996875" x2="78.199996875" y2="77.399996875" width="0.254" layer="1"/>
<wire x1="79.899996875" y1="76.699996875" x2="79.199996875" y2="77.399996875" width="0.254" layer="1"/>
<wire x1="90.499996875" y1="76.699996875" x2="79.899996875" y2="76.699996875" width="0.254" layer="1"/>
<wire x1="90.499996875" y1="77.999996875" x2="90.499996875" y2="76.699996875" width="0.254" layer="1"/>
<wire x1="78.199996875" y1="77.399996875" x2="78.128803125" y2="77.44393125" width="0.254" layer="1"/>
<wire x1="90.499996875" y1="77.999996875" x2="90.543359375" y2="78.030871875" width="0.254" layer="1"/>
<wire x1="87.199996875" y1="71.599996875" x2="88.199996875" y2="70.599996875" width="0.254" layer="16"/>
<wire x1="77.699996875" y1="71.599996875" x2="87.199996875" y2="71.599996875" width="0.254" layer="16"/>
<wire x1="77.299996875" y1="71.999996875" x2="77.699996875" y2="71.599996875" width="0.254" layer="1"/>
<wire x1="77.299996875" y1="76.399996875" x2="77.299996875" y2="71.999996875" width="0.254" layer="1"/>
<wire x1="78.199996875" y1="77.299996875" x2="77.299996875" y2="76.399996875" width="0.254" layer="1"/>
<wire x1="88.199996875" y1="70.599996875" x2="88.20181875" y2="70.507996875" width="0.254" layer="16"/>
<wire x1="78.199996875" y1="77.299996875" x2="78.128803125" y2="77.44393125" width="0.254" layer="1"/>
<via x="77.699996875" y="71.599996875" extent="1-16" drill="0.6096"/>
</signal>
<signal name="N$3">
<contactref element="R5" pad="2"/>
<contactref element="CTBC547BJS" pad="B"/>
<wire x1="87.399996875" y1="71.799996875" x2="85.299996875" y2="71.799996875" width="0.254" layer="1"/>
<wire x1="87.799996875" y1="72.199996875" x2="87.399996875" y2="71.799996875" width="0.254" layer="1"/>
<wire x1="90.699996875" y1="72.199996875" x2="87.799996875" y2="72.199996875" width="0.254" layer="1"/>
<wire x1="90.699996875" y1="70.599996875" x2="90.699996875" y2="72.199996875" width="0.254" layer="1"/>
<wire x1="85.299996875" y1="71.799996875" x2="85.249428125" y2="71.731540625" width="0.254" layer="1"/>
<wire x1="90.699996875" y1="70.599996875" x2="90.74181875" y2="70.507996875" width="0.254" layer="1"/>
</signal>
</signals>
</board>
</drawing>
<compatibility>
<note version="6.3" minversion="6.2.2" severity="warning">
Since Version 6.2.2 text objects can contain more than one line,
which will not be processed correctly with this version.
</note>
</compatibility>
</eagle>

extension: brd


text:
/*!
@file  frame.hpp
@brief definition of a class that contains frame (frame header and frame data)

@author Toru Niina (niina.toru.68u@gmail.com)
@date 2017-11-06 14:30
@copyright Toru Niina
*/

#ifndef LIBASD_FRAME_H
#define LIBASD_FRAME_H
#include <libasd/exception_thrower.hpp>
#include <libasd/container_dispatcher.hpp>
#include <libasd/frame_header.hpp>
#include <libasd/frame_data.hpp>
#include <libasd/tag.hpp>
#include <type_traits>
#include <stdexcept>
#include <array>
#include <cstdint>

namespace asd
{

//! .asd frame class containing frame header and frame data information.
/*!
 * @tparam valueT type of a value corresponding to each pixel
 * @tparam contT  a container-dispatcher that defines container class to be used
 * */
template<typename valueT, typename contT = container::vec>
struct Frame
{
    typedef valueT                                     pixel_type;
    typedef FrameHeader                                header_type;
    typedef FrameData<valueT, contT>                   frame_data_type;
    typedef typename frame_data_type::proxy_type             proxy_type;
    typedef typename frame_data_type::const_proxy_type       const_proxy_type;
    typedef typename frame_data_type::iterator               iterator;
    typedef typename frame_data_type::const_iterator         const_iterator;
    typedef typename frame_data_type::reverse_iterator       reverse_iterator;
    typedef typename frame_data_type::const_reverse_iterator const_reverse_iterator;

    header_type     header; //!< frame-header information
    frame_data_type data;   //!< frame-data information

    // ------------------------------------------------------------------------
    // container-interface as a framedata
    // ------------------------------------------------------------------------

    proxy_type       operator[](std::size_t i)       noexcept {return data[i];}
    const_proxy_type operator[](std::size_t i) const noexcept {return data[i];}
    proxy_type       at(std::size_t i)       {return data.at(i);}
    const_proxy_type at(std::size_t i) const {return data.at(i);}
    proxy_type       front()       noexcept {return data.front();}
    const_proxy_type front() const noexcept {return data.front();}
    proxy_type       back()        noexcept {return data.back();}
    const_proxy_type back()  const noexcept {return data.back();}

    iterator       begin()        noexcept {return data.begin();}
    iterator       end()          noexcept {return data.end();}
    const_iterator begin()  const noexcept {return data.begin();}
    const_iterator end()    const noexcept {return data.end();}
    const_iterator cbegin() const noexcept {return data.cbegin();}
    const_iterator cend()   const noexcept {return data.cend();}

    reverse_iterator       rbegin()        noexcept {return data.rbegin();}
    reverse_iterator       rend()          noexcept {return data.rend();}
    const_reverse_iterator rbegin()  const noexcept {return data.rbegin();}
    const_reverse_iterator rend()    const noexcept {return data.rend();}
    const_reverse_iterator crbegin() const noexcept {return data.crbegin();}
    const_reverse_iterator crend()   const noexcept {return data.crend();}
};

} // asd
#endif//LIBASD_FRAME_TAG_H

repository: ToruNiina/libasd

repo_name: ToruNiina/libasd

extension: hpp


text:
/*
 * And.cpp
 *
 *  Created on: Jul 17, 2014
 *      Author: psp
 */

#include "And.h"

#include "TermBuilder.h"
#include "Constant.h"

namespace autodiff
{
	And::And(shared_ptr<Term> left, shared_ptr<Term> right) :
			Term()
	{
		this->left = left;
		this->right = right;
	}

	int And::accept(shared_ptr<ITermVisitor> visitor)
	{
		shared_ptr<And> thisCasted = dynamic_pointer_cast<And>(shared_from_this());
		return visitor->visit(thisCasted);
	}

	shared_ptr<Term> And::aggregateConstants()
	{
		left = left->aggregateConstants();
		if (left == Term::FALSE) {
			return left;
		}
		right = right->aggregateConstants();
		if (left == Term::TRUE) {
			return right;
		}
		if (right == Term::FALSE) {
			return right;
		}
		if (right == Term::TRUE) {
			return left;
		}
		if (dynamic_pointer_cast<Constant>(left) != 0 && dynamic_pointer_cast<Constant>(right) != 0) {
			shared_ptr<Constant> leftConstant = dynamic_pointer_cast<Constant>(left);
			shared_ptr<Constant> rightConstant = dynamic_pointer_cast<Constant>(right);
			if (leftConstant->value > 0.75 && rightConstant->value > 0.75) {
				return Term::TRUE;
			} else {
				return Term::FALSE;
			}
		} else {
			return shared_from_this();
		}
	}

	shared_ptr<Term> And::derivative(shared_ptr<Variable> v)
	{
		throw "Symbolic Derivation of And not supported";
	}

	shared_ptr<Term> And::negate()
	{
		return left->negate() | right->negate();
	}

	string And::toString()
	{
		string str;
		str.append("and( ");
		str.append(left->toString());
		str.append(", ");
		str.append(right->toString());
		str.append(" )");
		return str;
	}
} /* namespace autodiff */

repository: andreaswitsch/cnlcsplib

repo_name: andreaswitsch/cnlcsplib


text:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE eagle SYSTEM "eagle.dtd">
<eagle version="5.91">
<drawing>
<settings>
<setting alwaysvectorfont="no"/>
<setting verticaltext="up"/>
</settings>
<grid distance="0.1" unitdist="inch" unit="inch" style="lines" multiple="1" display="no" altdistance="0.01" altunitdist="inch" altunit="inch"/>
<schematic xreflabel="%F%N/%S.%C%R" xrefpart="/%S.%C%R">
<libraries>
<library name="cap">
<description>Capacitor</description>
<symbols>
<symbol name="C-US">
<wire x1="-2.54" y1="0" x2="2.54" y2="0" width="0.254" layer="94"/>
<wire x1="0" y1="-1.016" x2="0" y2="-2.54" width="0.1524" layer="94"/>
<wire x1="0" y1="-1" x2="2.4892" y2="-1.8542" width="0.254" layer="94" curve="-37.878202" cap="flat"/>
<wire x1="-2.4668" y1="-1.8504" x2="0" y2="-1.0161" width="0.254" layer="94" curve="-37.373024" cap="flat"/>
<text x="1.016" y="0.635" size="1.778" layer="95">>NAME</text>
<text x="1.016" y="-4.191" size="1.778" layer="96">>VALUE</text>
<pin name="1" x="0" y="2.54" visible="off" length="short" direction="pas" swaplevel="1" rot="R270"/>
<pin name="2" x="0" y="-5.08" visible="off" length="short" direction="pas" swaplevel="1" rot="R90"/>
</symbol>
</symbols>
<devicesets>
<deviceset name="C-US" prefix="C" uservalue="yes">
<description>CAPACITOR, American symbol</description>
<gates>
<gate name="G$1" symbol="C-US" x="0" y="0"/>
</gates>
</deviceset>
</devicesets>
</library>
</libraries>
<attributes>
</attributes>
<variantdefs>
</variantdefs>
<classes>
<class number="0" name="default" width="0" drill="0">
</class>
</classes>
<parts>
<part name="C1" library="cap" deviceset="C-US" device="C0805"/>
</parts>
<sheets>
<sheet>
<plain>
</plain>
<instances>
<instance part="C1" gate="G$1" x="60.96" y="38.1"/>
</instances>
<busses>
</busses>
<nets>
</nets>
</sheet>
</sheets>
</schematic>
</drawing>
</eagle>

gha_license_id: NOASSERTION

extension: sch


text:
SUMMARY = "RTOS driver for BMET Ethernet"

inherit ti-pdk
require transport.inc

PR = "${INC_PR}.0"

LIC_FILES_CHKSUM = "file://bmet_transport.h;beginline=12;endline=40;md5=7c7fbe6af03d79b61025a67a8fc96f93"

COMPATIBLE_MACHINE = "k2hk-evm|k2e-evm|k2l-evm"

DEPENDS_append = " qmss-lld-rtos \
                   cppi-lld-rtos \
"

BMET_ETH_DESTSUFFIX = "git/bmet_eth"

S = "${WORKDIR}/${BMET_ETH_DESTSUFFIX}"

# HTML doc link params
PDK_COMP_LINK_TEXT = "Baremetal Ethernet Transport"

extension: bb


text:
package remediator_test

import (
	"context"
	"errors"
	"github.com/aksgithub/kube_remediator/pkg/k8s/mock"
	"github.com/aksgithub/kube_remediator/pkg/remediator"
	"github.com/golang/mock/gomock"
	"github.com/stretchr/testify/suite"
	"go.uber.org/zap"
	"gotest.tools/assert"
	corev1 "k8s.io/api/core/v1"
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
	"sync"
	"testing"
	"time"
)

type TestCompletedPodDeleterSuite struct {
	suite.Suite
	logger         *zap.Logger
	mockController *gomock.Controller
	mockClient     *mock_k8s.MockClientInterface
	pods           []corev1.Pod
	t              *testing.T
}

func TestSuitecompletedPodDeleter(t *testing.T) {
	suite.Run(t, &TestCompletedPodDeleterSuite{t: t})
}

func (suite *TestCompletedPodDeleterSuite) SetupTest() {
	suite.logger, _ = zap.NewDevelopment()
	suite.mockController = gomock.NewController(suite.t)
	suite.mockClient = mock_k8s.NewMockClientInterface(suite.mockController)
	suite.pods = []corev1.Pod{{
		ObjectMeta: metav1.ObjectMeta{
			Name:              "foo",
			Namespace:         "default",
			CreationTimestamp: metav1.NewTime(time.Now().Add(-25 * time.Hour)),
		},
		Status: corev1.PodStatus{
			Phase: "Succeeded",
		},
	}}
}

func (suite *TestCompletedPodDeleterSuite) TeardownTest() {
	suite.mockController.Finish()
}

func (suite *TestCompletedPodDeleterSuite) run() {
	completedPodDeleter := remediator.CompletedPodDeleter{}
	err := completedPodDeleter.Setup(suite.logger, suite.mockClient)
	assert.Equal(suite.t, err, nil)

	ctx, cancel := context.WithCancel(context.Background())
	cancel() // cancel first so we can just run once and exit

	var wg sync.WaitGroup
	wg.Add(1)

	completedPodDeleter.Run(ctx, &wg)
}

func (suite *TestCompletedPodDeleterSuite) TestDeleteCompletedPods() {
	suite.mockClient.EXPECT().GetPods("").Return(&corev1.PodList{Items: suite.pods}, nil)
	suite.mockClient.EXPECT().DeletePod(&suite.pods[0]).Return(nil)
	suite.run()
}

func (suite *TestCompletedPodDeleterSuite) TestKeepsNewPods() {
	suite.pods[0].ObjectMeta.CreationTimestamp = metav1.NewTime(time.Now().Add(-23 * time.Hour))
	suite.mockClient.EXPECT().GetPods("").Return(&corev1.PodList{Items: suite.pods}, nil)
	suite.run()
}

func (suite *TestCompletedPodDeleterSuite) TestDoesNotCrashWhenListFails() {
	suite.mockClient.EXPECT().GetPods("").Return(nil, errors.New("Foo"))
	suite.run()
}

func (suite *TestCompletedPodDeleterSuite) TestDoesNotCrashWhenDeleteFails() {
	suite.mockClient.EXPECT().GetPods("").Return(&corev1.PodList{Items: suite.pods}, nil)
	suite.mockClient.EXPECT().DeletePod(&suite.pods[0]).Return(errors.New("Foo"))
	suite.run()
}


text:
@inproceedings{de2018logical,
  title={Logical design of graph databases from an entity-relationship conceptual model},
  author={de Sousa, Victor Martins and Cura, Luis Mariano del Val},
  booktitle={Proceedings of the 20th International Conference on Information Integration and Web-based Applications \& Services},
  pages={183--189},
  year={2018},
  url={https://doi.org/10.1145/3282373.3282375},
  doi={10.1145/3282373.3282375}
}

extension: bib


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

#ifndef CONTENT_RENDERER_ACTIVE_NOTIFICATION_TRACKER_H_
#define CONTENT_RENDERER_ACTIVE_NOTIFICATION_TRACKER_H_

#include <map>

#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/id_map.h"
#include "content/common/content_export.h"
#include "third_party/WebKit/public/web/WebNotification.h"

namespace content {

class CONTENT_EXPORT ActiveNotificationTracker {
 public:
  ActiveNotificationTracker();
  ~ActiveNotificationTracker();

  int RegisterNotification(const blink::WebNotification& notification);
  void UnregisterNotification(int id);
  bool GetId(const blink::WebNotification& notification, int& id);
  bool GetNotification(int id, blink::WebNotification* notification);

  void Clear();

 private:
  typedef std::map<blink::WebNotification, int> ReverseTable;

  IDMap<blink::WebNotification> notification_table_;
  ReverseTable reverse_notification_table_;

  DISALLOW_COPY_AND_ASSIGN(ActiveNotificationTracker);
};

}

#endif

extension: h


text:
# Copyright (C) 2019 Garmin Ltd. or its subsidaries
# Released under the MIT license (see COPYING.MIT for the terms)

SUMMARY = "Arm Trusted Firmware"
HOMEPAGE = "https://developer.trustedfirmware.org/"
LICENSE = "BSD-3-Clause"
LIC_FILES_CHKSUM = "file://docs/license.rst;md5=189505435dbcdcc8caa63c46fe93fa89"

# Rockchip RK3399 compiles some M0 firmware which requires an arm-none-eabi GCC
# toolchain
DEPENDS_rk3399 = "virtual/arm-none-eabi-gcc"

PROVIDES = "virtual/atf"

BRANCH = "master"
SRC_URI = "git://git.trustedfirmware.org/TF-A/trusted-firmware-a.git;protocol=http;branch=${BRANCH} \
           "
SRCREV = "8ff55a9e14a23d7c7f89f52465bcc6307850aa33"

S = "${WORKDIR}/git"
B = "${WORKDIR}/build"

inherit deploy

ATF_SUFFIX ??= "bin"

do_compile() {
    unset LDFLAGS
    unset CFLAGS
    unset CPPFLAGS

    oe_runmake -C ${S} BUILD_BASE=${B} DEBUG=0 CROSS_COMPILE=${TARGET_PREFIX} \
        PLAT=${ATF_PLATFORM} ${ATF_TARGET}
}

PACKAGE_ARCH = "${MACHINE_ARCH}"

do_deploy() {
    install -m 644 ${B}/${ATF_PLATFORM}/release/${ATF_TARGET}/${ATF_TARGET}.${ATF_SUFFIX} \
        ${DEPLOYDIR}/${ATF_TARGET}.${ATF_SUFFIX}
}
addtask deploy after do_compile

repository: acrlinux/acrlinux-yocto

repo_name: acrlinux/acrlinux-yocto


text:
/*=============================================================================
ImageReader.h
Project: Sonata Engine
Author: Julien Delezenne
=============================================================================*/

#ifndef _SE_IMAGEREADER_H_
#define _SE_IMAGEREADER_H_

#include "Core/Core.h"
#include "Core/IO/Stream.h"
#include "Graphics/Image.h"

namespace SonataEngine
{

enum ImageOptionsFlag
{
	ImageOptions_Format = (1<<0),
	ImageOptions_Size = (1<<1)
};

/** Image reader options. */
struct ImageReaderOptions
{
	PixelFormat Format;
	int32 Width;
	int32 Height;
};

/** Image reader. */
class SE_GRAPHICS_EXPORT ImageReader
{
public:
	virtual Image* LoadImage(Stream& stream, ImageReaderOptions* options = NULL) = 0;
};

}

#endif

repository: jdelezenne/Sonata

repo_name: jdelezenne/Sonata


text:
#ifndef CEILINGFAN_H
#define CEILINGFAN_H

#include <iostream>
#include <string>
#include <vector>
#include <cstdio>

#include "../command.h"

class CeilingFan
{
public:
    const int OFF = 0;
    const int LOW = 1;
    const int MEDIUM = 2;
    const int HIGH = 3;
private:
    int speed;
    std::string placename;
public:
    CeilingFan (std::string placename) { this->speed = OFF; this->placename = placename; };
    std::string getPlacename () { return this->placename; }
    int getSpeed () { return this->speed; }
    void off () { this->speed = 0; printf("%s ceiling fan is OFF!\n", this->placename.c_str()); };
    void low () { this->speed = 1; printf("%s ceiling fan is LOW!\n", this->placename.c_str()); };
    void medium () { this->speed = 2; printf("%s ceiling fan is MEDIUM!\n", this->placename.c_str()); };
    void high () { this->speed = 3; printf("%s ceiling fan is HIGH!\n", this->placename.c_str()); };
};

class CeilingFanHighCommand : public Command
{
private:
    int prev_speed;
    CeilingFan *fan;
public:
    CeilingFanHighCommand (CeilingFan *fan) { this->fan = fan; };
    void execute ()
    {
        this->prev_speed = fan->getSpeed();
        this->fan->high();
    }
    void undo ()
    {
        if (prev_speed == this->fan->OFF) this->fan->off();
        else if (prev_speed == this->fan->LOW) this->fan->low();
        else if (prev_speed == this->fan->MEDIUM) this->fan->medium();
        else if (prev_speed == this->fan->HIGH) this->fan->high();
        else
        {
            fprintf(stderr,"[-] ERROR! Invalid ceiling fan speed!\n");
            exit(EXIT_FAILURE);
        }
    }
    std::string classname () { return "CeilingFanHighCommand"; }
};

class CeilingFanMediumCommand : public Command
{
private:
    int prev_speed;
    CeilingFan *fan;
public:
    CeilingFanMediumCommand (CeilingFan *fan) { this->fan = fan; };
    void execute ()
    {
        this->prev_speed = fan->getSpeed();
        this->fan->medium();
    }
    void undo ()
    {
        if (prev_speed == this->fan->OFF) this->fan->off();
        else if (prev_speed == this->fan->LOW) this->fan->low();
        else if (prev_speed == this->fan->MEDIUM) this->fan->medium();
        else if (prev_speed == this->fan->HIGH) this->fan->high();
        else
        {
            fprintf(stderr,"[-] ERROR! Invalid ceiling fan speed!\n");
            exit(EXIT_FAILURE);
        }
    }
    std::string classname () { return "CeilingFanMediumCommand"; }
};

class CeilingFanLowCommand : public Command
{
private:
    int prev_speed;
    CeilingFan *fan;
public:
    CeilingFanLowCommand (CeilingFan *fan) { this->fan = fan; };
    void execute ()
    {
        this->prev_speed = fan->getSpeed();
        this->fan->low();
    }
    void undo ()
    {
        if (prev_speed == this->fan->OFF) this->fan->off();
        else if (prev_speed == this->fan->LOW) this->fan->low();
        else if (prev_speed == this->fan->MEDIUM) this->fan->medium();
        else if (prev_speed == this->fan->HIGH) this->fan->high();
        else
        {
            fprintf(stderr,"[-] ERROR! Invalid ceiling fan speed!\n");
            exit(EXIT_FAILURE);
        }
    }
    std::string classname () { return "CeilingFanLowCommand"; }
};

class CeilingFanOffCommand : public Command
{
private:
    int prev_speed;
    CeilingFan *fan;
public:
    CeilingFanOffCommand (CeilingFan *fan) { this->fan = fan; };
    void execute ()
    {
        this->prev_speed = fan->getSpeed();
        this->fan->off();
    }
    void undo ()
    {
        if (prev_speed == this->fan->OFF) this->fan->off();
        else if (prev_speed == this->fan->LOW) this->fan->low();
        else if (prev_speed == this->fan->MEDIUM) this->fan->medium();
        else if (prev_speed == this->fan->HIGH) this->fan->high();
        else
        {
            fprintf(stderr,"[-] ERROR! Invalid ceiling fan speed!\n");
            exit(EXIT_FAILURE);
        }
    }
    std::string classname () { return "CeilingFanOffCommand"; }
};

#endif