text:
#include "osr/gui/loaders/DavidViveScanLoader.h"

#include <iostream>
#include <boost/format.hpp>

#include "davidviveres.h"
#include "osr/meshio.h"

#include <boost/date_time/gregorian/gregorian.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

#include <ostream>

using namespace osr;
using namespace osr::gui;
using namespace osr::gui::loaders;

const std::string autoItPath = "D:\\Program Files (x86)\\AutoIt3\\AutoIt3.exe"; //TODO: Generalize
const std::string scanPath = "D:\\Scans\\currentScan.ply"; //TODO::Generalize

DavidViveScanLoader::DavidViveScanLoader(nse::gui::AbstractViewer* viewer)
	: trackingThread(nullptr), tracking(false), viewer(viewer)
{ }

void DavidViveScanLoader::setup(nanogui::Window*)
{
	std::cout << "Starting the DAVID/Vive scan loader .." << std::endl;

	vr::HmdError error;
	vrSystem = vr::VR_Init(&error, vr::EVRApplicationType::VRApplication_Other);

	if (vrSystem == nullptr)
	{
		std::cout << "Cannot start OpenVR." << std::endl;
		return;
	}

	std::cout << "OpenVR started successfully." << std::endl;

	//write AutoIt script to current directory
	FILE* f = fopen("TakeDavidScan.au3", "wb");
	fwrite(takedavidscan_au3, 1, takedavidscan_au3_size, f);
	fclose(f);

	f = fopen("ViveController.ply", "wb");
	fwrite(vivecontroller_ply, 1, vivecontroller_ply_size, f);
	fclose(f);

	MatrixXu F;
	Matrix3Xf V, N;
	Matrix3Xus C;
	load_ply("ViveController.ply", F, V, N, C);
	viveController = new Scan(1000 * V, N, C, F);
	viveController->initialize();
	remove("ViveController.ply");

	tracking = true;
	trackingThread = new std::thread(&DavidViveScanLoader::track, this);

	f = fopen("calibration.bin", "rb");
	if (f)
	{
		std::cout << "Reading Vive calibration from file." << std::endl;
		fread(transformScannerControllerToDavidSystem.data(), sizeof(float), 16, f);
		fclose(f);
	}
	else
	{
		std::cout << "No Vive calibration available." << std::endl;
		transformScannerControllerToDavidSystem.setIdentity();
	}

	f = fopen("calibrationTurntable.bin", "rb");
	if (f)
	{
		std::cout << "Reading turntable calibration from file." << std::endl;
		fread(axisDirection.data(), sizeof(float), 3, f);
		fread(axisCenter.data(), sizeof(float), 3, f);
		fclose(f);
	}
	else
	{
		std::cout << "No turntable calibration available." << std::endl;
		axisDirection = Vector3f::UnitZ();
		axisCenter.setZero();
	}

	boost::filesystem::path p(scanPath);
	p.remove_filename();

	boost::format fmt("ScanSession_%04d-%02d-%02d_%02d-%02d-%02d");
	auto now = boost::posix_time::second_clock::local_time();
	std::string filename = (fmt % now.date().year() % (int)now.date().month() % now.date().day() % now.time_of_day().hours() % now.time_of_day().minutes() % now.time_of_day().seconds()).str();
	sessionPath = p / boost::filesystem::path(filename);
	boost::filesystem::create_directory(sessionPath);

	entireALNPath = (sessionPath / boost::filesystem::path("Session.aln")).string();
	fEntireALN.open(entireALNPath);
	fEntireALN << "0       " << std::endl;
	scansInALN = 0;

#ifdef WIN32
	turntable.openConnection();
#endif

	currentAngle = 0;

	state = Normal;

	hasReference = false;
	calibrationAutoImproveMatrix.setZero();
	adaptAfterCalibration.setIdentity();

	scannerControllerMatrix.linear().setConstant(std::numeric_limits<float>::quiet_NaN());
	secondaryControllerMatrix.linear().setConstant(std::numeric_limits<float>::quiet_NaN());
}

void DavidViveScanLoader::draw(const Matrix4f & mv, const Matrix4f & proj)
{
	if (state == CalibratingShowScan || state == CalibratingShowBoth)
	{
		if (currentScan)
		{
			if (!currentScan->isInitialized())
				currentScan->initialize();
			currentScan->draw(mv, proj);
		}
	}

	if (state == CalibratingShowViveController || state == CalibratingShowBoth)
	{
		if (viveController)
			viveController->draw(mv, proj);
	}

	if (state == Scanning)
	{
		NVGcontext* vg = viewer->nvgContext();
		float bounds[4];
		nvgTextBounds(vg, 0, 0, "Scanning ...", nullptr, bounds);

		nvgBeginPath(vg);
		nvgRoundedRect(vg, viewer->width() - 30 - bounds[2] + bounds[0], viewer->height() - 30 - bounds[3] + bounds[1], 20 + bounds[2] - bounds[0], 20 + bounds[3] - bounds[1], 4);
		nvgFillColor(vg, nvgRGBA(0, 0, 0, 128));
		nvgFill(vg);
		std::chrono::milliseconds ms = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch());
		unsigned char color = (unsigned char)(190 + 30 * sin(ms.count() / 200.0));
		nvgFillColor(vg, nvgRGBA(color, color, color, 255));
		nvgText(vg, viewer->width() - 20 - bounds[2], viewer->height() - 20 - bounds[3], "Scanning ...", nullptr);
	}
}

bool DavidViveScanLoader::mouseButtonEvent(const Eigen::Vector2i & p, int button, bool down, int modifiers)
{
	if (state == Normal)
		return false;

	if (down && button == GLFW_MOUSE_BUTTON_1 && modifiers == GLFW_MOD_CONTROL)
	{
		float depth;
		glReadPixels(p.x(), viewer->height() - 1 - p.y(), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &depth);

		if (depth < 1 && depth != 0)
		{
			float ndcDepth = 2 * (depth - 0.5);

			float x = 2 * ((float)p.x() / viewer->width() - 0.5f);
			float y = 2 * ((float)-p.y() / viewer->height() + 0.5f);

			Eigen::Matrix4f model, view, proj;
			viewer->camera().ComputeCameraMatrices(model, view, proj);

			Eigen::Matrix4f mvp = proj * view * model;
			Eigen::Matrix4f invMvp = mvp.inverse();

			Vector4f pos = invMvp * Vector4f(x, y, ndcDepth, 1);
			Vector3f pos3 = pos.block<3, 1>(0, 0) / pos.w();

			if (state == CalibratingShowScan)
			{
				correspondencesDavidSystem.push_back(pos3);
				state = CalibratingShowViveController;
				viveController->transform().setIdentity();
				scanCamParams = viewer->camera().saveParams();
				viewer->camera().restoreParams(controllerCamParams);
			}
			else
			{
				correspondencesSecondaryController.push_back(pos3);
				state = CalibratingShowScan;
				controllerCamParams = viewer->camera().saveParams();
				viewer->camera().restoreParams(scanCamParams);
			}

			if (correspondencesDavidSystem.size() >= 3 && correspondencesSecondaryController.size() >= 3)
				Calibrate();
		}

		return true;
	}

	return false;
}

void writeALNPart(std::ofstream& file, const std::string& filename, const Eigen::Affine3f& transform)
{
	file << filename << std::endl;
	file << "#" << std::endl;
	file << transform(0, 0) << " " << transform(0, 1) << " " << transform(0, 2) << " " << transform(0, 3) << std::endl;
	file << transform(1, 0) << " " << transform(1, 1) << " " << transform(1, 2) << " " << transform(1, 3) << std::endl;
	file << transform(2, 0) << " " << transform(2, 1) << " " << transform(2, 2) << " " << transform(2, 3) << std::endl;
	file << "0.0 0.0 0.0 1.0" << std::endl;
}

int DavidViveScanLoader::FindOtherController(vr::TrackedDeviceIndex_t controller, vr::TrackedDevicePose_t* poses)
{
	int otherController = -1;
	for (vr::TrackedDeviceIndex_t i = 0; i < vr::k_unMaxTrackedDeviceCount; ++i)
	{
		auto deviceClass = vrSystem->GetTrackedDeviceClass(i);
		if (i != controller && deviceClass == vr::TrackedDeviceClass::TrackedDeviceClass_Controller && poses[i].bPoseIsValid && poses[i].eTrackingResult == vr::ETrackingResult::TrackingResult_Running_OK)
		{
			otherController = i;
			break;
		}
	}

	return otherController;
}

bool DavidViveScanLoader::ToEigenMatrix(const vr::TrackedDevicePose_t& pose, Eigen::Affine3f& m)
{
	if (!pose.bPoseIsValid || pose.eTrackingResult != vr::ETrackingResult::TrackingResult_Running_OK)
	{
		m.linear().setConstant(std::numeric_limits<float>::quiet_NaN());
		return false;
	}

	m.linear() <<
		pose.mDeviceToAbsoluteTracking.m[0][0], pose.mDeviceToAbsoluteTracking.m[0][1], pose.mDeviceToAbsoluteTracking.m[0][2],
		pose.mDeviceToAbsoluteTracking.m[1][0], pose.mDeviceToAbsoluteTracking.m[1][1], pose.mDeviceToAbsoluteTracking.m[1][2],
		pose.mDeviceToAbsoluteTracking.m[2][0], pose.mDeviceToAbsoluteTracking.m[2][1], pose.mDeviceToAbsoluteTracking.m[2][2];

	m.translation() <<
		pose.mDeviceToAbsoluteTracking.m[0][3] * 1000.0f,
		pose.mDeviceToAbsoluteTracking.m[1][3] * 1000.0f,
		pose.mDeviceToAbsoluteTracking.m[2][3] * 1000.0f;

	return true;
}

bool DavidViveScanLoader::waitUntilStill(vr::TrackedDevicePose_t* poses, vr::TrackedDeviceIndex_t device)
{
	vr::TrackedDevicePose_t posesOld[16];
	memcpy(posesOld, poses, 16 * sizeof(vr::TrackedDevicePose_t));

	int stillFrames = 0;
	int unavailableFrames = 0;
	int maxWaitFrames = 100;
	while (stillFrames < 10)
	{
		std::this_thread::sleep_for(std::chrono::milliseconds(100));
		vrSystem->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0, poses, vr::k_unMaxTrackedDeviceCount);

		if (!poses[device].bPoseIsValid || poses[device].eTrackingResult != vr::ETrackingResult::TrackingResult_Running_OK)
		{
			unavailableFrames++;
			if (unavailableFrames > 10)
				return false;
		}
		else
			unavailableFrames = 0;

		bool still = true;
		for(int i = 0; i < 3; ++i)
			for (int j = 0; j < 4; ++j)
			{
				if (std::abs(poses[device].mDeviceToAbsoluteTracking.m[i][j] - posesOld[device].mDeviceToAbsoluteTracking.m[i][j]) > 0.0005f)
				{
					still = false;
					break;
				}
			}

		if (still)
			stillFrames++;
		else
			stillFrames = 0;
		memcpy(posesOld, poses, 16 * sizeof(vr::TrackedDevicePose_t));
	}
	return true;
}

void DavidViveScanLoader::track()
{
	vr::TrackedDevicePose_t poses[16];

	while (tracking)
	{
		//check if the trigger has been pushed
		vr::VREvent_t e;
		while (vrSystem->PollNextEvent(&e, sizeof(e)))
		{
			if (e.eventType == vr::VREvent_ButtonUnpress && (e.data.controller.button == vr::k_EButton_SteamVR_Trigger || e.data.controller.button == vr::k_EButton_ApplicationMenu))
			{
				vrSystem->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0, poses, vr::k_unMaxTrackedDeviceCount);

				int primaryController = e.trackedDeviceIndex;
				int secondaryController = FindOtherController(e.trackedDeviceIndex, poses);

				if (e.data.controller.button == vr::k_EButton_ApplicationMenu)
					std::swap(primaryController, secondaryController);

				std::cout << "Waiting until primary controller stays still..." << std::endl;
				waitUntilStill(poses, primaryController);

				if (!ToEigenMatrix(poses[primaryController], scannerControllerMatrix))
				{
					std::cout << "Could not track primary controller." << std::endl;
					continue;
				}

				if(state == Normal)
				{
					state = Scanning;
					Eigen::Affine3f transformUncalibrated = Eigen::Translation3f(axisCenter) * Eigen::AngleAxisf(-currentAngle * M_PI / 180.0f, axisDirection) * Eigen::Translation3f(-axisCenter) * scannerControllerMatrix;
					Eigen::Affine3f transformCalibrated = adaptAfterCalibration * transformUncalibrated * transformScannerControllerToDavidSystem;
					TakeScan(transformCalibrated);

					currentScan->davidViveData.transformUncalibrated = transformUncalibrated;
					currentScan->davidViveData.turntableRotation = Eigen::AngleAxisf(-currentAngle * M_PI / 180.0f, axisDirection);
					currentScan->davidViveData.davidToVive = scannerControllerMatrix * transformScannerControllerToDavidSystem;

					bool withSecondary = ToEigenMatrix(poses[secondaryController], secondaryControllerMatrix);

					std::ofstream aln("ScanAlignment.aln");
					aln << (withSecondary ? 3 : 2) << std::endl;
					writeALNPart(aln, "controller.ply", scannerControllerMatrix);
					if(withSecondary)
						writeALNPart(aln, "controller.ply", secondaryControllerMatrix);
					writeALNPart(aln, "scan.ply", transformCalibrated);
					aln.close();

					NewScan(currentScan);
					currentScan = nullptr;
					state = Normal;
				}
				else if(state == CalibratingShowScan)
				{
					if (secondaryController == -1)
					{
						std::cout << "Secondary controller is not connected." << std::endl;
						continue;
					}

					std::cout << "Waiting until secondary controller stays still ..." << std::endl;
					waitUntilStill(poses, secondaryController);
					if (!ToEigenMatrix(poses[secondaryController], secondaryControllerMatrix))
					{
						std::cout << "Could not track secondary controller." << std::endl;
						continue;
					}

					correspondencesDavidSystem.clear();
					correspondencesSecondaryController.clear();
					viveController->transform().setIdentity();

					TakeScan(Eigen::Affine3f::Identity());

					viewer->camera().FocusOnBBox(currentScan->boundingBox());
				}
			}

			if (e.eventType == vr::VREvent_ButtonUnpress && e.data.controller.button == vr::k_EButton_SteamVR_Touchpad)
			{
				vr::VRControllerState_t state;
				vrSystem->GetControllerState(e.trackedDeviceIndex, &state);
				currentAngle += turntable.move(30 * (state.rAxis[0].x > 0 ? 1 : -1));
			}

			if (e.eventType == vr::VREvent_ButtonPress && e.data.controller.button == vr::k_EButton_Grip)
			{
				if (state == Normal)
				{
					std::cout << "Entering calibration mode" << std::endl;
					state = CalibratingShowScan;

					auto currentParams = viewer->camera().saveParams();
					viewer->camera().FocusOnBBox(viveController->boundingBox());
					controllerCamParams = viewer->camera().saveParams();
					viewer->camera().restoreParams(currentParams);
				}
				else
				{
					if (state == CalibratingShowScan)
					{
						CalibrateTurntable(e.trackedDeviceIndex);

						state = Normal;
					}
					else
					{
						state = Normal;
					}
				}
			}
		}

		std::this_thread::sleep_for(std::chrono::milliseconds(500));
	}

	vr::VR_Shutdown();

	std::cout << "Stopped tracking ..." << std::endl;
}

void DavidViveScanLoader::TakeScan(const Eigen::Affine3f& transform)
{
	nse::util::TimedBlock b("Scanning ..");

	if (currentScan)
		delete currentScan;
	currentScan = nullptr;

	remove(scanPath.c_str());

	std::string command = "\"" + autoItPath + "\" TakeDavidScan.au3";
	system(command.c_str());

	while (!boost::filesystem::exists(scanPath))
	{
		std::this_thread::sleep_for(std::chrono::milliseconds(500));
	}

	MatrixXu F;
	Matrix3Xf V, N;
	Matrix3Xus C;
	load_ply(scanPath, F, V, N, C, true);

	if (state == Scanning)
	{
		//save scan for later use

		int i = -1;
		boost::filesystem::path savePathPLY;
		boost::format fmtPLY("DavidScan_%04d.ply");
		boost::format fmtALN("DavidScan_%04d.aln");
		boost::format fmtPNG("DavidScan_%04d.png");
		std::string saveFilename;
		do
		{
			++i;
			saveFilename = (fmtPLY % i).str();
			savePathPLY = sessionPath / boost::filesystem::path(saveFilename);
		} while (boost::filesystem::exists(savePathPLY));

		std::rename(scanPath.c_str(), savePathPLY.string().c_str());

		std::string oldPNG = (sessionPath.parent_path() / boost::filesystem::path("currentScan.png")).string();
		std::string newPNG = (sessionPath / boost::filesystem::path((fmtPNG % i).str())).string();
		std::rename(oldPNG.c_str(), newPNG.c_str());

		std::ofstream aln((sessionPath / (fmtALN % i).str()).wstring());
		aln << "1" << std::endl;
		writeALNPart(aln, saveFilename, transform);
		aln.close();

		writeALNPart(fEntireALN, saveFilename, transform);
		scansInALN++;
		fEntireALN.seekp(0, std::ios_base::beg);
		fEntireALN << scansInALN;
		fEntireALN.seekp(0, std::ios_base::end);
	}

	currentScan = new Scan(V, N, C, F, "David Scan", transform);
}

DavidViveScanLoader::~DavidViveScanLoader()
{
	tracking = false;

	if (trackingThread)
		trackingThread->join();

#ifdef WIN32
	turntable.move(-currentAngle); //reset to 0
#endif

	if(viveController)
		delete viveController;

	if (currentScan)
		delete currentScan;

	fEntireALN.close();
	if (scansInALN == 0)
		boost::filesystem::remove_all(sessionPath);
}

void DavidViveScanLoader::Calibrate()
{
	//Kabsch algorithm
	int n = std::min(correspondencesDavidSystem.size(), correspondencesSecondaryController.size());
	if (n < 3)
	{
		std::cout << "Need at least three correspondences for calibration." << std::endl;
		return;
	}

	Eigen::Vector3f X_mean, Y_mean;
	X_mean.setZero(); Y_mean.setZero();
	for (int i = 0; i < n; ++i)
	{
		X_mean += correspondencesSecondaryController[i];
		Y_mean += correspondencesDavidSystem[i];
	}
	X_mean /= n;
	Y_mean /= n;

	/// Compute transformation
	Eigen::Matrix3f sigma; sigma.setConstant(0.0f);
	for (int i = 0; i < n; ++i)
		sigma += (correspondencesSecondaryController[i] - X_mean) * (correspondencesDavidSystem[i] - Y_mean).transpose();
	Eigen::JacobiSVD<Eigen::Matrix3f> svd(sigma, Eigen::ComputeFullU | Eigen::ComputeFullV);
	Eigen::Affine3f transformSecondaryControllerToDavid;
	transformSecondaryControllerToDavid.setIdentity();
	transformSecondaryControllerToDavid.pretranslate(-X_mean);
	Eigen::Affine3f rotation;
	if (svd.matrixU().determinant()*svd.matrixV().determinant() < 0.0) {
		Eigen::Vector3f S = Eigen::Vector3f::Ones(); S(2) = -1.0;
		rotation.linear().noalias() = svd.matrixV()*S.asDiagonal()*svd.matrixU().transpose();
	}
	else {
		rotation.linear().noalias() = svd.matrixV()*svd.matrixU().transpose();
	}
	transformSecondaryControllerToDavid = rotation * transformSecondaryControllerToDavid;
	transformSecondaryControllerToDavid.pretranslate(Y_mean);

	float error = 0;
	for (int i = 0; i < n; ++i)
		error += (correspondencesDavidSystem[i] - transformSecondaryControllerToDavid * correspondencesSecondaryController[i]).norm();
	error /= n;

	std::cout << "Coarse calibration error: " << error << "." << std::endl;

	state = CalibratingShowBoth;

	//fine registration
	viveController->transform() = transformSecondaryControllerToDavid;
	currentScan->buildTree();
	//currentScan->closestPointRadius = 30;
	//viveController->alignTo(*currentScan, 5, 1.0);
	currentScan->closestPointRadius = 10;
	viveController->alignTo(*currentScan, 10, 1.0);

	transformScannerControllerToDavidSystem = scannerControllerMatrix.inverse() * secondaryControllerMatrix * viveController->transform().inverse();

	std::cout << "Controller to Scan registration matrix:" << std::endl << viveController->transform().matrix() << std::endl;

	std::ofstream aln("Calibration.aln");
	aln << 3 << std::endl;
	writeALNPart(aln, "controller.ply", scannerControllerMatrix);
	writeALNPart(aln, "controller.ply", secondaryControllerMatrix);
	writeALNPart(aln, "scan.ply", scannerControllerMatrix * transformScannerControllerToDavidSystem);
	aln.close();

	FILE* f = fopen("calibration.bin", "wb");
	if (f)
	{
		fwrite(transformScannerControllerToDavidSystem.data(), sizeof(float), 16, f);

		fclose(f);
	}

	correspondencesSecondaryController.clear();
	correspondencesDavidSystem.clear();
}

void DavidViveScanLoader::CalibrateTurntable(vr::TrackedDeviceIndex_t device)
{
	vr::TrackedDevicePose_t poses[16];

	//Calibrate rotation axis of turntable
	std::this_thread::sleep_for(std::chrono::milliseconds(1000));
	std::vector<std::pair<double, Eigen::Affine3f>> orientations;
	int steps = 16;
	currentAngle = 0;
	for (int i = 0; i < steps; ++i)
	{
		std::this_thread::sleep_for(std::chrono::milliseconds(200));
		vrSystem->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseStanding, 0, poses, vr::k_unMaxTrackedDeviceCount);
		Eigen::Affine3f t;
		if (ToEigenMatrix(poses[device], t))
			orientations.push_back(std::make_pair(currentAngle, t));
		currentAngle += turntable.move(720 / steps);
	}

	//Calculate the direction of the rotation axis
	axisDirection.setZero();
	int offset = 2;
	for (int i = 0; i + offset < orientations.size(); ++i)
	{
		auto& o1 = orientations[i];
		auto& o2 = orientations[i + offset];
		auto rot = o2.second.linear() * o1.second.linear().transpose();
		Vector3f localAxis(rot(2, 1) - rot(1, 2), rot(0, 2) - rot(2, 0), rot(1, 0) - rot(0, 1));
		//float angle = std::acos(std::min(1.0f, (rot(0, 0) + rot(1, 1) + rot(2, 2) - 1) / 2));
		//if (angle < 0)
		//	localAxis *= -1;
		axisDirection += localAxis.normalized();
	}
	axisDirection.normalize();
	std::cout << axisDirection.transpose() << std::endl;

	//Calculate the location of the rotation axis
	Eigen::Matrix<float, 2, 3> toLocal;
	//toLocal.row(2) = axis;
	toLocal.row(0) = (std::abs(axisDirection.x()) > std::abs(axisDirection.y()) ? Vector3f(0, 1, 0) : Vector3f(1, 0, 0));
	toLocal.row(1) = axisDirection.cross(toLocal.row(0)).normalized();
	toLocal.row(0) = toLocal.row(1).cross(axisDirection).normalized();

	Eigen::Matrix2f systemLHS; systemLHS.setZero();
	Eigen::Vector2f systemRHS; systemRHS.setZero();

	offset = 4;
	for (int i = 0; i + offset < orientations.size(); ++i)
	{
		auto p1 = toLocal * (orientations[i].second * Vector3f(0, 0, 150));
		auto p2 = toLocal * (orientations[i + offset].second * Vector3f(0, 0, 150));

		Vector2f d = (p2 - p1).normalized();
		Vector2f m = 0.5f * (p1 + p2);
		float b = m.dot(d);
		systemLHS += d * d.transpose();
		systemRHS += d * b;
	}
	auto circleCenter = systemLHS.colPivHouseholderQr().solve(systemRHS);
	axisCenter = toLocal.transpose() * circleCenter;
	std::cout << axisCenter.transpose() << std::endl;

	FILE* f = fopen("calibrationTurntable.bin", "wb");
	if (f)
	{
		fwrite(axisDirection.data(), sizeof(float), 3, f);
		fwrite(axisCenter.data(), sizeof(float), 3, f);

		fclose(f);
	}

	std::ofstream ply("turntable.ply", std::ios::binary);
	ply << "format binary_little_endian 1.0" << std::endl;
	ply << "element vertex " << orientations.size() * 4 + 3 << std::endl;
	ply << "property float32 x" << std::endl;
	ply << "property float32 y" << std::endl;
	ply << "property float32 z" << std::endl;
	ply << "element face " << 3 * orientations.size() + 1 << std::endl;
	ply << "property list int32 int32 vertex_index" << std::endl;
	ply << "end_header" << std::endl;

	float scale = 20;
	Vector3f p;
	for (auto& o : orientations)
	{
		p = o.second * Vector3f(0, 0, 0);
		ply.write(reinterpret_cast<const char*>(p.data()), sizeof(Vector3f));
		p = o.second * Vector3f(scale, 0, 0);
		ply.write(reinterpret_cast<const char*>(p.data()), sizeof(Vector3f));
		p = o.second * Vector3f(0, scale, 0);
		ply.write(reinterpret_cast<const char*>(p.data()), sizeof(Vector3f));
		p = o.second * Vector3f(0, 0, scale);
		ply.write(reinterpret_cast<const char*>(p.data()), sizeof(Vector3f));
	}

	p = axisCenter + 200 * axisDirection;
	ply.write(reinterpret_cast<const char*>(p.data()), sizeof(Vector3f));
	ply.write(reinterpret_cast<const char*>(p.data()), sizeof(Vector3f));
	p = axisCenter - 200 * axisDirection;
	ply.write(reinterpret_cast<const char*>(p.data()), sizeof(Vector3f));

	for (int i = 0; i < orientations.size(); ++i)
	{
		int32_t data[] = {3, 4 * i, 4 * i + 1, 4 * i + 2, 3, 4 * i, 4 * i + 2, 4 * i + 3, 3, 4 * i, 4 * i + 1, 4 * i + 3};
		ply.write(reinterpret_cast<const char*>(data), sizeof(data));
	}

	int32_t axis[] = { 3, 4 * orientations.size(), 4 * orientations.size() + 1, 4 * orientations.size() + 2};
	ply.write(reinterpret_cast<const char*>(axis), sizeof(axis));

	ply.close();
}

extension: cpp


text:
package request

type AdminLogin struct {
	Username  string `p:"username" v:"required|length:1,30#请输入用户名称|您输入用户名称长度非法"`
	Password  string `p:"password" v:"required|length:6,30#请输入密码|密码长度为:min到:max位"`
	Captcha   string `json:"captcha" valid:"required#请输入正确的验证码"`
	CaptchaId string `json:"captchaId" valid:"required|length:20,20#请输入captchaId|您输入captchaId长度非法"`
}

repository: SanFenZuiCom/gf-vue-admin

license_type: permissive

repo_name: SanFenZuiCom/gf-vue-admin

branch_name: refs/heads/master

gha_language: Go

extension: go


text:
SUMMARY = "Thin-wrapper around the mock package for easier use with pytest"
HOMEPAGE = "https://github.com/pytest-dev/pytest-mock/"
LICENSE = "MIT"
LIC_FILES_CHKSUM = " \
    file://LICENSE;md5=b2ddb1e69238461b7e4ef2a84d874109 \
"

SRC_URI = " \
    git://github.com/pytest-dev/pytest-mock;branch=main;protocol=https \
    file://run-ptest \
"

SRCREV ?= "d3e73f2e93f7b93eba0a36e17e43bafd969da4fe"

SRC_URI[sha256sum] = "fbbdb085ef7c252a326fd8cdcac0aa3b1333d8811f131bdcc701002e1be7ed4f"

inherit setuptools3 ptest

DEPENDS += "${PYTHON_PN}-setuptools-scm-native"

RDEPENDS:${PN} += " \
    python3-asyncio \
    python3-pytest \
    python3-unittest \
"

S = "${WORKDIR}/git"

do_install_ptest() {
    install -d ${D}${PTEST_PATH}/tests
    cp -rf ${S}/tests ${D}${PTEST_PATH}/
}

repository: openembedded/meta-openembedded

repo_name: openembedded/meta-openembedded

gha_license_id: MIT

gha_language: BitBake

extension: bb


text:
// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2017 The KORE developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "pow.h"

#include "arith_uint256.h"
#include "chain.h"
#include "chainparams.h"
#include "main.h"
#include "primitives/block.h"
#include "uint256.h"
#include "util.h"

#include <math.h>

static arith_uint256 GetTargetLimit_Legacy(int64_t nTime, bool fProofOfStake)
{
    uint256 nLimit = fProofOfStake ? Params().ProofOfStakeLimit() : Params().ProofOfWorkLimit();

    return UintToArith256(nLimit);
}

unsigned int CalculateNextWorkRequired_Legacy(const CBlockIndex* pindexLast, int64_t nFirstBlockTime,  bool fProofOfStake)
{
    int64_t nActualSpacing = pindexLast->GetBlockTime() - nFirstBlockTime;
    int64_t nTargetSpacing = Params().GetTargetSpacing();
    int64_t nTargetTimespan = Params().GetTargetTimespan();

    // Limit adjustment step

    if (nActualSpacing < 0)
        nActualSpacing = nTargetSpacing;

    // Retarget
    const arith_uint256 bnLimit = GetTargetLimit_Legacy(pindexLast->GetBlockTime(), fProofOfStake);
    arith_uint256 bnNew, bnOld;
    if ((Params().GetNetworkID() == CBaseChainParams::TESTNET || Params().GetNetworkID() == CBaseChainParams::UNITTEST) && pindexLast->nHeight < 100) {
        return bnLimit.GetCompact();
    }
    bnNew.SetCompact(pindexLast->nBits);
    bnOld = bnNew;
    bnNew *= (((nTargetTimespan / nTargetSpacing) - 1) * nTargetSpacing + nActualSpacing + nActualSpacing);
    bnNew /= (((nTargetTimespan / nTargetSpacing) + 1) * nTargetSpacing);

    if (bnNew <= 0 || bnNew > bnLimit)
        bnNew = bnLimit;

    if (fDebug) {
        LogPrintf("RETARGET\n");
        LogPrintf("params.nTargetSpacing = %d    nActualSpacing = %d\n", Params().GetTargetSpacing(), nActualSpacing);
        LogPrintf("Before: %08x  %s\n", pindexLast->nBits, bnOld.ToString());
        LogPrintf("After:  %08x  %s\n", bnNew.GetCompact(), bnNew.ToString());
    }

    return bnNew.GetCompact();
}

unsigned int GetNextWorkRequired_Legacy(const CBlockIndex* pindexLast, const CBlockHeader* pblock, bool fProofOfStake)
{
    // Genesis block and first block
    if (pindexLast == NULL || pindexLast->pprev == NULL)
        return UintToArith256(Params().ProofOfWorkLimit()).GetCompact();

    if (pindexLast->nHeight == Params().GetLastPoWBlock())
        return UintToArith256(Params().ProofOfStakeLimit()).GetCompact();

    return CalculateNextWorkRequired_Legacy(pindexLast, pindexLast->GetBlockTime(), fProofOfStake);
}

bool CheckProofOfWork(uint256 hash, unsigned int nBits)
{
    bool fNegative;
    bool fOverflow;
    uint256 bnTarget;

    if (Params().SkipProofOfWorkCheck())
        return true;

    bnTarget.SetCompact(nBits, &fNegative, &fOverflow);

    // Check range
    if (fNegative || bnTarget == 0 || fOverflow || bnTarget > Params().ProofOfWorkLimit()) {
        LogPrintf("CheckProofOfWork() : nBits below minimum work");

        return false;
    }

    if (hash > bnTarget) {
        LogPrintf("CheckProofOfWork() : hash doesn't match nBits");

        return false;
    }

    return true;
}

bool CheckProofOfWork_Legacy(uint256 hash, unsigned int nBits)
{
    bool fNegative;
    bool fOverflow;
    arith_uint256 bnTarget;

    bnTarget.SetCompact(nBits, &fNegative, &fOverflow);

    if (fDebug) {
        LogPrintf("CheckProofOfWork \n");
        LogPrintf("nBits    : %x \n", nBits);
        LogPrintf("hash    : %s \n", UintToArith256(hash).ToString().c_str());
        LogPrintf("bnTarget: %s \n", bnTarget.ToString().c_str());
    }

    // Check range
    if (fNegative || bnTarget == 0 || fOverflow || bnTarget > UintToArith256(Params().ProofOfWorkLimit()))
        return false;

    // Check proof of work matches claimed amount
    if (UintToArith256(hash) > bnTarget)
        return false;

    return true;
}

uint256 GetBlockProof(const CBlockIndex& block)
{
    uint256 bnTarget;
    bool fNegative;
    bool fOverflow;
    bnTarget.SetCompact(block.nBits, &fNegative, &fOverflow);
    if (fNegative || fOverflow || bnTarget == 0)
        return 0;
    // We need to compute 2**256 / (bnTarget+1), but we can't represent 2**256
    // as it's too large for a uint256. However, as 2**256 is at least as large
    // as bnTarget+1, it is equal to ((2**256 - bnTarget - 1) / (bnTarget+1)) + 1,
    // or ~bnTarget / (nTarget+1) + 1.
    return (~bnTarget / (bnTarget + 1)) + 1;
}

license: MIT

repository: Kore-Core/KORE

repo_name: Kore-Core/KORE

gha_language: C


text:
package beanWork

import (
	"testing"
	"github.com/kr/beanstalk"
	"reflect"
)

func getTestBeanTube(conn *beanstalk.Conn,tubeName string)*beanTube{
	return &beanTube{
		conn:conn,
		tubeName:tubeName,
	}
}

func TestGetTubeSet(t *testing.T){

	c:=getTestConnection(t)
	defer c.Close()
	tube := getTestTube(c,t)

	bt := getTestBeanTube(c,tube.Name)

	tsA := bt.getTubeSet()
	tsB := getTestTubeSet(c,tube.Name)

	if !reflect.DeepEqual(tsA,tsB){
		t.Fatalf("FAILED AT %s","DeepEqual")
	}

}

repository: yaronsumel/beanWork

repo_name: yaronsumel/beanWork


text:
// Copyright 2016 The LUCI Authors. All rights reserved.
// Use of this source code is governed under the Apache License, Version 2.0
// that can be found in the LICENSE file.

package utils

import (
	"testing"

	. "github.com/smartystreets/goconvey/convey"
)

func TestZip(t *testing.T) {
	Convey("ZlibCompress/ZlibDecompress roundtrip", t, func() {
		data := "blah-blah"
		for i := 0; i < 10; i++ {
			data += data
		}

		blob, err := ZlibCompress([]byte(data))
		So(err, ShouldBeNil)

		back, err := ZlibDecompress(blob)
		So(err, ShouldBeNil)

		So(back, ShouldResemble, []byte(data))
	})

	Convey("ZlibDecompress garbage", t, func() {
		_, err := ZlibDecompress([]byte("garbage"))
		So(err, ShouldNotBeNil)
	})
}

repository: mithro/luci-go

repo_name: mithro/luci-go


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.1" unitdist="inch" unit="inch" style="dots" multiple="1" display="yes" altdistance="0.05" 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="yes" active="yes"/>
<layer number="30" name="bStop" color="7" fill="6" visible="yes" active="yes"/>
<layer number="31" name="tCream" color="7" fill="4" visible="yes" active="yes"/>
<layer number="32" name="bCream" color="7" fill="5" visible="yes" active="yes"/>
<layer number="33" name="tFinish" color="6" fill="3" visible="yes" active="yes"/>
<layer number="34" name="bFinish" color="6" fill="6" visible="yes" active="yes"/>
<layer number="35" name="tGlue" color="7" fill="4" visible="yes" active="yes"/>
<layer number="36" name="bGlue" color="7" fill="5" visible="yes" active="yes"/>
<layer number="37" name="tTest" color="7" fill="1" visible="yes" active="yes"/>
<layer number="38" name="bTest" color="7" fill="1" visible="yes" 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="yes" active="yes"/>
<layer number="45" name="Holes" color="7" fill="1" visible="yes" active="yes"/>
<layer number="46" name="Milling" color="3" fill="1" visible="yes" active="yes"/>
<layer number="47" name="Measures" color="7" fill="1" visible="yes" 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="yes" active="yes"/>
<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="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="101" name="Hidden" color="15" fill="1" visible="yes" active="yes"/>
<layer number="102" name="Changes" color="12" fill="1" visible="yes" active="yes"/>
<layer number="250" name="Descript" color="3" fill="1" visible="no" active="no"/>
<layer number="251" name="SMDround" color="12" fill="11" visible="no" active="no"/>
</layers>
<board>
<plain>
<wire x1="1.27" y1="35.56" x2="1.27" y2="0.33" width="0" layer="20"/>
<wire x1="1.27" y1="0.33" x2="71.11" y2="0.33" width="0" layer="20"/>
<wire x1="71.11" y1="0.33" x2="71.11" y2="35.56" width="0" layer="20"/>
<wire x1="71.11" y1="35.56" x2="1.27" y2="35.56" width="0" layer="20"/>
<text x="25.4" y="12.7" size="1.778" layer="48" rot="R270">SCK</text>
<text x="22.86" y="12.7" size="1.778" layer="48" rot="R270">MISO</text>
<text x="20.32" y="12.7" size="1.778" layer="48" rot="R270">MOSI</text>
<hole x="48.26" y="15.24" drill="2.2"/>
<hole x="45.72" y="15.24" drill="2.2"/>
<hole x="43.18" y="15.24" drill="2.2"/>
<hole x="40.64" y="15.24" drill="2.2"/>
<hole x="38.1" y="15.24" drill="2.2"/>
<hole x="35.56" y="15.24" drill="2.2"/>
<hole x="33.02" y="17.78" drill="2.2"/>
<hole x="30.48" y="15.24" drill="2.2"/>
<hole x="27.94" y="15.24" drill="2.2"/>
<hole x="25.4" y="15.24" drill="2.2"/>
<hole x="22.86" y="15.24" drill="2.2"/>
<hole x="20.32" y="15.24" drill="2.2"/>
<hole x="17.78" y="15.24" drill="2.2"/>
<hole x="15.24" y="15.24" drill="2.2"/>
<hole x="30.48" y="7.62" drill="2.2"/>
</plain>
<libraries>
<library name="atmel">
<packages>
<package name="DIL28-3">
<description>Dual In Line 0.3 inch</description>
<wire x1="-18.542" y1="-0.635" x2="-18.542" y2="-2.794" width="0.1524" layer="21"/>
<wire x1="-18.542" y1="0.635" x2="-18.542" y2="-0.635" width="0.1524" layer="21" curve="-180"/>
<wire x1="-18.542" y1="-2.794" x2="18.542" y2="-2.794" width="0.1524" layer="21"/>
<wire x1="-18.542" y1="2.794" x2="-18.542" y2="0.635" width="0.1524" layer="21"/>
<wire x1="-18.542" y1="2.794" x2="18.542" y2="2.794" width="0.1524" layer="21"/>
<wire x1="18.542" y1="2.794" x2="18.542" y2="-2.794" width="0.1524" layer="21"/>
<pad name="1" x="-16.51" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="2" x="-13.97" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="3" x="-11.43" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="4" x="-8.89" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="5" x="-6.35" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="6" x="-3.81" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="7" x="-1.27" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="8" x="1.27" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="9" x="3.81" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="10" x="6.35" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="11" x="8.89" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="12" x="11.43" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="13" x="13.97" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="14" x="16.51" y="-3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="15" x="16.51" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="16" x="13.97" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="17" x="11.43" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="18" x="8.89" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="19" x="6.35" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="20" x="3.81" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="21" x="1.27" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="22" x="-1.27" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="23" x="-3.81" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="24" x="-6.35" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="25" x="-8.89" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="26" x="-11.43" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="27" x="-13.97" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<pad name="28" x="-16.51" y="3.81" drill="0.8128" shape="long" rot="R90"/>
<text x="-19.2024" y="-2.54" size="1.778" layer="25" ratio="10" rot="R90">>NAME</text>
<text x="-15.875" y="-0.635" size="1.778" layer="27" ratio="10">>VALUE</text>
</package>
</packages>
</library>
<library name="rcl">
<packages>
<package name="C025-024X044">
<description>CAPACITOR

grid 2.5 mm, outline 2.4 x 4.4 mm</description>
<wire x1="-2.159" y1="-0.635" x2="-2.159" y2="0.635" width="0.1524" layer="21"/>
<wire x1="-2.159" y1="0.635" x2="-1.651" y2="1.143" width="0.1524" layer="21" curve="-90"/>
<wire x1="-2.159" y1="-0.635" x2="-1.651" y2="-1.143" width="0.1524" layer="21" curve="90"/>
<wire x1="1.651" y1="1.143" x2="-1.651" y2="1.143" width="0.1524" layer="21"/>
<wire x1="2.159" y1="-0.635" x2="2.159" y2="0.635" width="0.1524" layer="21"/>
<wire x1="1.651" y1="-1.143" x2="-1.651" y2="-1.143" width="0.1524" layer="21"/>
<wire x1="1.651" y1="1.143" x2="2.159" y2="0.635" width="0.1524" layer="21" curve="-90"/>
<wire x1="1.651" y1="-1.143" x2="2.159" y2="-0.635" width="0.1524" layer="21" curve="90"/>
<wire x1="-0.3048" y1="0.762" x2="-0.3048" y2="-0.762" width="0.3048" layer="21"/>
<wire x1="0.3302" y1="0.762" x2="0.3302" y2="-0.762" width="0.3048" layer="21"/>
<wire x1="1.27" y1="0" x2="0.3302" y2="0" width="0.1524" layer="51"/>
<wire x1="-1.27" y1="0" x2="-0.3048" y2="0" width="0.1524" layer="51"/>
<pad name="1" x="-1.27" y="0" drill="0.8128" shape="octagon"/>
<pad name="2" x="1.27" y="0" drill="0.8128" shape="octagon"/>
<text x="-1.778" y="1.397" size="1.27" layer="25" ratio="10">>NAME</text>
<text x="-1.778" y="-2.667" size="1.27" layer="27" ratio="10">>VALUE</text>
</package>
<package name="C050-025X075">
<description>CAPACITOR

grid 5 mm, outline 2.5 x 7.5 mm</description>
<wire x1="-0.3048" y1="0.635" x2="-0.3048" y2="0" width="0.3048" layer="21"/>
<wire x1="-0.3048" y1="0" x2="-0.3048" y2="-0.635" width="0.3048" layer="21"/>
<wire x1="-0.3048" y1="0" x2="-1.524" y2="0" width="0.1524" layer="21"/>
<wire x1="0.3302" y1="0.635" x2="0.3302" y2="0" width="0.3048" layer="21"/>
<wire x1="0.3302" y1="0" x2="0.3302" y2="-0.635" width="0.3048" layer="21"/>
<wire x1="0.3302" y1="0" x2="1.524" y2="0" width="0.1524" layer="21"/>
<wire x1="-3.683" y1="1.016" x2="-3.683" y2="-1.016" width="0.1524" layer="21"/>
<wire x1="-3.429" y1="-1.27" x2="3.429" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="3.683" y1="-1.016" x2="3.683" y2="1.016" width="0.1524" layer="21"/>
<wire x1="3.429" y1="1.27" x2="-3.429" y2="1.27" width="0.1524" layer="21"/>
<wire x1="3.429" y1="1.27" x2="3.683" y2="1.016" width="0.1524" layer="21" curve="-90"/>
<wire x1="3.429" y1="-1.27" x2="3.683" y2="-1.016" width="0.1524" layer="21" curve="90"/>
<wire x1="-3.683" y1="-1.016" x2="-3.429" y2="-1.27" width="0.1524" layer="21" curve="90"/>
<wire x1="-3.683" y1="1.016" x2="-3.429" y2="1.27" width="0.1524" layer="21" curve="-90"/>
<pad name="1" x="-2.54" y="0" drill="0.8128" shape="octagon"/>
<pad name="2" x="2.54" y="0" drill="0.8128" shape="octagon"/>
<text x="-3.429" y="1.651" size="1.27" layer="25" ratio="10">>NAME</text>
<text x="-3.429" y="-2.794" size="1.27" layer="27" ratio="10">>VALUE</text>
</package>
<package name="0204/5">
<description>RESISTOR

type 0204, grid 5 mm</description>
<wire x1="2.54" y1="0" x2="2.032" y2="0" width="0.508" layer="51"/>
<wire x1="-2.54" y1="0" x2="-2.032" y2="0" width="0.508" layer="51"/>
<wire x1="-1.778" y1="0.635" x2="-1.524" y2="0.889" width="0.1524" layer="21" curve="-90"/>
<wire x1="-1.778" y1="-0.635" x2="-1.524" y2="-0.889" width="0.1524" layer="21" curve="90"/>
<wire x1="1.524" y1="-0.889" x2="1.778" y2="-0.635" width="0.1524" layer="21" curve="90"/>
<wire x1="1.524" y1="0.889" x2="1.778" y2="0.635" width="0.1524" layer="21" curve="-90"/>
<wire x1="-1.778" y1="-0.635" x2="-1.778" y2="0.635" width="0.1524" layer="51"/>
<wire x1="-1.524" y1="0.889" x2="-1.27" y2="0.889" width="0.1524" layer="21"/>
<wire x1="-1.143" y1="0.762" x2="-1.27" y2="0.889" width="0.1524" layer="21"/>
<wire x1="-1.524" y1="-0.889" x2="-1.27" y2="-0.889" width="0.1524" layer="21"/>
<wire x1="-1.143" y1="-0.762" x2="-1.27" y2="-0.889" width="0.1524" layer="21"/>
<wire x1="1.143" y1="0.762" x2="1.27" y2="0.889" width="0.1524" layer="21"/>
<wire x1="1.143" y1="0.762" x2="-1.143" y2="0.762" width="0.1524" layer="21"/>
<wire x1="1.143" y1="-0.762" x2="1.27" y2="-0.889" width="0.1524" layer="21"/>
<wire x1="1.143" y1="-0.762" x2="-1.143" y2="-0.762" width="0.1524" layer="21"/>
<wire x1="1.524" y1="0.889" x2="1.27" y2="0.889" width="0.1524" layer="21"/>
<wire x1="1.524" y1="-0.889" x2="1.27" y2="-0.889" width="0.1524" layer="21"/>
<wire x1="1.778" y1="-0.635" x2="1.778" y2="0.635" width="0.1524" layer="51"/>
<pad name="1" x="-2.54" y="0" drill="0.8128" shape="octagon"/>
<pad name="2" x="2.54" y="0" drill="0.8128" shape="octagon"/>
<text x="-2.0066" y="1.1684" size="0.9906" layer="25" ratio="10">>NAME</text>
<text x="-2.1336" y="-2.3114" size="0.9906" layer="27" ratio="10">>VALUE</text>
<rectangle x1="-2.032" y1="-0.254" x2="-1.778" y2="0.254" layer="51"/>
<rectangle x1="1.778" y1="-0.254" x2="2.032" y2="0.254" layer="51"/>
</package>
<package name="TT2D5">
<description>ELECTROLYTIC CAPACITOR

diameter 5 mm, grid 2.54 mm</description>
<wire x1="-1.016" y1="0" x2="-0.508" y2="0" width="0.1524" layer="51"/>
<wire x1="-0.508" y1="0" x2="-0.508" y2="-0.889" width="0.1524" layer="51"/>
<wire x1="-0.508" y1="-0.889" x2="-0.1778" y2="-0.889" width="0.1524" layer="51"/>
<wire x1="-0.1778" y1="-0.889" x2="-0.1778" y2="0.889" width="0.1524" layer="51"/>
<wire x1="-0.1778" y1="0.889" x2="-0.508" y2="0.889" width="0.1524" layer="51"/>
<wire x1="-0.508" y1="0.889" x2="-0.508" y2="0" width="0.1524" layer="51"/>
<wire x1="0.508" y1="0" x2="1.016" y2="0" width="0.1524" layer="51"/>
<wire x1="-1.27" y1="1.016" x2="-1.27" y2="1.778" width="0.1524" layer="21"/>
<wire x1="-0.889" y1="1.397" x2="-1.651" y2="1.397" width="0.1524" layer="21"/>
<circle x="0" y="0" radius="2.54" width="0.1524" layer="21"/>
<pad name="-" x="1.27" y="0" drill="0.8128" shape="octagon"/>
<pad name="+" x="-1.27" y="0" drill="0.8128"/>
<text x="2.54" y="1.27" size="1.27" layer="25" ratio="10">>NAME</text>
<text x="2.54" y="-2.413" size="1.27" layer="27" ratio="10">>VALUE</text>
<text x="-0.762" y="-2.159" size="0.9906" layer="21" ratio="12">TT</text>
<rectangle x1="0.127" y1="-0.9398" x2="0.5588" y2="0.9398" layer="51"/>
</package>
</packages>
</library>
<library name="crystal">
<packages>
<package name="TC26V">
<description>CRYSTAL</description>
<wire x1="-0.127" y1="-0.508" x2="0.127" y2="-0.508" width="0.1524" layer="51"/>
<wire x1="0.127" y1="0.508" x2="0.127" y2="-0.508" width="0.1524" layer="51"/>
<wire x1="0.127" y1="0.508" x2="-0.127" y2="0.508" width="0.1524" layer="51"/>
<wire x1="-0.127" y1="-0.508" x2="-0.127" y2="0.508" width="0.1524" layer="51"/>
<wire x1="-0.381" y1="-0.508" x2="-0.381" y2="0" width="0.1524" layer="51"/>
<wire x1="0.381" y1="-0.508" x2="0.381" y2="0" width="0.1524" layer="51"/>
<wire x1="0.381" y1="0" x2="0.762" y2="0" width="0.1524" layer="51"/>
<wire x1="0.381" y1="0" x2="0.381" y2="0.508" width="0.1524" layer="51"/>
<wire x1="-0.381" y1="0" x2="-0.762" y2="0" width="0.1524" layer="51"/>
<wire x1="-0.381" y1="0" x2="-0.381" y2="0.508" width="0.1524" layer="51"/>
<wire x1="0" y1="1.016" x2="0.7184" y2="0.7184" width="0.1524" layer="21" curve="-44.999323"/>
<wire x1="-0.7184" y1="0.7184" x2="0" y2="1.016" width="0.1524" layer="21" curve="-44.999323"/>
<wire x1="-0.7184" y1="-0.7184" x2="0" y2="-1.016" width="0.1524" layer="21" curve="44.999323"/>
<wire x1="0" y1="-1.016" x2="0.7184" y2="-0.7184" width="0.1524" layer="21" curve="44.999323"/>
<circle x="0" y="0" radius="1.016" width="0.1524" layer="51"/>
<pad name="1" x="-1.27" y="0" drill="0.8128"/>
<pad name="2" x="1.27" y="0" drill="0.8128"/>
<text x="-2.032" y="1.397" size="1.27" layer="25" ratio="10">>NAME</text>
<text x="-2.032" y="-2.667" size="1.27" layer="27" ratio="10">>VALUE</text>
</package>
</packages>
</library>
<library name="con-lstb">
<description>Pin Headers

Naming:

MA = male

# contacts - # rows

W = angled

<author>Created by librarian@cadsoft.de</author></description>
<packages>
<package name="MA06-1">
<description>PIN HEADER</description>
<wire x1="-6.985" y1="1.27" x2="-5.715" y2="1.27" width="0.1524" layer="21"/>
<wire x1="-5.715" y1="1.27" x2="-5.08" y2="0.635" width="0.1524" layer="21"/>
<wire x1="-5.08" y1="-0.635" x2="-5.715" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="-5.08" y1="0.635" x2="-4.445" y2="1.27" width="0.1524" layer="21"/>
<wire x1="-4.445" y1="1.27" x2="-3.175" y2="1.27" width="0.1524" layer="21"/>
<wire x1="-3.175" y1="1.27" x2="-2.54" y2="0.635" width="0.1524" layer="21"/>
<wire x1="-2.54" y1="-0.635" x2="-3.175" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="-3.175" y1="-1.27" x2="-4.445" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="-4.445" y1="-1.27" x2="-5.08" y2="-0.635" width="0.1524" layer="21"/>
<wire x1="-7.62" y1="0.635" x2="-7.62" y2="-0.635" width="0.1524" layer="21"/>
<wire x1="-6.985" y1="1.27" x2="-7.62" y2="0.635" width="0.1524" layer="21"/>
<wire x1="-7.62" y1="-0.635" x2="-6.985" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="-5.715" y1="-1.27" x2="-6.985" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="-2.54" y1="0.635" x2="-1.905" y2="1.27" width="0.1524" layer="21"/>
<wire x1="-1.905" y1="1.27" x2="-0.635" y2="1.27" width="0.1524" layer="21"/>
<wire x1="-0.635" y1="1.27" x2="0" y2="0.635" width="0.1524" layer="21"/>
<wire x1="0" y1="-0.635" x2="-0.635" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="-0.635" y1="-1.27" x2="-1.905" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="-1.905" y1="-1.27" x2="-2.54" y2="-0.635" width="0.1524" layer="21"/>
<wire x1="0.635" y1="1.27" x2="1.905" y2="1.27" width="0.1524" layer="21"/>
<wire x1="1.905" y1="1.27" x2="2.54" y2="0.635" width="0.1524" layer="21"/>
<wire x1="2.54" y1="-0.635" x2="1.905" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="2.54" y1="0.635" x2="3.175" y2="1.27" width="0.1524" layer="21"/>
<wire x1="3.175" y1="1.27" x2="4.445" y2="1.27" width="0.1524" layer="21"/>
<wire x1="4.445" y1="1.27" x2="5.08" y2="0.635" width="0.1524" layer="21"/>
<wire x1="5.08" y1="-0.635" x2="4.445" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="4.445" y1="-1.27" x2="3.175" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="3.175" y1="-1.27" x2="2.54" y2="-0.635" width="0.1524" layer="21"/>
<wire x1="0.635" y1="1.27" x2="0" y2="0.635" width="0.1524" layer="21"/>
<wire x1="0" y1="-0.635" x2="0.635" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="1.905" y1="-1.27" x2="0.635" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="5.08" y1="0.635" x2="5.715" y2="1.27" width="0.1524" layer="21"/>
<wire x1="5.715" y1="1.27" x2="6.985" y2="1.27" width="0.1524" layer="21"/>
<wire x1="6.985" y1="1.27" x2="7.62" y2="0.635" width="0.1524" layer="21"/>
<wire x1="7.62" y1="-0.635" x2="6.985" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="6.985" y1="-1.27" x2="5.715" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="5.715" y1="-1.27" x2="5.08" y2="-0.635" width="0.1524" layer="21"/>
<wire x1="7.62" y1="0.635" x2="7.62" y2="-0.635" width="0.1524" layer="21"/>
<pad name="1" x="-6.35" y="0" drill="1.016" shape="long" rot="R90"/>
<pad name="2" x="-3.81" y="0" drill="1.016" shape="long" rot="R90"/>
<pad name="3" x="-1.27" y="0" drill="1.016" shape="long" rot="R90"/>
<pad name="4" x="1.27" y="0" drill="1.016" shape="long" rot="R90"/>
<pad name="5" x="3.81" y="0" drill="1.016" shape="long" rot="R90"/>
<pad name="6" x="6.35" y="0" drill="1.016" shape="long" rot="R90"/>
<text x="-7.62" y="1.651" size="1.27" layer="25" ratio="10">>NAME</text>
<text x="-6.985" y="-2.921" size="1.27" layer="21" ratio="10">1</text>
<text x="5.715" y="1.651" size="1.27" layer="21" ratio="10">6</text>
<text x="-2.54" y="-2.921" size="1.27" layer="27" ratio="10">>VALUE</text>
<rectangle x1="-4.064" y1="-0.254" x2="-3.556" y2="0.254" layer="51"/>
<rectangle x1="-6.604" y1="-0.254" x2="-6.096" y2="0.254" layer="51"/>
<rectangle x1="-1.524" y1="-0.254" x2="-1.016" y2="0.254" layer="51"/>
<rectangle x1="3.556" y1="-0.254" x2="4.064" y2="0.254" layer="51"/>
<rectangle x1="1.016" y1="-0.254" x2="1.524" y2="0.254" layer="51"/>
<rectangle x1="6.096" y1="-0.254" x2="6.604" y2="0.254" layer="51"/>
</package>
<package name="MA04-1">
<description>PIN HEADER</description>
<wire x1="-4.445" y1="1.27" x2="-3.175" y2="1.27" width="0.1524" layer="21"/>
<wire x1="-3.175" y1="1.27" x2="-2.54" y2="0.635" width="0.1524" layer="21"/>
<wire x1="-2.54" y1="-0.635" x2="-3.175" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="-2.54" y1="0.635" x2="-1.905" y2="1.27" width="0.1524" layer="21"/>
<wire x1="-1.905" y1="1.27" x2="-0.635" y2="1.27" width="0.1524" layer="21"/>
<wire x1="-0.635" y1="1.27" x2="0" y2="0.635" width="0.1524" layer="21"/>
<wire x1="0" y1="-0.635" x2="-0.635" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="-0.635" y1="-1.27" x2="-1.905" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="-1.905" y1="-1.27" x2="-2.54" y2="-0.635" width="0.1524" layer="21"/>
<wire x1="-5.08" y1="0.635" x2="-5.08" y2="-0.635" width="0.1524" layer="21"/>
<wire x1="-4.445" y1="1.27" x2="-5.08" y2="0.635" width="0.1524" layer="21"/>
<wire x1="-5.08" y1="-0.635" x2="-4.445" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="-3.175" y1="-1.27" x2="-4.445" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="0" y1="0.635" x2="0.635" y2="1.27" width="0.1524" layer="21"/>
<wire x1="0.635" y1="1.27" x2="1.905" y2="1.27" width="0.1524" layer="21"/>
<wire x1="1.905" y1="1.27" x2="2.54" y2="0.635" width="0.1524" layer="21"/>
<wire x1="2.54" y1="-0.635" x2="1.905" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="1.905" y1="-1.27" x2="0.635" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="0.635" y1="-1.27" x2="0" y2="-0.635" width="0.1524" layer="21"/>
<wire x1="3.175" y1="1.27" x2="4.445" y2="1.27" width="0.1524" layer="21"/>
<wire x1="4.445" y1="1.27" x2="5.08" y2="0.635" width="0.1524" layer="21"/>
<wire x1="5.08" y1="0.635" x2="5.08" y2="-0.635" width="0.1524" layer="21"/>
<wire x1="5.08" y1="-0.635" x2="4.445" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="3.175" y1="1.27" x2="2.54" y2="0.635" width="0.1524" layer="21"/>
<wire x1="2.54" y1="-0.635" x2="3.175" y2="-1.27" width="0.1524" layer="21"/>
<wire x1="4.445" y1="-1.27" x2="3.175" y2="-1.27" width="0.1524" layer="21"/>
<pad name="1" x="-3.81" y="0" drill="1.016" shape="long" rot="R90"/>
<pad name="2" x="-1.27" y="0" drill="1.016" shape="long" rot="R90"/>
<pad name="3" x="1.27" y="0" drill="1.016" shape="long" rot="R90"/>
<pad name="4" x="3.81" y="0" drill="1.016" shape="long" rot="R90"/>
<text x="-5.08" y="1.651" size="1.27" layer="25" ratio="10">>NAME</text>
<text x="-6.223" y="-0.635" size="1.27" layer="21" ratio="10">1</text>
<text x="0.635" y="1.651" size="1.27" layer="27" ratio="10">>VALUE</text>
<text x="5.334" y="-0.635" size="1.27" layer="21" ratio="10">4</text>
<rectangle x1="-1.524" y1="-0.254" x2="-1.016" y2="0.254" layer="51"/>
<rectangle x1="-4.064" y1="-0.254" x2="-3.556" y2="0.254" layer="51"/>
<rectangle x1="1.016" y1="-0.254" x2="1.524" y2="0.254" layer="51"/>
<rectangle x1="3.556" y1="-0.254" x2="4.064" y2="0.254" layer="51"/>
</package>
</packages>
</library>
<library name="jumper">
<description>Jumpers

<author>Created by librarian@cadsoft.de</author></description>
<packages>
<package name="JP1">
<description>JUMPER</description>
<wire x1="-1.016" y1="0" x2="-1.27" y2="0.254" width="0.1524" layer="21"/>
<wire x1="-1.016" y1="0" x2="-1.27" y2="-0.254" width="0.1524" layer="21"/>
<wire x1="1.016" y1="0" x2="1.27" y2="0.254" width="0.1524" layer="21"/>
<wire x1="1.016" y1="0" x2="1.27" y2="-0.254" width="0.1524" layer="21"/>
<wire x1="1.27" y1="-0.254" x2="1.27" y2="-2.286" width="0.1524" layer="21"/>
<wire x1="1.016" y1="-2.54" x2="1.27" y2="-2.286" width="0.1524" layer="21"/>
<wire x1="1.27" y1="2.286" x2="1.016" y2="2.54" width="0.1524" layer="21"/>
<wire x1="1.27" y1="2.286" x2="1.27" y2="0.254" width="0.1524" layer="21"/>
<wire x1="1.016" y1="2.54" x2="-1.016" y2="2.54" width="0.1524" layer="21"/>
<wire x1="-1.27" y1="2.286" x2="-1.016" y2="2.54" width="0.1524" layer="21"/>
<wire x1="-1.27" y1="2.286" x2="-1.27" y2="0.254" width="0.1524" layer="21"/>
<wire x1="-1.27" y1="-0.254" x2="-1.27" y2="-2.286" width="0.1524" layer="21"/>
<wire x1="-1.016" y1="-2.54" x2="-1.27" y2="-2.286" width="0.1524" layer="21"/>
<wire x1="-1.016" y1="-2.54" x2="1.016" y2="-2.54" width="0.1524" layer="21"/>
<pad name="1" x="0" y="-1.27" drill="0.9144" shape="long"/>
<pad name="2" x="0" y="1.27" drill="0.9144" shape="long"/>
<text x="-1.651" y="-2.54" size="1.27" layer="25" ratio="10" rot="R90">>NAME</text>
<text x="2.921" y="-2.54" size="1.27" layer="27" ratio="10" rot="R90">>VALUE</text>
<rectangle x1="-0.3048" y1="0.9652" x2="0.3048" y2="1.5748" layer="51"/>
<rectangle x1="-0.3048" y1="-1.5748" x2="0.3048" y2="-0.9652" 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="50mil"/>
<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>
</autorouter>
<elements>
<element name="IC1" library="atmel" package="DIL28-3" value="" x="31.75" y="16.51" rot="R180"/>
<element name="C4" library="rcl" package="C025-024X044" value="22p" x="29.21" y="25.4" rot="R180"/>
<element name="C5" library="rcl" package="C050-025X075" value="22p" x="27.94" y="27.94" rot="R180"/>
<element name="Q1" library="crystal" package="TC26V" value="16MHz" x="26.67" y="22.86"/>
<element name="C3" library="rcl" package="C025-024X044" value="100n" x="31.75" y="22.86" rot="R180"/>
<element name="R6" library="rcl" package="0204/5" value="10k" x="50.8" y="25.4" rot="R180"/>
<element name="C2" library="rcl" package="C025-024X044" value="100n" x="31.75" y="10.16" rot="R180"/>
<element name="SV1" library="con-lstb" package="MA06-1" value="ISP" x="26.67" y="2.54" rot="R180">
<attribute name="OC_NEWARK" value="unknown" x="26.67" y="2.54" size="1.778" layer="27" rot="R180" display="off"/>
<attribute name="MPN" value="" x="26.67" y="2.54" size="1.778" layer="27" rot="R180" display="off"/>
<attribute name="MF" value="" x="26.67" y="2.54" size="1.778" layer="27" rot="R180" display="off"/>
<attribute name="OC_FARNELL" value="unknown" x="26.67" y="2.54" size="1.778" layer="27" rot="R180" display="off"/>
</element>
<element name="C6" library="rcl" package="TT2D5" value="4u7" x="11.43" y="22.86" rot="R180"/>
<element name="JP2" library="jumper" package="JP1" value="" x="11.43" y="5.08" rot="R90"/>
<element name="LCD" library="con-lstb" package="MA04-1" value="" x="44.45" y="2.54" rot="R180">
<attribute name="OC_NEWARK" value="unknown" x="44.45" y="2.54" size="1.778" layer="27" rot="R180" display="off"/>
<attribute name="MPN" value="" x="44.45" y="2.54" size="1.778" layer="27" rot="R180" display="off"/>
<attribute name="MF" value="" x="44.45" y="2.54" size="1.778" layer="27" rot="R180" display="off"/>
<attribute name="OC_FARNELL" value="unknown" x="44.45" y="2.54" size="1.778" layer="27" rot="R180" display="off"/>
</element>
</elements>
<signals>
<signal name="N$22">
<contactref element="IC1" pad="9"/>
<contactref element="Q1" pad="2"/>
<contactref element="C4" pad="2"/>
<wire x1="27.94" y1="22.86" x2="27.94" y2="25.4" width="0.4064" layer="16"/>
<wire x1="27.94" y1="25.4" x2="27.94" y2="20.32" width="0.4064" layer="16"/>
</signal>
<signal name="N$23">
<contactref element="IC1" pad="10"/>
<contactref element="Q1" pad="1"/>
<contactref element="C5" pad="2"/>
<wire x1="25.4" y1="27.94" x2="25.4" y2="20.32" width="0.4064" layer="16"/>
<wire x1="25.4" y1="22.86" x2="25.4" y2="27.94" width="0.4064" layer="16"/>
</signal>
<signal name="MOSI">
<contactref element="IC1" pad="17"/>
<contactref element="SV1" pad="6"/>
<wire x1="20.32" y1="2.54" x2="20.32" y2="12.7" width="0.4064" layer="16"/>
</signal>
<signal name="SCK">
<contactref element="IC1" pad="19"/>
<contactref element="SV1" pad="4"/>
<wire x1="25.4" y1="2.54" x2="25.4" y2="12.7" width="0.4064" layer="16"/>
</signal>
<signal name="MISO">
<contactref element="IC1" pad="18"/>
<contactref element="SV1" pad="5"/>
<wire x1="22.86" y1="12.7" x2="22.86" y2="2.54" width="0.4064" layer="16"/>
</signal>
<signal name="RST">
<contactref element="IC1" pad="1"/>
<contactref element="R6" pad="2"/>
<contactref element="SV1" pad="2"/>
<wire x1="30.48" y1="2.54" x2="30.48" y2="5.08" width="0.4064" layer="16"/>
<wire x1="48.26" y1="22.86" x2="48.26" y2="20.32" width="0.4064" layer="16"/>
<via x="48.26" y="22.86" extent="1-16" drill="0.6" shape="square"/>
<via x="30.48" y="5.08" extent="1-16" drill="0.6" shape="square"/>
<wire x1="48.26" y1="22.86" x2="49.53" y2="22.86" width="0.4064" layer="1"/>
<wire x1="49.53" y1="22.86" x2="54.61" y2="20.32" width="0.4064" layer="1"/>
<wire x1="54.61" y1="20.32" x2="54.61" y2="5.08" width="0.4064" layer="1"/>
<wire x1="54.61" y1="5.08" x2="30.48" y2="5.08" width="0.4064" layer="1"/>
<wire x1="48.26" y1="25.4" x2="48.26" y2="22.86" width="0.4064" layer="16"/>
</signal>
<signal name="N$1">
<contactref element="IC1" pad="21"/>
<contactref element="C2" pad="2"/>
<wire x1="30.48" y1="12.7" x2="30.48" y2="10.16" width="0.4064" layer="16"/>
</signal>
<signal name="GND">
<contactref element="C3" pad="2"/>
<contactref element="C5" pad="1"/>
<contactref element="IC1" pad="8"/>
<contactref element="IC1" pad="22"/>
<contactref element="C2" pad="1"/>
<contactref element="C4" pad="1"/>
<wire x1="33.02" y1="15.24" x2="33.02" y2="12.7" width="0.4064" layer="16"/>
<wire x1="30.48" y1="20.32" x2="30.48" y2="17.78" width="0.4064" layer="16"/>
<wire x1="30.48" y1="17.78" x2="33.02" y2="15.24" width="0.4064" layer="1"/>
<wire x1="30.48" y1="22.86" x2="30.48" y2="20.32" width="0.4064" layer="16"/>
<wire x1="30.48" y1="27.94" x2="30.48" y2="22.86" width="0.4064" layer="16"/>
<wire x1="30.48" y1="25.4" x2="30.48" y2="27.94" width="0.4064" layer="16"/>
<via x="33.02" y="15.24" extent="1-16" drill="0.6" shape="square"/>
<via x="30.48" y="17.78" extent="1-16" drill="0.6" shape="square"/>
<contactref element="SV1" pad="1"/>
<contactref element="JP2" pad="2"/>
<wire x1="10.16" y1="22.86" x2="10.16" y2="7.62" width="0.4064" layer="16"/>
<wire x1="10.16" y1="7.62" x2="10.16" y2="5.08" width="0.4064" layer="16"/>
<wire x1="33.02" y1="2.54" x2="33.02" y2="7.62" width="0.4064" layer="16"/>
<wire x1="33.02" y1="7.62" x2="33.02" y2="10.16" width="0.4064" layer="16"/>
<wire x1="33.02" y1="10.16" x2="33.02" y2="12.7" width="0.4064" layer="16"/>
<contactref element="C6" pad="-"/>
<via x="33.02" y="7.62" extent="1-16" drill="0.6" shape="square"/>
<via x="10.16" y="7.62" extent="1-16" drill="0.6" shape="square"/>
<wire x1="33.02" y1="7.62" x2="10.16" y2="7.62" width="0.4064" layer="1"/>
<contactref element="LCD" pad="4"/>
<wire x1="33.02" y1="2.54" x2="40.64" y2="2.54" width="0" layer="19" extent="1-1"/>
</signal>
<signal name="+5V">
<contactref element="IC1" pad="7"/>
<contactref element="C3" pad="1"/>
<contactref element="R6" pad="1"/>
<contactref element="IC1" pad="20"/>
<wire x1="33.02" y1="22.86" x2="33.02" y2="20.32" width="0.4064" layer="16"/>
<wire x1="12.7" y1="22.86" x2="12.7" y2="10.16" width="0.4064" layer="16"/>
<wire x1="12.7" y1="10.16" x2="27.94" y2="10.16" width="0.4064" layer="1"/>
<via x="33.02" y="25.4" extent="1-16" drill="0.6" shape="square"/>
<via x="27.94" y="10.16" extent="1-16" drill="0.6" shape="square"/>
<via x="12.7" y="10.16" extent="1-16" drill="0.6" shape="square"/>
<contactref element="SV1" pad="3"/>
<wire x1="27.94" y1="10.16" x2="27.94" y2="2.54" width="0.4064" layer="16"/>
<contactref element="JP2" pad="1"/>
<wire x1="12.7" y1="5.08" x2="12.7" y2="10.16" width="0.4064" layer="16"/>
<wire x1="27.94" y1="12.7" x2="27.94" y2="10.16" width="0.4064" layer="16"/>
<contactref element="C6" pad="+"/>
<wire x1="53.34" y1="22.86" x2="53.34" y2="10.16" width="0.4064" layer="16"/>
<via x="53.34" y="22.86" extent="1-16" drill="0.6" shape="square"/>
<wire x1="33.02" y1="25.4" x2="33.02" y2="22.86" width="0.4064" layer="16"/>
<wire x1="53.34" y1="22.86" x2="53.34" y2="25.4" width="0.4064" layer="16"/>
<wire x1="33.02" y1="25.4" x2="34.29" y2="24.13" width="0.4064" layer="1"/>
<wire x1="34.29" y1="24.13" x2="52.07" y2="24.13" width="0.4064" layer="1"/>
<wire x1="52.07" y1="24.13" x2="53.34" y2="22.86" width="0.4064" layer="1"/>
<via x="53.34" y="10.16" extent="1-16" drill="0.6" shape="square"/>
<wire x1="27.94" y1="10.16" x2="29.21" y2="11.43" width="0.4064" layer="1"/>
<wire x1="29.21" y1="11.43" x2="52.07" y2="11.43" width="0.4064" layer="1"/>
<wire x1="52.07" y1="11.43" x2="53.34" y2="10.16" width="0.4064" layer="1"/>
<contactref element="LCD" pad="3"/>
<wire x1="52.07" y1="11.43" x2="43.18" y2="2.54" width="0" layer="19" extent="1-1"/>
</signal>
<signal name="F">
<contactref element="IC1" pad="14"/>
<contactref element="IC1" pad="11"/>
<wire x1="22.86" y1="20.32" x2="22.86" y2="22.86" width="0.4064" layer="16"/>
<wire x1="15.24" y1="20.32" x2="15.24" y2="22.86" width="0.4064" layer="16"/>
<via x="22.86" y="22.86" extent="1-16" drill="0.6" shape="square"/>
<via x="15.24" y="22.86" extent="1-16" drill="0.6" shape="square"/>
<wire x1="22.86" y1="22.86" x2="15.24" y2="22.86" width="0.4064" layer="1"/>
</signal>
<signal name="SDA">
<contactref element="IC1" pad="27"/>
<contactref element="LCD" pad="2"/>
<wire x1="45.72" y1="12.7" x2="45.72" y2="2.54" width="0.4064" layer="16"/>
</signal>
<signal name="SCL">
<contactref element="IC1" pad="28"/>
<contactref element="LCD" pad="1"/>
<wire x1="48.26" y1="12.7" x2="48.26" y2="2.54" width="0.4064" layer="16"/>
</signal>
</signals>
</board>
</drawing>
</eagle>

repository: Jaceksto/MyElectronicProjects

repo_name: Jaceksto/MyElectronicProjects

extension: brd


text:
SUMMARY = "Sigma WFA agent"
DESCRIPTION = "Sigma WFA agent tool used for Wifi pre-certification"
SECTION = "test-tools"
LICENSE = "CLOSED"

PV = "r4.0"
PR = "0"

S = "${EDISONREPO_TOP_DIR}/test_tools/PRIVATE/wfa_tool"

do_install() {
    install -v -d  ${D}/usr/sbin/
    install -m 0755 ${B}/ca/wfa_ca ${D}/usr/sbin
    install -m 0755 ${B}/dut/wfa_dut ${D}/usr/sbin
    install -m 0755 ${S}/scripts/wfa_send_ping ${D}/usr/sbin
    install -m 0755 ${S}/scripts/wfa_send_ping6 ${D}/usr/sbin
    install -m 0755 ${S}/scripts/wfa_service ${D}/usr/sbin
    install -m 0755 ${S}/scripts/wfa_start_iperf ${D}/usr/sbin
    install -m 0755 ${S}/scripts/wfa_stop_iperf ${D}/usr/sbin
    install -m 0755 ${S}/scripts/wfa_stop_ping ${D}/usr/sbin
    install -m 0755 ${S}/scripts/wfa_start_dhcp_client ${D}/usr/sbin
    install -m 0755 ${S}/scripts/wfa_stop_dhcp_client ${D}/usr/sbin

    install -v -d ${D}${sysconfdir}/sigma
    install -m 644 ${S}/certificates/cas.pem ${D}${sysconfdir}/sigma
    install -m 644 ${S}/certificates/root.pem  ${D}${sysconfdir}/sigma
    install -m 644 ${S}/certificates/wifiuser.pem ${D}${sysconfdir}/sigma
    install -m 644 ${S}/certificates/fast-mschapv2.pac  ${D}${sysconfdir}/sigma
}

do_clean() {
    make clean
}

repository: TeamElevate/edison

repo_name: TeamElevate/edison


text:
// Package cmd offers CLI functionality
package cmd

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"
	"strings"
	"testing"

	"github.com/mateimicu/kdiscover/internal/aws"
	log "github.com/sirupsen/logrus"
	"github.com/sirupsen/logrus/hooks/test"
)

type testCase struct {
	Cmd        []string
	Partitions []string
}

var cases []testCase = []testCase{
	{[]string{"aws", "list"}, []string{"aws"}},
	{[]string{"aws", "list"}, []string{"aws-cn"}},
	{[]string{"aws", "list"}, []string{"aws-iso-b"}},
	{[]string{"aws", "list"}, []string{"aws", "aws-cn"}},
	{[]string{"aws", "list"}, []string{"aws-us-gov", "aws-iso", "aws-iso-b"}},
	{[]string{"aws", "list"}, []string{"aws", "aws-cn", "aws-us-gov", "aws-iso", "aws-iso-b"}},
	{[]string{"aws", "update"}, []string{"aws"}},
	{[]string{"aws", "update"}, []string{"aws-cn"}},
	{[]string{"aws", "update"}, []string{"aws-iso-b"}},
	{[]string{"aws", "update"}, []string{"aws", "aws-cn"}},
	{[]string{"aws", "update"}, []string{"aws-us-gov", "aws-iso", "aws-iso-b"}},
	{[]string{"aws", "update"}, []string{"aws", "aws-cn", "aws-us-gov", "aws-iso", "aws-iso-b"}},
}

func TestQueryAllRegions(t *testing.T) {
	for _, tt := range cases {
		testname := fmt.Sprintf("command %v", tt.Partitions)
		t.Run(testname, func(t *testing.T) {
			dir, err := ioutil.TempDir("", ".kube")
			if err != nil {
				t.Error(err.Error())
			}
			defer os.RemoveAll(dir)
			kubeconfigPath := filepath.Join(dir, "kubeconfig")

			cmd := NewRootCommand("", "", "")
			buf := new(strings.Builder)
			cmd.SetOut(buf)
			cmd.SetErr(buf)
			log.SetOutput(ioutil.Discard)
			defer func() { log.SetOutput(os.Stdout) }()
			hook := test.NewGlobal()
			defer hook.Reset()
			args := append(tt.Cmd, []string{
				"--log-level", "debug",
				"--kubeconfig-path", kubeconfigPath,
				"--aws-partitions", strings.Join(tt.Partitions, ","),
			}...)

			cmd.SetArgs(args)
			err = cmd.Execute()
			if err != nil {
				t.Error(err.Error())
			}

			expectedLogs := make(map[string]bool)
			for _, region := range aws.GetRegions(tt.Partitions) {
				expectedLogs[region] = false
			}
			for _, e := range hook.AllEntries() {
				if v, ok := e.Data["region"]; ok {
					expectedLogs[fmt.Sprintf("%v", v)] = true
				}
			}

			for k, v := range expectedLogs {
				if !v {
					t.Errorf("Could not find log for %v", k)
				}
			}
		})
	}
}

repository: fossabot/kdiscover

repo_name: fossabot/kdiscover


text:
package docker

const (
	ACRegistry   = "appscode"
	ImageStash   = "stash"
	ImageKubectl = "kubectl"
)

type Docker struct {
	Registry, Image, Tag string
}

func (docker Docker) ToContainerImage() string {
	return docker.Registry + "/" + docker.Image + ":" + docker.Tag
}

repository: mcanevet/stash

repo_name: mcanevet/stash


text:
package sidh

import (
	"bufio"
	"bytes"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"io"
	"os"
	"strings"
	"testing"

	"github.com/cloudflare/circl/dh/sidh/internal/common"
	. "github.com/cloudflare/circl/internal/test"
)

type sikeVec struct {
	id      uint8
	name    string
	kem     *KEM
	KatFile string
	PkB     string
	PrB     string
}

var tdataSike = map[uint8]sikeVec{
	Fp434: {
		Fp434, "P-434", NewSike434(rand.Reader),
		"testdata/PQCkemKAT_374.rsp",
		"1BD0A2E81307B6F96461317DDF535ACC0E59C742627BAE60D27605E10FAF722D" +
			"22A73E184CB572A12E79DCD58C6B54FB01442114CBE9010B6CAEC25D04C16C5E" +
			"42540C1524C545B8C67614ED4183C9FA5BD0BE45A7F89FBC770EE8E7E5E391C7" +
			"EE6F35F74C29E6D9E35B1663DA01E48E9DEB2347512D366FDE505161677055E3" +
			"EF23054D276E817E2C57025DA1C10D2461F68617F2D11256EEE4E2D7DBDF6C8E" +
			"34F3A0FD00C625428CB41857002159DAB94267ABE42D630C6AAA91AF837C7A67" +
			"40754EA6634C45454C51B0BB4D44C3CCCCE4B32C00901CF69C008D013348379B" +
			"2F9837F428A01B6173584691F2A6F3A3C4CF487D20D261B36C8CDB1BC158E2A5" +
			"162A9DA4F7A97AA0879B9897E2B6891B672201F9AEFBF799C27B2587120AC586" +
			"A511360926FB7DA8EBF5CB5272F396AE06608422BE9792E2CE9BEF21BF55B7EF" +
			"F8DC7EC8C99910D3F800",
		"4B622DE1350119C45A9F2E2EF3DC5DF56A27FCDFCDDAF58CD69B903752D68C20" +
			"0934E160B234E49EDE247601",
	},
	Fp503: {
		Fp503, "P-503", NewSike503(rand.Reader),
		"testdata/PQCkemKAT_434.rsp",
		"4032A90B6C036B7D2A83878AD116641AD319E420235A505F3F5C3DEC27C87A6C" +
			"BA0792201D6E7B196C582D43CAF86CB2C7DEFA6598B543C946CDDF62EF9A328C" +
			"8719B66BA5052231DAE13AF7D9CDEBB4ED327773C7AE0818F41AF1D28CD78B16" +
			"C996232528235C8392B8FCFD925CB311B2A801B0402A90E527261EA32F2BEF67" +
			"7C544908D5509B8AB7D7BF20456727AD358AD585306A0B28F6B2AA583CE8A3E0" +
			"BB92D8CD55347D39D4E3C30D3D0F96EABB721A6968CDD143FE9227643CF697FB" +
			"2DF0B71322B5EA1505D0DDBF70A2FD1193011F3BC18AA1E127C614B76969DCDA" +
			"45A2072B519A1074FDA49F5C828450C6A007BF8D7CDDD5D2FC112119C679CA3A" +
			"B16C6960B25F6C681A7DCED0F0E3901740D3DBF3A33011EB7DA460E8ADA80EE3" +
			"45B2B71420950A9A803E4F11330EB91CCABB1EEE4D875A109D7724ABD201272C" +
			"0B4981BDCDFA70F3430A89D2A88EEED474CF0CFAC65CE883F44B4722FA280C6F" +
			"A9C4724D414B35AF69D6ECB21BFDA23BFF6B66C22C2451DC8E1C",
		"7BF6938C975658AEB8B4D37CFFBDE25D97E561F36C219A0E8FE645816DBBC7ED7B57" +
			"7700AE8DC3138E97A0C3F6F002065C92A0B1B8180208",
	},
	Fp751: {
		Fp751, "P-751", NewSike751(rand.Reader),
		"testdata/PQCkemKAT_644.rsp",
		"E1A758EC0D418BFE86D8077B5BB169133C06C1F2A067D8B202D9D058FFC51F63" +
			"FD26155A6577C74BA7F1A27E7BA51982517B923615DEB00BE408920A07831DF5" +
			"978CFDDD0BF690A264353A4A16B666F90586D7F89A193CE09375D389C1379A7A" +
			"528581C3ACB002CD2DC4F0FD672568FF9050BA8365C7FEFC5E6ED089B921DE68" +
			"04091A0744DE3EB14D426A3F7DA215C50312617C1C2697243980D06056F2CCE8" +
			"8AE7AE73C7343C0B7104C9F2870A94FED744CF6E94630514B6CEAB0E64733BB6" +
			"FA67B931E5D8206010475CBE8BC587248D65D89D8CD9C8BBFA93E8B5F9EB9130" +
			"773DED665D52ABBD91C4C8C255F73C0FC82501AE33330E9F308DE7177CBF83E4" +
			"E26E334D7CB09019E638147FC58ED372AF660F14C194BC80E9666325C98E0F80" +
			"877271D4A6BF514F603703D8A697874CD50A34D92F5AAEA84633CCF96801BD51" +
			"7BF425DEE4A32AAF06684052473EA14643C3D535440FB2240A988D09F297C5A3" +
			"88CB3DE60ED943F124034B90EFF611221F80F78EC124956338A105F6636B063D" +
			"7E48BFBD5D614310FB97D86F122E4AE6F9DDF4977A93ED7D0CE2A94E346A1A03" +
			"D3219CF21907B85A5BCDC713F93A4406A22E03B1655A66E1F6741A2F953E6FE0" +
			"868B2614BABEF1943BBBCB1B66D3E7017E533EA84F291240B56AB33EF1DC3F3D" +
			"E99DBF9E8BE51A0076E462BCDD825EA96D7F63C99177C305C257B31461F4C23D" +
			"43115F0220409E8880BBB2468586D03461E807BE824B693874911B2B52AF06FD" +
			"BDC47F5A0159729641A7C950AB9E03F2DC045135",
		"0001020304050607080900010203040506070809000102030405060708090102" +
			"8626ED79D451140800E03B59B956F8210E556067407D13DC90FA9E8B872BFB8F" +
			"AB0A7289852106E40538D3575C500201",
	},
}

// Encrypt, Decrypt, check if input/output plaintext is the same.
func testPKERoundTrip(t *testing.T, v sikeVec) {
	// Message to be encrypted
	var pt [common.MaxMsgBsz]byte
	params := common.Params(v.id)
	ct := make([]byte, v.kem.CiphertextSize())
	msg := make([]byte, params.MsgLen)
	for i := range msg {
		msg[i] = byte(i)
	}

	// Import keys
	pkB := NewPublicKey(params.ID, KeyVariantSike)
	skB := NewPrivateKey(params.ID, KeyVariantSike)
	pkHex, err := hex.DecodeString(v.PkB)
	CheckNoErr(t, err, "Test vector wrong")
	skHex, err := hex.DecodeString(v.PrB)
	CheckNoErr(t, err, "Test vector wrong")
	err = pkB.Import(pkHex)
	CheckNoErr(t, err, "Public key import failed")
	err = skB.Import(skHex)
	CheckNoErr(t, err, "Private key import failed")
	err = v.kem.encrypt(ct, rand.Reader, pkB, msg[:])
	CheckNoErr(t, err, "PKE roundtrip - encryption failed")
	ptLen, err := v.kem.decrypt(pt[:], skB, ct)
	CheckNoErr(t, err, "PKE roundtrip - description failed")

	if !bytes.Equal(pt[:ptLen], msg[:]) {
		t.Errorf("Decryption failed \n got : %X\n exp : %X", pt[:ptLen], msg)
	}
}

// Generate key and check if can encrypt.
func testPKEKeyGeneration(t *testing.T, v sikeVec) {
	var err error
	params := common.Params(v.id)
	var pt [common.MaxMsgBsz]byte
	msg := make([]byte, params.MsgLen)
	ct := make([]byte, v.kem.CiphertextSize())
	// static buffer to ensure no overrides
	pk := NewPublicKey(v.id, KeyVariantSike)
	sk := NewPrivateKey(v.id, KeyVariantSike)

	for i := range msg {
		msg[i] = byte(i)
	}

	err = sk.Generate(rand.Reader)
	CheckNoErr(t, err, "PKE key generation")
	sk.GeneratePublicKey(pk)

	err = v.kem.encrypt(ct, rand.Reader, pk, msg[:])
	CheckNoErr(t, err, "PKE encryption")
	ptLen, err := v.kem.decrypt(pt[:], sk, ct)
	CheckNoErr(t, err, "PKE key decryption")

	if !bytes.Equal(pt[:ptLen], msg[:]) {
		t.Fatalf("Decryption failed \n got : %X\n exp : %X", pt, msg)
	}
}

func testNegativePKE(t *testing.T, v sikeVec) {
	var err error
	var msg [common.MaxMsgBsz]byte
	ct := make([]byte, v.kem.CiphertextSize())
	pk := NewPublicKey(v.id, KeyVariantSike)
	sk := NewPrivateKey(v.id, KeyVariantSike)

	// Generate key
	err = sk.Generate(rand.Reader)
	CheckNoErr(t, err, "key generation")
	sk.GeneratePublicKey(pk)

	// bytelen(msg) - 1
	err = v.kem.encrypt(ct, rand.Reader, pk, msg[:v.kem.params.KemSize+8-1])
	CheckIsErr(t, err, "PKE encryption doesn't fail")
	for _, v := range ct {
		if v != 0 {
			t.Fatal("Returned ciphertext must be not changed")
		}
	}
}

func testKEMRoundTrip(t *testing.T, pkB, skB []byte, v sikeVec) {
	// Import keys
	var err error
	var ssE [common.MaxSharedSecretBsz]byte
	var ssD [common.MaxSharedSecretBsz]byte
	pk := NewPublicKey(v.id, KeyVariantSike)
	sk := NewPrivateKey(v.id, KeyVariantSike)
	ct := make([]byte, v.kem.CiphertextSize())
	ssBsz := v.kem.SharedSecretSize()

	err = pk.Import(pkB)
	CheckNoErr(t, err, "Public key import failed")
	err = sk.Import(skB)
	CheckNoErr(t, err, "Private key import failed")

	v.kem.Reset()
	err = v.kem.Encapsulate(ct, ssE[:], pk)
	CheckNoErr(t, err, "Encapsulation failed")
	v.kem.Reset()
	err = v.kem.Decapsulate(ssD[:ssBsz], sk, pk, ct)
	CheckNoErr(t, err, "Decapsulation failed")

	if !bytes.Equal(ssE[:v.kem.SharedSecretSize()], ssD[:v.kem.SharedSecretSize()]) {
		t.Errorf("Shared secrets from decapsulation and encapsulation differ [%s]", v.name)
	}
}

func testKEMKeyGeneration(t *testing.T, v sikeVec) {
	var ssE [common.MaxSharedSecretBsz]byte
	var ssD [common.MaxSharedSecretBsz]byte
	ct := make([]byte, v.kem.CiphertextSize())

	sk := NewPrivateKey(v.id, KeyVariantSike)
	pk := NewPublicKey(v.id, KeyVariantSike)
	CheckNoErr(t, sk.Generate(rand.Reader), "error: key generation")
	sk.GeneratePublicKey(pk)

	// calculated shared secret
	v.kem.Reset()
	err := v.kem.Encapsulate(ct, ssE[:], pk)
	CheckNoErr(t, err, "encapsulation failed")
	v.kem.Reset()
	err = v.kem.Decapsulate(ssD[:v.kem.SharedSecretSize()], sk, pk, ct)
	CheckNoErr(t, err, "decapsulation failed")

	if !bytes.Equal(ssE[:], ssD[:]) {
		t.Fatalf("KEM failed \n encapsulated: %X\n decapsulated: %X", ssD[:], ssE[:])
	}
}

func testNegativeKEM(t *testing.T, v sikeVec) {
	var ssE [common.MaxSharedSecretBsz]byte
	var ssD [common.MaxSharedSecretBsz]byte
	var ssTmp [common.MaxSharedSecretBsz]byte
	ct := make([]byte, v.kem.CiphertextSize())
	ssBsz := v.kem.SharedSecretSize()

	sk := NewPrivateKey(v.id, KeyVariantSike)
	pk := NewPublicKey(v.id, KeyVariantSike)
	CheckNoErr(t, sk.Generate(rand.Reader), "error: key generation")
	sk.GeneratePublicKey(pk)

	v.kem.Reset()
	err := v.kem.Encapsulate(ct, ssE[:], pk)
	CheckNoErr(t, err, "pre-requisite for a test failed")

	// Try decapsulate too small ciphertext
	v.kem.Reset()
	CheckNoErr(
		t,
		CheckPanic(func() { _ = v.kem.Decapsulate(ssTmp[:ssBsz], sk, pk, ct[:len(ct)-2]) }),
		"Decapsulation must panic if ciphertext is too small")

	ctTmp := make([]byte, len(ct)+1)
	// Try decapsulate too big ciphertext
	v.kem.Reset()
	CheckNoErr(
		t,
		CheckPanic(func() { _ = v.kem.Decapsulate(ssTmp[:ssBsz], sk, pk, ctTmp) }),
		"Decapsulation must panic if ciphertext is too big")

	// Change ciphertext
	ct[0] = ct[0] - 1
	v.kem.Reset()
	err = v.kem.Decapsulate(ssD[:ssBsz], sk, pk, ct)
	CheckNoErr(t, err, "decapsulation returns error when invalid ciphertext provided")

	if bytes.Equal(ssE[:], ssD[:]) {
		// no idea how this could ever happen, but it would be very bad
		t.Error("critical error")
	}

	// Try encapsulating with SIDH key
	pkSidh := NewPublicKey(v.id, KeyVariantSidhB)
	prSidh := NewPrivateKey(v.id, KeyVariantSidhB)
	v.kem.Reset()
	CheckNoErr(
		t,
		CheckPanic(func() { _ = v.kem.Encapsulate(ct, ssE[:], pkSidh) }),
		"encapsulation accepts SIDH public key")

	// Try decapsulating with SIDH key
	v.kem.Reset()
	CheckNoErr(
		t,
		CheckPanic(func() { _ = v.kem.Decapsulate(ssD[:ssBsz], prSidh, pk, ct) }),
		"encapsulation accepts SIDH public key")
}

// In case invalid ciphertext is provided, SIKE's decapsulation must
// return same (but unpredictable) result for a given key.
func testNegativeKEMSameWrongResult(t *testing.T, v sikeVec) {
	var ssE [common.MaxSharedSecretBsz]byte
	var ssD1 [common.MaxSharedSecretBsz]byte
	var ssD2 [common.MaxSharedSecretBsz]byte
	ct := make([]byte, v.kem.CiphertextSize())
	ssBsz := v.kem.SharedSecretSize()

	sk := NewPrivateKey(v.id, KeyVariantSike)
	pk := NewPublicKey(v.id, KeyVariantSike)
	CheckNoErr(t, sk.Generate(rand.Reader), "error: key generation")
	sk.GeneratePublicKey(pk)

	v.kem.Reset()
	err := v.kem.Encapsulate(ct, ssE[:], pk)
	CheckNoErr(t, err, "pre-requisite for a test failed")

	// make ciphertext wrong
	ct[0] = ct[0] - 1
	v.kem.Reset()
	err = v.kem.Decapsulate(ssD1[:ssBsz], sk, pk, ct)
	CheckNoErr(t, err, "pre-requisite for a test failed")

	// change secret keysecond decapsulation must be done with same, but imported private key
	var expSk [common.MaxSikePrivateKeyBsz]byte
	sk.Export(expSk[:])

	// create new private key
	sk = NewPrivateKey(v.id, KeyVariantSike)
	CheckNoErr(t, sk.Import(expSk[:sk.Size()]), "import failed")

	// try decapsulating again.
	v.kem.Reset()
	err = v.kem.Decapsulate(ssD2[:ssBsz], sk, pk, ct)
	CheckNoErr(t, err, "pre-requisite for a test failed")

	// ssD1 must be same as ssD2
	if !bytes.Equal(ssD1[:], ssD2[:]) {
		t.Error("decapsulation is insecure")
	}

	// ssD1 and ssD2 must be different than ssE
	if bytes.Equal(ssE[:], ssD1[:]) || bytes.Equal(ssE[:], ssD2[:]) {
		// this test requires that decapsulation returns wrong result
		t.Errorf("test implementation error")
	}
}

func testKAT(t *testing.T, v sikeVec) {
	ssGot := make([]byte, v.kem.SharedSecretSize())
	testDecapsulation := func(pk, sk, ct, ssExpected []byte) {
		pubKey := NewPublicKey(v.id, KeyVariantSike)
		prvKey := NewPrivateKey(v.id, KeyVariantSike)
		if pubKey.Import(pk) != nil || prvKey.Import(sk) != nil {
			panic("sike test: can't load KAT")
		}

		err := v.kem.Decapsulate(ssGot, prvKey, pubKey, ct)
		CheckNoErr(t, err, "sike test: can't perform degcapsulation KAT")
		if !bytes.Equal(ssGot, ssExpected) {
			t.Fatalf("KAT decapsulation failed\n")
		}
	}

	readAndCheckLine := func(r *bufio.Reader) []byte {
		// Read next line from buffer
		line, isPrefix, err := r.ReadLine()
		if err != nil || isPrefix {
			panic("Wrong format of input file")
		}

		// Function expects that line is in format "KEY = HEX_VALUE". Get
		// value, which should be a hex string
		hexst := strings.Split(string(line), "=")[1]
		hexst = strings.TrimSpace(hexst)
		// Convert value to byte string
		ret, err := hex.DecodeString(hexst)
		if err != nil {
			panic("Wrong format of input file")
		}
		return ret
	}

	testKeygen := func(pk, sk []byte) {
		// Import provided private key
		prvKey := NewPrivateKey(v.id, KeyVariantSike)
		pubKey := NewPublicKey(v.id, KeyVariantSike)
		pubKeyBytes := make([]byte, pubKey.Size())
		CheckNoErr(t, prvKey.Import(sk), "Can't load KAT")

		// Generate public key
		prvKey.GeneratePublicKey(pubKey)
		pubKey.Export(pubKeyBytes)
		if !bytes.Equal(pubKeyBytes, pk) {
			t.Errorf("Public key differ [%s]", v.name)
		}
	}

	f, err := os.Open(v.KatFile)
	if err != nil {
		t.Fatal(err)
	}

	r := bufio.NewReader(f)
	for {
		line, isPrefix, err := r.ReadLine()
		if err != nil || isPrefix {
			if err == io.EOF {
				break
			} else {
				t.Fatal(err)
			}
		}
		if len(strings.TrimSpace(string(line))) == 0 || line[0] == '#' {
			continue
		}

		// count
		_ = strings.Split(string(line), "=")[1]
		// seed
		_ = readAndCheckLine(r)
		// pk
		pk := readAndCheckLine(r)
		// sk (secret key in test vector is concatenation of
		// MSG + SECRET_BOB_KEY + PUBLIC_BOB_KEY. We use only MSG+SECRET_BOB_KEY
		sk := readAndCheckLine(r)
		sk = sk[:v.kem.params.MsgLen+int(v.kem.params.B.SecretByteLen)]
		// ct
		ct := readAndCheckLine(r)
		// ss
		ss := readAndCheckLine(r)

		testKeygen(pk, sk)
		testDecapsulation(pk, sk, ct, ss)
		testKEMRoundTrip(t, pk, sk, v)
	}
}

// Interface to "testing"

/* -------------------------------------------------------------------------
   Wrappers for 'testing' SIDH
   -------------------------------------------------------------------------*/

func testSike(t *testing.T, m *map[uint8]sikeVec, f func(*testing.T, sikeVec)) {
	for i := range *m {
		v := (*m)[i]
		t.Run(v.name, func(t *testing.T) { f(t, v) })
	}
}

func TestPKERoundTrip(t *testing.T)     { testSike(t, &tdataSike, testPKERoundTrip) }
func TestPKEKeyGeneration(t *testing.T) { testSike(t, &tdataSike, testPKEKeyGeneration) }
func TestNegativePKE(t *testing.T)      { testSike(t, &tdataSike, testNegativePKE) }
func TestKEMKeyGeneration(t *testing.T) { testSike(t, &tdataSike, testKEMKeyGeneration) }
func TestNegativeKEM(t *testing.T)      { testSike(t, &tdataSike, testNegativeKEM) }
func TestKAT(t *testing.T)              { testSike(t, &tdataSike, testKAT) }
func TestNegativeKEMSameWrongResult(t *testing.T) {
	testSike(t, &tdataSike, testNegativeKEMSameWrongResult)
}

func TestKEMRoundTrip(t *testing.T) {
	for _, val := range tdataSike {
		//		fmt.Printf("\tTesting: %s\n", val.name)
		pk, err := hex.DecodeString(val.PkB)
		CheckNoErr(t, err, "public key B not a number")
		sk, err := hex.DecodeString(val.PrB)
		CheckNoErr(t, err, "private key B not a number")
		testKEMRoundTrip(t, pk, sk, val)
	}
}

/* -------------------------------------------------------------------------
   Benchmarking
   -------------------------------------------------------------------------*/

func benchSike(t *testing.B, m *map[uint8]sikeVec, f func(*testing.B, sikeVec)) {
	for i := range *m {
		v := (*m)[i]
		t.Run(v.name, func(t *testing.B) { f(t, v) })
	}
}

func benchKeygen(b *testing.B, v sikeVec) {
	pub := NewPublicKey(v.id, KeyVariantSike)
	prv := NewPrivateKey(v.id, KeyVariantSike)
	_ = prv.Generate(rand.Reader)

	b.ResetTimer()
	for n := 0; n < b.N; n++ {
		prv.GeneratePublicKey(pub)
	}
}

func benchmarkEncaps(b *testing.B, v sikeVec) {
	pub := NewPublicKey(v.id, KeyVariantSike)
	prv := NewPrivateKey(v.id, KeyVariantSike)

	if prv.Generate(rand.Reader) != nil {
		b.FailNow()
	}
	prv.GeneratePublicKey(pub)

	var ct [common.MaxCiphertextBsz]byte
	var ss [common.MaxSharedSecretBsz]byte

	b.ResetTimer()
	for n := 0; n < b.N; n++ {
		v.kem.Reset()
		_ = v.kem.Encapsulate(ct[:], ss[:], pub)
	}
}

func benchmarkDecaps(b *testing.B, v sikeVec) {
	var ct [common.MaxCiphertextBsz]byte
	var ss [common.MaxSharedSecretBsz]byte
	ssBsz := v.kem.SharedSecretSize()

	pkA := NewPublicKey(v.id, KeyVariantSike)
	prvA := NewPrivateKey(v.id, KeyVariantSike)
	pkB := NewPublicKey(v.id, KeyVariantSike)
	prvB := NewPrivateKey(v.id, KeyVariantSike)

	if prvA.Generate(rand.Reader) != nil || prvB.Generate(rand.Reader) != nil {
		b.FailNow()
	}

	prvA.GeneratePublicKey(pkA)
	prvB.GeneratePublicKey(pkB)

	v.kem.Reset()
	err := v.kem.Encapsulate(ct[:], ss[:], pkA)
	if err != nil {
		b.FailNow()
	}

	ctSlc := ct[:v.kem.CiphertextSize()]

	b.ResetTimer()
	for n := 0; n < b.N; n++ {
		v.kem.Reset()
		_ = v.kem.Decapsulate(ss[:ssBsz], prvA, pkB, ctSlc)
	}
}

func BenchmarkKeygen(b *testing.B) { benchSike(b, &tdataSike, benchKeygen) }
func BenchmarkEncaps(b *testing.B) { benchSike(b, &tdataSike, benchmarkEncaps) }
func BenchmarkDecaps(b *testing.B) { benchSike(b, &tdataSike, benchmarkDecaps) }

func ExampleKEM() {
	// Allice's key pair
	prvA := NewPrivateKey(Fp503, KeyVariantSike)
	pubA := NewPublicKey(Fp503, KeyVariantSike)
	// Bob's key pair
	prvB := NewPrivateKey(Fp503, KeyVariantSike)
	pubB := NewPublicKey(Fp503, KeyVariantSike)
	// Generate keypair for Allice
	err := prvA.Generate(rand.Reader)
	if err != nil {
		panic(err)
	}
	prvA.GeneratePublicKey(pubA)
	// Generate keypair for Bob
	err = prvB.Generate(rand.Reader)
	if err != nil {
		panic(err)
	}
	prvB.GeneratePublicKey(pubB)
	// Initialize internal KEM structures
	kem := NewSike503(rand.Reader)
	// Create buffers for ciphertext, shared secret received
	// from encapsulation and shared secret from decapsulation
	ct := make([]byte, kem.CiphertextSize())
	ssE := make([]byte, kem.SharedSecretSize())
	ssD := make([]byte, kem.SharedSecretSize())
	// Allice performs encapsulation with Bob's public key
	err = kem.Encapsulate(ct, ssE, pubB)
	if err != nil {
		panic(err)
	}
	// Bob performs decapsulation with his key pair
	err = kem.Decapsulate(ssD, prvB, pubB, ct)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%t\n", bytes.Equal(ssE, ssD))

	// Bob performs encapsulation with Allices's public key
	err = kem.Encapsulate(ct, ssE, pubA)
	if err != nil {
		panic(err)
	}
	// Allice performs decapsulation with hers key pair
	err = kem.Decapsulate(ssD, prvA, pubA, ct)
	if err != nil {
		panic(err)
	}
	fmt.Printf("%t\n", bytes.Equal(ssE, ssD))

	// Output:
	// true
	// true
}

repository: cloudflare/circl

repo_name: cloudflare/circl

branch_name: refs/heads/main

gha_license_id: NOASSERTION