text:
# Salt Vagrant Demo

A Salt Demo using Vagrant.

## Requirements
This demo requires `libvirt` with at least one supported hypervisor, this guide will be KVM/QEMU specific.
In addition, the [vagrant-libvirt](https://github.com/vagrant-libvirt/vagrant-libvirt) plugin is needed to utilize libvirt:
```sh
vagrant plugin install vagrant-libvirt
```
## Instructions

Run the following commands in a terminal. Vagrant, Git and any guide-specific packages specified in the **Requirements** section  must already be installed.
```sh
git clone https://github.com/stiftcast/salt-vagrant-demo.git
cd salt-vagrant-demo
vagrant up
```
To be able to spin up VMs using libvirt as a non-root user, it may be required to follow the instructions [here.](https://computingforgeeks.com/use-virt-manager-as-non-root-user/)

This will download a generic Ubuntu 18.04 image and create three virtual
machines for you. One will be a Salt Master named `master` and two will be Salt
Minions named `minion1` and `minion2`.  The Salt Minions will point to the Salt
Master and the Minion's keys will already be accepted. Because the keys are
pre-generated and reside in the repo, please be sure to regenerate new keys if
you use this for production purposes.

You can then run the following commands to log into the Salt Master and begin
using Salt.
```sh
vagrant ssh master
sudo salt \* test.ping
```

repository: stiftcast/salt-vagrant-demo

repo_name: stiftcast/salt-vagrant-demo


text:
# Worst Fit allocates
Worst Fit allocates a process to the partition which is largest sufficient among the freely available partitions available in the main memory. If a large process comes at a later stage, then memory will not have space to accommodate it.

## INPUT
**nb**
- It accepts input for the number of blocks.

**nf**
- This variable contains the input for the number of files.

**block**
- This array accept input for a particular block size.

**file**
- Accept input for a particular file size.

## PROCESS

**temp**
- This variable holds the difference between the current block and the current file.

**bf**
- It checks if process has been assigned to that block.

**ff**
- It holds the Block containing that file.

**lowest**
- IT holds the value of fragmentation in a memory.

**frag**
- It holds the value of Fragment of block index.

## OUTPUT
- The output display  file number ( as I) , file size(as file[i]),Block Size( as block[ff[i]]) and fragment( as frag[i]).

license: MIT

branch_name: refs/heads/main

extension: md

license_type: permissive


text:
---
title: Web Browser Automation with Selenium IDE
venue: University of North Texas Libraries Digital Projects Unit Tech Talk
location: Denton, TX
duration: February 2013
skills:
  - Presentation
  - UNT
---

Abstract
-------

Selenium IDE is a Firefox plugin that sends commands to the browser according to the instructions contained in user-defined scripts. This Tech Talk will cover the basics of Selenium IDE, present examples of how the Digital Projects Newspaper Group is using Selenium to streamline the process of editing metadata records in The Portal to Texas History and UNT Digital Library, and provide resources for further inquiry. The Tech Talk will conclude with a demonstration of Selenium IDE including a suite of search scripts developed for the UNT Libraries.

Links
----------

* <https://digital.library.unt.edu/ark:/67531/metadc78279/>

branch_name: refs/heads/master


text:
# 03 - Switch_with 2 LEDs

Lesson Plan for the [Crazy Circuits Classroom Set: Programing 101](https://www.browndoggadgets.com/collections/new-crazy-circuits-kits/products/crazy-circuits-classroom-set-programing-101)

Upload the Arduino sketch `Switch_with_2_LEDs.ino` to your Robotics Board.

Full build guide here: https://browndoggadgets.dozuki.com/Guide/03+-+Switch+with+2+LEDs/206

![Switch_with 2 LEDs](Images/Switch_with_2_LEDs.png)

---

Brown Dog Gadgets

https://www.browndoggadgets.com/

url: https://raw.githubusercontent.com/BrownDogGadgets/Programming101Curriculum/ceeef81a43785e8aa62426683189ca08dad2d003/Project Based Curriculum/03 - Switch with 2 LEDs/README.md


text:
---
layout: post
title: My 2017 GSoC Project - Part IV
subtitle: (Un)Filling The Box
category: Programming
tags: [GSoC-2017, Scilab, Modelica]
---

Hello there,

I was undecided about where to begin the posts about glueing **FMI2** calls to the **Scicos Block** interface, mentioned in [the last post]({% post_url 2017-06-10-blocky_package %}), so I'll take the most obvious route and start from the beginning...

... of block processing/simulation, I mean. And that is triggered by the **Initialization flag** (**4**):

 flags	                 inputs                	   outputs   	                description

  ... 	                   ...                 	     ...     	                   ...

   4  	                t, x, z                	 x, z, outptr	   initialize states and other initializations

  ... 	                   ...                 	     ...     	                   ...

The purpose of the **Initialization job** is more thoroughly described in [the available documentation](http://www.scicos.org/Newblock.pdf):

- *"Initialization: At the begining of the simulation, this job is called under flag=4 to initialize continuous and discrete states (if necessary). It also initialize the output port of the block. This function is not used in all of the blocks, it is used for blocks that needed dynamically allocated memory (the allocation is done under this flag), for blocks that read and write data from files, for opening a file, or by the scope to initialize the graphics window."*

So, aside from **continuos/discrete state and output initialization** (in arrays **x**, **z** and **outptr**, respectively), this flag also indicates the moment when all **manual memory allocations** (if needed) should be performed for a given block.

That's our case, because **FMI2 API** involves allocation of **components** to hold internal state values.

*But, as **scicos_block** is the only data structure provided at the **computational function call**, where will they be stored ?*

Taking a look at **scicos_block4.h** header, it seems there is a field intended for this very role:

{% highlight cpp %}
typedef struct
{
  /* ... */
  int nz;         // Size of discrete-time state vector
  double* z;      // Vector of discrete-time state
  /* ... */
  int nx;         // Size of continuous-time state vector
  double* x;      // Vector of continuous-time state
  /* ... */
  int nin;        // Number of regular input ports
  int* insz;      // Vector of sizes of regular input ports
  void** inptr;   // Tables of pointer to the regular input ports
  int nout;       // Number of regular output ports
  int* outsz;     // Vector of sizes of regular output ports
  void** outptr;  // Tables of pointers to the regular output ports
  /* ... */
  void** work;    // Table of pointers to the block workspace (if allocation done by the block)
  /* ... */
}
scicos_block;
{% endhighlight %}

Then, assuming that the **work** pointer is the one to be used, we initialized the block inside our **Scicos**/**FMI2** wrapper:

{% highlight cpp %}
#include <string.h>
#include <stdio.h>
#include <stdarg.h>

// Scilab Scicos block interface and definitions
#include "scicos_block4.h"
#include "scicos.h"
#include "dynlib_scicos.h"

// FMI2 API definitions
#include "fmi2TypesPlatform.h"
#include "fmi2FunctionTypes.h"
#include "fmi2Functions.h"

// Definitions based on model properties

#define BLOCK_FUNCTION_NAME /* ... */
#define MODEL_NAME /* ... */
#define MODEL_GUID /* ... */

static fmi2Real inputsList[] = /* ... */;
const static fmi2ValueReference INPUT_REFS_LIST[] = /* ... */;
static fmi2Real outputsList[] = /* ... */;
const static fmi2ValueReference OUTPUT_REFS_LIST[] = /* ... */;
static fmi2Real stateDetivativesList[] = /* ... */;
const static fmi2ValueReference STATE_REFS_LIST[] = /* ... */;
const static fmi2ValueReference STATE_DER_REFS_LIST[] = /* ... */;

// Simple terminal message logging function
static void print_log_message( fmi2ComponentEnvironment componentEnvironment, fmi2String instanceName,
                               fmi2Status status, fmi2String category, fmi2String message, ... )
{
    va_list args;
    va_start( args, message );
    vprintf( (const char*) message, args );
    printf( "\n" );
    va_end( args );
}

// Utility function for setting Scicos block -> FMI2 model input
static void set_input( scicos_block* block )
{
    // Considering input only floating point continuous values
    double** u = (double**) block->inptr;
    // Set u inputs before calculation derivatives
    if( block->nin > 0 )
    {
        for( int i = 0; i < block->nin; i++ )
            inputsList[ i ] = u[ i ][ 0 ];
        fmi2SetReal( (fmi2Component) block->work, INPUT_REFS_LIST, block->nin, inputsList );
    }
}

// Utility function for getting FMI2 model -> Scicos block output
static void get_output( scicos_block* block )
{
    // Considering output only floating point continuous values
    double** y = (double**) block->outptr;
    // Retrieve output values
    if( fmi2GetReal( (fmi2Component) block->work, OUTPUT_REFS_LIST, block->nout, outputsList ) == fmi2OK )
    {
        // Setting outputs the same as continuous states
        for( int i = 0; i < block->nout; i++ )
            y[ i ][ 0 ] = outputsList[ i ];
    }

    // For now, we assume no discrete outputs
}

// The computational function itself
SCICOS_IMPEXP void BLOCK_FUNCTION_NAME( scicos_block* block, const int flag )
{
    static fmi2EventInfo eventInfo;

    switch( flag )
    {
        /* ... */

        // Flag 4: State initialisation and memory allocation
        case Initialization:
        {
            // User provided functions for FMI2 data management
            const fmi2CallbackFunctions functions = { .logger = print_log_message,
                                                      .allocateMemory = calloc,
                                                      .freeMemory = free,
                                                      .stepFinished = NULL,
                                                      .componentEnvironment = NULL };

            // Store FMI2 component in the work field
            block->work = (void**) fmi2Instantiate( MODEL_NAME,            // Instance name
                                                    fmi2ModelExchange,     // Exported model type
                                                    MODEL_GUID,            // Model GUID, have to be obtained
                                                    "",                    // Optional FMU resources location
                                                    &functions,            // User provided callbacks
                                                    fmi2True,              // Interactive mode
                                                    fmi2True );            // Logging On

            // Need to set input references based on model description (to be implemented)

            set_input( block );           // Set initial inputs

            // Define simulation parameters. Internally calls state and event setting functions,
            // which should be called before any model evaluation/event processing ones
            fmi2SetupExperiment( (fmi2Component) block->work,              // FMI2 component
                                 fmi2False,                                // Tolerance undefined
                                 0.0,                                      // Tolerance value (not used)
                                 0.0,                                      // Start time
                                 fmi2False,                                // Stop time undefined
                                 1.0 );                                    // Stop time (not used)

            // FMI2 component initialization
            fmi2EnterInitializationMode( (fmi2Component) block->work );
            fmi2ExitInitializationMode( (fmi2Component) block->work );

            // Event iteration
            eventInfo.newDiscreteStatesNeeded = fmi2True;
            while( eventInfo.newDiscreteStatesNeeded )
            {
                // update discrete states
                fmi2NewDiscreteStates( (fmi2Component) block->work, &eventInfo );
                // if( eventInfo.terminateSimulation ) goto TERMINATE_MODEL;
            }

            // Enable iterative derivatives calculation and integration
            fmi2EnterContinuousTimeMode( (fmi2Component) block->work );

            fmi2GetContinuousStates( (fmi2Component) block->work, block->x, block->nx );

            get_output( block );          // Get initial outputs

            break;
        }

        /* ... */
    }

    return;
}
{% endhighlight %}

(Error handling is not shown to simplify visualization)

### [De/Re]initialization

As we are describing initialization procedures for **FMI2**-based blocks, it makes sense to also talk about ending and reinitializing them:

 flags	                 inputs                	   outputs   	                description

  ... 	                   ...                 	     ...     	                   ...

   5  	               x, z, inptr             	 x, z, outptr	  final call to block for ending the simulation

   6  	  t, nevprt, x, z, inptr, mode, phase  	 x, z, outptr	        reinitialization (if needed)

  ... 	                   ...                 	     ...     	                   ...

From the **documentation**:

- *"Ending: This job is called when flag=5 at the end. This case is used to close files opened by the block at the begining or during the simulation, to free the allocated memory, etc."*

- *"Reinitialization: This job is called under flag=6. In this case, the values of the inputs are available and the function create a fixed point iteration for the outputs of the block. On this occasion, the function can also reinitialize its initial states."*

{% highlight cpp %}
/* ... */

void fmi2_block( scicos_block* block, const int flag )
{
    /* ... */

    switch( flag )
    {
        /* ... */

        // Flag 5: simulation end and memory deallocation
        case Ending:
        {
            // Get final state and output

            fmi2SetTime( (fmi2Component) block->work, get_scicos_time() );

            fmi2GetContinuousStates( (fmi2Component) block->work, block->x, block->nx );

            get_output( block );

            fmi2Terminate( (fmi2Component) block->work );       // Terminate simulation for this component

            // Deallocate memory
            fmi2FreeInstance( (fmi2Component) block->work );

            break;
        }
        // Flag 6: Output state initialisation
        case ReInitialization:
        {
            // Set reinitialized model state and get output

            fmi2SetTime( (fmi2Component) block->work, get_scicos_time() );

            fmi2SetContinuousStates( (fmi2Component) block->work, block->x, block->nx );

            get_output( block );

            break;
        }

        /* ... */
    }

    return;
}
{% endhighlight %}

Be aware that this implementation is subject to change, as I better understand of how to deal with the **API**. But, for now, that's all I have to show you.

Thanks for sticking with me one more time. See Ya !


text:
---
layout: home
---

Couscous generates a [GitHub pages](https://pages.github.com/) website from your markdown documentation.

[![Build Status](https://travis-ci.org/CouscousPHP/Couscous.svg?branch=master)](https://travis-ci.org/CouscousPHP/Couscous)
[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/CouscousPHP/Couscous.svg)](https://isitmaintained.com/project/CouscousPHP/Couscous "Average time to resolve an issue")
[![Percentage of issues still open](https://isitmaintained.com/badge/open/CouscousPHP/Couscous.svg)](https://isitmaintained.com/project/CouscousPHP/Couscous "Percentage of issues still open")

**Everything is documented on [couscous.io](https://couscous.io/).**

What follows is the documentation for contributors.

## How Couscous works?

Couscous was designed to be as simple as possible. By embracing simplicity, it becomes extremely simple to extend.

### Website generation

The website generation is composed of a list of **steps** to process the `Project` model object:

```php
interface Step
{
    /**
     * Process the given project.
     *
     * @param Project $project
     */
    public function __invoke(Project $project);
}
```

Steps are very granular, thus extremely easy to write and test. For example:

- `LoadConfig`: load the `couscous.yml` config file
- `InstallDependencies`: install the dependencies (using yarn, npm or bower)
- `LoadMarkdownFiles`: load the content of all the `*.md` files in memory
- `RenderMarkdown`: render the markdown content
- `WriteFiles`: write the in-memory processed files to the target directory
- …

For example, here is a step that would preprocess Markdown files to put the word "Couscous" in bold:

```php
class PutCouscousInBold implements \Couscous\Step
{
    public function __invoke(Project $project)
    {
        /** @var MarkdownFile[] $markdownFiles */
        $markdownFiles = $project->findFilesByType('Couscous\Model\MarkdownFile');

        foreach ($markdownFiles as $file) {
            $file->content = str_replace('Couscous', '**Couscous**', $file->content);
        }
    }
}
```

Couscous uses [PHP-DI](https://php-di.org/) for wiring everything together with dependency injection.

The full list of steps is configured in [`src/Application/config.php`](src/Application/config.php).

### Website deployment

Couscous deploys by cloning (in a temp directory) the current repository, checking out the `gh-pages` branch, generating the website inside it, committing and pushing.

In the future, Couscous will support several deployment strategies.

## Contributing

See the [CONTRIBUTING](CONTRIBUTING.md) file.

## License

Couscous is released under the MIT License.

repository: CouscousPHP/Couscous

gha_language: PHP

gha_license_id: NOASSERTION

repo_name: CouscousPHP/Couscous


text:
#Common Text Layout Operations

This chapter describes some common text layout operations and shows how they can be performed using Core Text. The following operations with code listings are included in this chapter:

* Laying Out a Paragraph
* Simple Text Label
* Columnar Layout
* Manual Line Breaking
* Applying a Paragraph Style
* Displaying Text in a Nonrectangular Region

##Laying Out a Paragraph

One of the most common operations in typesetting is laying out a multiline paragraph within an arbitrarily sized rectangular area. Core Text makes this operation easy, requiring only a few lines of Core Text–specific code. To lay out the paragraph, you need a graphics context to draw into, a rectangular path to provide the area where the text is laid out, and an attributed string. Most of the code in this example is required to create and initialize the context, path, and string. After that is done, Core Text requires only three lines of code to do the layout.

常见排版操作的一种是在一个固定大小的矩形区域绘制一个多行的段落。CoreText 可很简单的实现这个操作, 只需要简单的几行代码。绘制段落前你需要在获取的图形上下文中绘制一个矩形区域, 用于绘制文本。实例中的大多数代码被用于获取上下文，创建路径和字符串。做完这些操作后 CoreText 只需调用三句话来绘制文本。

The code in Listing 2-1 shows how a paragraph is laid out. This code could reside in the drawRect: method of a UIView subclass (an NSView subclass in OS X).
列表2-1展示了段落的绘制, 这些代码在 UIView或者NSView的 drawRect:方法 中被调用。

######Listing 2-1  Typesetting a simple paragraph

```
// Initialize a graphics context in iOS.
CGContextRef context = UIGraphicsGetCurrentContext();

// Flip the context coordinates, in iOS only.
CGContextTranslateCTM(context, 0, self.bounds.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

// Initializing a graphic context in OS X is different:
// CGContextRef context =
//     (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];

// Set the text matrix.
CGContextSetTextMatrix(context, CGAffineTransformIdentity);

// Create a path which bounds the area where you will be drawing text.
// The path need not be rectangular.
CGMutablePathRef path = CGPathCreateMutable();

// In this simple example, initialize a rectangular path.
CGRect bounds = CGRectMake(10.0, 10.0, 200.0, 200.0);
CGPathAddRect(path, NULL, bounds );

// Initialize a string.
CFStringRef textString = CFSTR("Hello, World! I know nothing in the world that has as much power as a word. Sometimes I write one, and I look at it, until it begins to shine.");

// Create a mutable attributed string with a max length of 0.
// The max length is a hint as to how much internal storage to reserve.
// 0 means no hint.
CFMutableAttributedStringRef attrString =
         CFAttributedStringCreateMutable(kCFAllocatorDefault, 0);

// Copy the textString into the newly created attrString
CFAttributedStringReplaceString (attrString, CFRangeMake(0, 0),
         textString);

// Create a color that will be added as an attribute to the attrString.
CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat components[] = { 1.0, 0.0, 0.0, 0.8 };
CGColorRef red = CGColorCreate(rgbColorSpace, components);
CGColorSpaceRelease(rgbColorSpace);

// Set the color of the first 12 chars to red.
CFAttributedStringSetAttribute(attrString, CFRangeMake(0, 12),
         kCTForegroundColorAttributeName, red);

// Create the framesetter with the attributed string.
CTFramesetterRef framesetter =
         CTFramesetterCreateWithAttributedString(attrString);
CFRelease(attrString);

// Create a frame.
CTFrameRef frame = CTFramesetterCreateFrame(framesetter,
          CFRangeMake(0, 0), path, NULL);

// Draw the specified frame in the given context.
CTFrameDraw(frame, context);

// Release the objects we used.
CFRelease(frame);
CFRelease(path);
CFRelease(framesetter);

```

url: https://raw.githubusercontent.com/Jerrywx/AttributeText-Demo/fa582b105efd5adae70367526976341b349b4777/Core Text Programming Guide/Common Text Layout Operations.md

repository: Jerrywx/AttributeText-Demo

filename: Common Text Layout Operations.md

repo_name: Jerrywx/AttributeText-Demo


text:
# ToDoPlaning

## It is a planing application.

We are very open-minded to be corrected.
Please correct our code or give us some advice if there is the better way to code.

### Goal
1. "To do List" with calendar.

### Program flow
1. Log in
2. Show calendar with "To do list"

### JSON format
```
{
  "todoList" : {
    "user1" : [
      {
        "date" : "20190101",
        "todo" : "crossFit"
      },
      {
        "date" : "20190101",
        "todo" : "study"
      }
    ],
    "user2" : [],
    .
    .
    .
  }
}

```

### Coding rule
1. Use the camel case.
2. Use tab to indent.

### Git
We are using "git flow" strategy.

repository: diddlybop/ToDoPlaning

repo_name: diddlybop/ToDoPlaning


text:
## TEST: Powerful Builds(Lesson 16)

### Gulp and Grunt
Leverage the power of build tools liek Gulp and Grunt
- to automate the process of converting your development code into streamlined production-ready

### Gulp
- [Installation Instructions](https://github.com/gulpjs/gulp/blob/master/docs/getting-started.md)

###  Installing Gulp and Course Code
_Note_: if you have not installed NodeJS or NPM you will need to install these first before installing Gulp. You can download and install NodeJS and NPM by going to [Nodes official site](https://nodejs.org/en/) and downloading the latest version of NodeJS.

- 1. Take a few moments and install Gulp.
The instructions are listed in the [link](https://github.com/gulpjs/gulp/blob/master/docs/getting-started.md).

- 2. Grab the course code from Github.
- [Gulp- course on Github](https://github.com/udacity/ud892)

Make CSS Suck less with Sass
- [SASS](http://sass-lang.com/)

#### Resources
- [Gulp Installation](https://github.com/gulpjs/gulp/blob/master/docs/getting-started.md)
- [Nodes JS](https://nodejs.org/en/)
- [Gulp- course on Github](https://github.com/udacity/ud892)
- [SASS](http://sass-lang.com/)
- [Gulp Autoprefixer plugin on npm](https://www.npmjs.com/package/gulp-autoprefixer)

repository: WebDevCaptain/Code-Notes

path: /Powerful Builds.md

filename: Powerful Builds.md

repo_name: WebDevCaptain/Code-Notes


text:
# sporz

PHP implementation of the board game "sporz"

# Installation

* Get [composer](https://getcomposer.org/)
* Clone this repository
* In the root directory:

        $ make all
        $ # edit config/config.php to suits your needs
        $ make migration

repository: gitus/sporz

repo_name: gitus/sporz


text:
# LavaClient
[![Build Status](https://travis-ci.org/SamOphis/LavaClient.svg?branch=master)](https://travis-ci.org/SamOphis/LavaClient)
[![Download](https://api.bintray.com/packages/samophis/maven/LavaClient/images/download.svg) ](https://bintray.com/samophis/maven/LavaClient/_latestVersion)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

[![LavaClient Guild](https://discordapp.com/api/guilds/455002103757406218/embed.png?style=banner2)](https://discord.gg/dvUhTJX)

LavaClient is a fast, feature-complete **and abstract** client implementation for [Lavalink v2.x and v3.x](https://github.com/Frederikam/Lavalink) that
doesn't depend on any Discord API Library. Although being abstract, it supports [JDA](https://github.com/DV8FromTheWorld/JDA) via the [LavaClient-JDA](https://github.com/SamOphis/LavaClient-JDA) project.

This page doesn't go into too much detail, so please [check out the Wiki instead.](https://github.com/SamOphis/LavaClient/wiki)
The [Documentation for the Latest Version can also be found here.](https://samophis.github.io/LavaClient)

Projects made using LavaClient:
* [Kyoko](https://github.com/KyokoBot/Kyoko) - A cool, modular Discord Bot made in [JDA](https://github.com/DV8FromTheWorld/JDA)
* [LavaClient-JDA](https://github.com/SamOphis/LavaClient-JDA) - Official LavaClient integration for [JDA](https://github.com/DV8FromTheWorld/JDA).

> Note: People migrating from LavaClient to LavaClient v2 now must add [Lavaplayer](https://github.com/sedmelluq/lavaplayer) to their build file themselves.

# Why Choose LavaClient?

As of writing this (9th June 2018), LavaClient is the most frequently updated Lavalink Client Implementation with documentation of every public
class and support for every documented [Lavalink Feature from v2.0 onwards.](https://github.com/Frederikam/Lavalink/blob/master/IMPLEMENTATION.md)

Additionally, it:

* Uses faster and lighter dependencies.
* Uses SLF4J Logging frequently allowing for super simple error/warning management.
* Offers full documentation of any public class meant to be used.
* Uses the same load balancing logic found in the [Lavalink JDA Client](https://github.com/Frederikam/Lavalink/tree/master/LavalinkClient).
* Has self-explanatory and easy-to-use features.
* Has a **configurable** cache to reduce load on both nodes and clients.
* Has neat features such as `SocketInitializer`s and `AudioWrapper`s to allow low-level socket configuration as well as complete compatibility between
  Lavalink v2.0 and v3.0, meaning you don't have to change one bit of code even when using mixtures of nodes running v2.0 or v3.0 of Lavalink.
  Users can also specify a custom `WebSocketFactory` for even deeper configuration.
* Has easy-to-understand [guides found in the Wiki.](https://github.com/SamOphis/LavaClient/wiki)
* Very fault tolerant (as of v3.0.0): LavaClient will automatically reconnect to nodes where possible, and has an almost entirely configurable
  backoff/interval system. This allows for the rebooting of nodes and accounts for sudden disconnections without your application exploding.
* Supports reconnecting and disconnecting from nodes manually with safe, optional callbacks.
* Has "placeholder" values meaning you only have to configure what you specifically need.

However, there is one big con of LavaClient which is how abstract it is. LavaClient doesn't rely on [JDA](https://github.com/DV8FromTheWorld/JDA),
[Discord4J](https://github.com/austinv11/Discord4J) or any other Discord API Library, and so things such as rate limiting or the handling of events
needed to connect to Lavalink have to be handled by the user. As a result, it's recommended that you rely on a well-established library that allows
you to do this easily such as the aforementioned ones, then you can take advantage of their built-in rate limiting and event handling.

If you really cannot use those libraries though, you'll need at the very bare minimum a semi-complete Discord Gateway Implementation before you can
even begin using LavaClient. An example of how you can handle just the rate limiting part [can be found here.](https://gist.github.com/SamOphis/766c62d6fb91bac77ea9f2dea0edb330)

As of the 14th June 2018, a [LavaClient integration for JDA](https://github.com/SamOphis/LavaClient-JDA) exists however the problem still remains for other libraries.

# Creating and Adding Nodes to a LavaClient Instance

You can create any number of `LavaClient` instances (although you only need one to handle a bot account and all of its shards) with this code:

```java
LavaClient client = new LavaClientBuilder()
        .setUserId(bot_user_id)
        .setShardCount(bot_shard_count)
        .build();
```

In the `LavaClientBuilder` constructor you can specify 0-3 parameters: `overrideJson`, `expireWriteMs` and `expireAccessMs`. If you don't specify
any, the default values are: `true`, `1200000`, `900000`.

Their meanings are:
* Should LavaClient enable the fastest Jsoniter Encoding/Decoding option (uses Javassist).
* How long should LavaClient wait to remove Cache Entries after being written.
* How long should LavaClient wait to remove Cache Entries after being accessed (resets write time).

Then, you can actually add `AudioNode`s to a client instance with the code:

```java
AudioNodeEntry node = new AudioNodeEntryBuilder(client)
        .setAddress("localhost")
        .build();
client.addEntry(node);
```

> Note: Many more methods are available in the builders, but these are the bare minimums needed to connect.

The node is automatically connected to however any created `LavaPlayer`s don't send Voice Updates until their `connect` method is called.
It's strongly encouraged to not use that method as it is and instead use the `EventWaiter`.

More information can be found in the Wiki, so please check that out!

# Contributing

Contributions are always welcome if your contribution follows the [Contribution Guidelines](https://github.com/SamOphis/LavaClient/blob/master/.github/CONTRIBUTING.md).

repository: NovaReXs/LavaClient

repo_name: NovaReXs/LavaClient


text:
---
layout: default
---

# 1996-02-22 - Re: Digital Signature Legislation

## Header Data

From: "E. ALLEN SMITH"<EMAIL_ADDRESS>To<EMAIL_ADDRESS>Message Hash: 5b3b5146db335731a39bbc1a736e08d295f42e6316508db0aaf740440887bf5d

Message ID<EMAIL_ADDRESS>Reply To: _N/A_

UTC Datetime: 1996-02-22 23:42:27 UTC

Raw Date: Fri, 23 Feb 1996 07:42:27 +0800

## Raw message

```
{% raw  %}From: "E. ALLEN SMITH"<EMAIL_ADDRESS>Date: Fri, 23 Feb 1996 07:42:27 +0800
To<EMAIL_ADDRESS>Subject: Re: Digital Signature Legislation
Message-ID<EMAIL_ADDRESS>MIME-Version: 1.0
Content-Type: text/plain

	I find it interesting to note that Dr. Biddle's concerns on the
economic aspects of the legislation are almost the reverse of those on the
cypherpunks list. For instance, he is concerned about too much liability by
the consumer (and I would agree that the "strict liability" rather than
"negligence" model is a problem). The concern on the list has been that there
is too much liability for the CA, given the potential of unlimited liability
for all transactions such as Dr. Biddle appears to be favoring.
	-Allen

{% endraw %}
```

## Thread

+ Return to [February 1996](/archive/1996/02)

+ Return to "["E. ALLEN SMITH" <EALLENSMITH@ocelot.Rutgers.EDU>](/authors/e_allen_smith_eallensmith_at_ocelot_rutgers_edu_)"

+ 1996-02-22 (Fri, 23 Feb 1996 07:42:27 +0800) - Re: Digital Signature Legislation - _"E. ALLEN SMITH"<EMAIL_ADDRESS>

gha_license_id: MIT


text:
---
title: Inheriting A WebForm From A Custom Class
categories: .Net
date: 2005-04-15 03:01:00 +10:00
---

For the last couple of days at work, I have been developing a new ASP.Net site. Across all the pages in the site, there are some common methods and properties that need to be used. In the case of this new application, I needed to check if the authenticated user has permissions in Active Directory to see the details of the user they are requesting.

 The easiest way to achieve this common functionality is to create a base class that inherits from System.Web.UI.Page. Each WebForm code behind page can then inherit from the custom class instead of the default System.Web.UI.Page class. I hit some interesting problems with developing this solution in the VS IDE.

<!--more-->

 The first problem is that the design-time view of the pages usually didn't render because it couldn't identify the custom class. This was caused because I initially had the custom class in the ASP.Net project. This is an issue because the design-time render needs a compiled class to render controls and pages as it doesn't interpret uncompiled code. As the class was in the web project , the assembly may not yet be compiled, or if compiled, it usually can't be resolved.

 To fix this problem, I separated the custom class out into a class library which was referenced by the web project. This meant that when the designer attempted to render the design-time display, it had a compiled assembly that it could resolve and use.

 The second problem was that the IDE was continuously locking files in the .Net cache. This caused compiling problems with the solution. I can only guess that this second problem was caused by the custom class being in the web project as they haven't happened since I separated the class out into another project.

license: MIT,Unlicense

detected_licenses: MIT Unlicense

gha_language: SCSS


text:
# Designing a Multi-rotor Drone

**WORK IN PROGRESS**

This document goes through the IQ design process for designing drones for intelligent missions. All of the autonomous drones I have designed have been for research purposes. From doing this, I have noticed there is not a lot of material about designing and building your custom drone for this purpose. I have tried to aggregate all of the information I have learned over the years into one document. I have also developed a fairly robust design process to help guide new and old drone engineers through their design choices.

## Overview of the Process
1. Figure out what you want your drone to do
2. Figure out your sensor package
3. Design a frame to carry your payload
4. Estimate the weight of the frame and payload
5. Do power thrust analysis and select motors, escs and batteries

## What will my drone do?

This is where you examen the mission and decide what you will design to accomplish the goal. Start thinking of how your drone will fly, navigate, and take data.

## Sensor Compute and Comms Selection

You should figure out all of the mission specific hardware computers and sensors before you design the vehicle to move your payload.

### Payload Components Most Intelligent Drones Need
- FCC
- Companion Computer
- Camera(s)
- RC receiver
- Telemetry Radio
- Navigation equipment (GPS, OF, altimeter)
- Avoidance sensors (lidar, sonar, more cameras)

## Designing a Frame

How do we best arrange our sensors, compute and comms to accomplish the mission. Make a CAD to best lock down the spacial arrangement of the components. Use the CAD to get a better weight estimate of your frame.

## Picking out motors ESCs and Props

This part of the process is the most tricky. All of these bits and pieces are coupled, so changing one affects the other. This is not a well-defined process, and in its current state, most hobbyists rely on trial and error, as well as word of mouth. It is more of an art than a science.lege. I will attempt to make this more based on my experience to be more scientific and use some aerospace principles I learned in college.

It is helpful to think of what our ultimate goal is when designing a drone. We want to carry a payload, and we want to be able to carry it for as long as possible usually.  While we may think we have constraints on the flight time and payload, ultimately, people want to add more sensors and make the vehicle do more things. As the designer to the aircraft, we should try to give the mission designers as much margin as possible. To get the most out of our system, we should analyze the efficiency of our system and try to optimize each component. The two main design principles I will try to optimize are

- Aerodynamic/Mechanical Efficiency
- Electrical Efficiency

## Aerodynamic Efficiency of a Multi-rotor

The Aerodynamic efficiency of your multi-rotor is affected by a couple different parameters.
- The propeller disk
- The pitch of the propeller
- Blade count
- The mass of the vehicle

## Propeller Disk

A multi-rotor works by taking mass(air) and throwing it down so the vehicle can hover or ascend. This is Newton’s third law in a nutshell: for every action, there is an equal and opposite reaction.  To generate more thrust, we want to throw as much air as possible down, one way to do this is to increase the propeller disk diameter. When we look at the equation for a circle, we notice that the area increases by the square of the radius, so a small increase in the radius will net us a whole heap more of air!

Principal:
- A bigger disk area equals a lot more thrust

## Propeller Pitch

By the logic of wanting to throw as much air down as possible, we can increase thrust by throwing the air down faster. This can be accomplished by increasing the pitch of your blade. So great, let’s have a large rotor and high pitch! Not so fast. Increasing the pitch of the propeller increases the drag of the rotor, and the added pitch doesn’t transfer the energy from the rotor to the air very well.

Principal:
- Higher pitch equals more thrust
- Higher pitch equals low efficiency

## Blade Count

Similar to blade pitch, more blades will give higher thrust, but will also increases the drag of the blade as well as the mass.

Principal:
- More blades equal more thrust
- More blades equal lower efficiency

## Mass of Vehicle

Basically there is a decent amount of math that goes into this, but the big takeaway is this equation.

We notice that the power to hover increases to the power of 1.5, which means adding double the mass requires almost 3 times the power! This is a huge mistake people make: they say “I’m only going to add a little bit of weight”, but then their flight time decrease quite a bit.

Principal:
- Required power increase to the 1.5 power of mass

## Aerodynamic Efficiency Summary

- A bigger disk area equals more thrust by the square of the radius
- Higher pitch equals more thrust
- Higher pitch equals low efficiency
- More blades equal more thrust
- More blades equal low efficiency
- Required power increase to the 1.5 power of mass

## Electrical Efficiency of the Drone
The basic idea behind analyzing the electrical efficiency is to minimize the resistance loss in the circuit. Since P=I^2R, this means that the power consumed by the resistance in the wires increases with the square of the current. This means having a higher voltage system, which in turn reduces the current, is a more efficient electrical system.

## Selecting Motors ECSs and Battery
Now that we understand how to best use the energy stored within our drone, we can look at selecting motors and escs.

The first thing to do is take the weight estimate you calculated from our CAD and parts spreadsheet and use this as the minimum thrust our motors will need at 50% throttle. The best thing to do is take the estimated weight of the done and add a healthy margin; the more you add, the better off you will be. This is especially important if this a developmental drone. As you continue to develop your application, you will want to add more sensors and actuators to the aircraft, which will kill your flight time quickly. As we noted above, the power required to hover is to the 1.5 power of your mass!


text:
# Installation
> `npm install --save @types/autoprefixer`

# Summary
This package contains type definitions for autoprefixer (https://github.com/postcss/autoprefixer).

# Details
Files were exported from https://www.github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/autoprefixer

Additional Details
 * Last updated: Thu, 31 Aug 2017 21:47:30 GMT
 * Dependencies: postcss
 * Global values: none

# Credits
These definitions were written by Armando Meziat <https://github.com/odnamrataizem>.

repository: jocanjg/newstore

gha_language: CSS

repo_name: jocanjg/newstore


text:
---
layout: post
title: Dlt Viewer For Android
tag: [DLT,COVESA]
categories: [Android]
---

<!--break-->

Sometimes, we need to do some quick check over WiFi with DLT-Logs.
I asked the COVESA offical，[Is there any plan to build an android edition?](https://github.com/GENIVI/dlt-viewer/issues/20) But no reply.

So I think I need to do something myself.

This is the result just by now.

https://github.com/zeerd/dlt-viewer-android


text:
## Convenience Methods

##

All of these take a string or buffer as the first argument, an optional second
argument to supply options to the zlib classes and will call the supplied
callback with `callback(error, result)`.

Every method has a `*Sync` counterpart, which accept the same arguments, but
without a callback.

filename: nodejs_Convenience Methods.md


text:
---
type: "journal"
title: "Tim Toke Benefit"
date: 2022-02-11T11:14:42-05:00
draft: false
thumbnail: "https://res.cloudinary.com/dpmsynxig/image/upload/c_scale,f_auto,q_auto:good,w_700/v1645287265/2022%20Posts/2022-02-11_Tim-Toke-Benefit/2022-02-11_leica-m10p-114.jpg"
image: "https://res.cloudinary.com/dpmsynxig/image/upload/f_auto,q_auto:good/v1645287265/2022%20Posts/2022-02-11_Tim-Toke-Benefit/2022-02-11_leica-m10p-114.jpg"
alt: "man on stage at a concert"
caption: "Thunderlip! / Leica M10-P / 35mm Summicron ASPH"
tags:
- thunderlip
- worsen
- toke
- shows
---

Tim of the band {{< link href="https://www.discogs.com/artist/4472757-Toke-6" text="Toke" >}} (a really great stoner/doom metal band from Wilmington North Carolina) was involved in a bad motorcycle accident in September of last year. From what I understand he's recovering and things are going in the right direction, but it's going to be a lengthy process.

In true Wilmington fashion, friends and family came together to put on one helluva benefit show at Reggie's. Both nights sold out pretty quickly. A lot of people, businesses and artists offered goods and/or services for the raffle (which did _very_ well) and quite a few local bands played. One of the major highlights for me and lots of others is that the incredible {{< link href="https://www.discogs.com/artist/3838710-Thunderlip" text="Thunderlip!" >}} would be playing with the original line up!

{{< figure src="https://res.cloudinary.com/dpmsynxig/image/upload/f_auto,q_auto:good/v1645287264/2022%20Posts/2022-02-11_Tim-Toke-Benefit/2022-02-11_leica-m10p-113.jpg" alt="man on stage at concert" caption="Thunderlip! / Leica M10-P / 35mm Summicron ASPH" >}}

Thunderlip! shows are some of the funnest and entertaining shows I've ever been to and I wasn't going to miss this for anything.

I also got to see {{< link href="https://www.discogs.com/artist/3893225-Worsen" text="Worsen" >}} for the first time. Worsen is a black metal band from here in Charlotte which includes members from {{< link href="https://www.discogs.com/artist/7507435-Raw-Hex" text="Raw Hex." >}}

{{< figure src="https://res.cloudinary.com/dpmsynxig/image/upload/f_auto,q_auto:good/v1645287266/2022%20Posts/2022-02-11_Tim-Toke-Benefit/2022-02-11_leica-m10p-18.jpg" alt="man playing guitar on stage" caption="Worsen / Leica M10-P / 35mm Summicron ASPH" >}}

This was also the first time I got to put the M10-P to work and probably the first time I've shot a live show in, I don't know, 10 years? This is how I got started doing photography in the first place and it felt really great to do it again. I shot about 200 photos. I knew it would be pretty dark and a lot of movement during Thunderlip! so I shot their set with an off-camera flash.

Never shot a show with a rangefinder and now I don't want to shoot a show with anything else. Being able to zone focus and frame your shot without having to worry about what the lens sees is incredible in low-light situations. It was basically like using a point n shoot.

We stayed through most of {{< link href="https://www.discogs.com/artist/1090946-ASG-2" text="ASG's" >}} set and missed {{< link href="https://www.discogs.com/artist/343797-Weedeater" text="Weedeater" >}}, but we weren't staying in town for the weekend so needed to head back for the long-ish drive.

I'm sure the second day did just as well if not better. It was an all day event. We spent the rest of the weekend relaxing at my parents place by the beach. A packed, but also relaxing weekend.

More photos from the show can be viewed {{< link href="https://www.flickr.com/photos/jasonwhite/albums/72177720296803372" text="here." >}}

repository: jason-white/personal-site

gha_language: HTML

repo_name: jason-white/personal-site


text:
# Glide universal module

This package integrates Glide in any [container-interop](https://github.com/container-interop/service-provider) compatible framework/container.

## Installation

```
composer require mnapoli/glide-module
```

Once installed, you need to register the [`GlideModule\GlideServiceProvider`](src/GlideDefinitionProvider.php) into your container.

Refer to your framework or container's documentation to learn how to register *service providers*.

## Usage

This module registers the Glide server under the `League\Glide\Server` key in your service container. You can now inject it in your services. Have a look at [the official documentation](http://glide.thephpleague.com/1.0/simple-example/) to know how to use the server.

Since **Glide's server requires the `source` and `cache` options to be configured**, you must define a `glide.options` entry in your container. That entry should be an array containing Glide options.

Here is an example using [PHP-DI](http://php-di.org/)'s syntax:

```php
return [
    'glide.options' => [
        'source' => 'path/to/source/folder',
        'cache' => 'path/to/cache/folder',
    ]
];
```

Here is the same example using [Pimple](http://pimple.sensiolabs.org/):

```php
$pimple['glide.options'] = [
    'source' => 'path/to/source/folder',
    'cache' => 'path/to/cache/folder',
];
```

### Returning a response

This module automatically configures Glide to generate PSR-7 responses. To use it in a controller, simply inject the `League\Glide\Server` object and use it like this:

```php
// This returns a PSR-7 response
return $server->getImageResponse($filename, $options);
```

### Advanced options

The `glide.options` array is passed straight to Glide's `ServerFactory`. Have a look at [the official documentation about configuration](http://glide.thephpleague.com/0.3/config/the-server/) to learn about all the options you can use.

repository: mnapoli/glide-module

repo_name: mnapoli/glide-module


text:
---
title: Moving From WordPress to Jekyll
layout: post
keywords: ["Jekyll", "WordPress", "moving", "static", "website", "markdown"]
tags: ["Jekyll", "WordPress", "Website"]
---

Two days ago, I decided to make transition from WordPress to Jekyll. If you guys do not know what Jekyll is, Jekyll is a **static site generator**, it generates a complete website using only HTML and CSS by processing a variety of input formats like HTML, Markdown, Text files combined with a CSS.

I took this decision mainly due to the following reasons.

  - I'm very much bothered by the amount of spam registrations I get in the site
  - It's not interesting to write in TineMCE editor
  - I made my WordPress installation a **mess** with a ton of plugins
  - I'm tired of the 'User Locked' mails

With these reasons, I also wanted to try my hand at CSS _(I admit, I'm very poor in CSS)_ and I want to style my own website, so I found Jekyll to be interesting, so I thought of moving my WordPress website into Jekyll. Unfortunately, Jekyll importer complained the massive HTML generated by **Page Builder** plugin, so I used these two days to re-create it from scratch.

Now, after two days, I ended up with this theme. Unfortunately, I couldn't import my comments into Disquss because some of the urls have been changed, but I regret that. But now, I'm really enjoying writing in Markdown with Jekyll.

Another **BIG** change is, I'm re-writing my LWJGL Tutorial Series using LWJGL3. So yeah, there is a lot of work, see you guys soon! :smile:

license: Unlicense

gha_language: JavaScript

gha_license_id: Unlicense


text:
---
layout: default
title: Liquibase Quickstart
includeDaticalBox: true
---
## Step 1: Create a Changelog File: ##

The [database changelog file](documentation/databasechangelog.html) is where all database changes are listed. It is XML based, so start with an empty XML file:

{% highlight xml %}
<?xml version="1.0" encoding="UTF-8"?>

<databaseChangeLog
  xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
         http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">

</databaseChangeLog>
{% endhighlight %}

## Step 2: Add a ChangeSet ##

Each [change set](documentation/changeset.html) is uniquely identified by an "id" attribute and an "author" attribute. These two tags, along with the name and package of the changelog file uniquely identify the change. If only an "id" needed to be specified, it would be too easy to accidentally duplicate them, especially when dealing with multiple developers and code branches. Including an "author" attribute minimizes the chances of duplications.

Think of each change set as an atomic change that you want to apply to your database. It's usually best to include just one change in your change set, but more are allowed and can make sense if you are inserting multiple rows that should be added as a single transaction.  Liquibase will attempt to run each change set as a single transaction, but many databases will silently commit and resume transactions for certain commands (create table, drop table, etc.)

{% highlight xml %}
<?xml version="1.0" encoding="UTF-8"?>

<databaseChangeLog
  xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
         http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">

    <changeSet id="1" author="bob">
        <createTable tableName="department">
            <column name="id" type="int">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="name" type="varchar(50)">
                <constraints nullable="false"/>
            </column>
            <column name="active" type="boolean" defaultValueBoolean="true"/>
        </createTable>
    </changeSet>

</databaseChangeLog>
{% endhighlight %}

## Step 3: Run the ChangeSet ##

There are many ways to execute your change log including via [command line](documentation/command_line.html), [Ant](documentation/ant/index.html), [Maven](documentation/maven/index.html), [Spring](documentation/spring.html), a [servlet listener](documentation/servlet_listener.html), and a [CDI Environment](documentation/cdi.html).

Here is an example for mysql via jdbc:

{% highlight bat %}
liquibase --driver=com.mysql.jdbc.Driver \
     --classpath=/path/to/classes \
     --changeLogFile=com/example/db.changelog.xml \
     --url="jdbc:mysql://localhost/example" \
     --username=user \
     --password=asdf \
     migrate
{% endhighlight %}

There are many more databases supported by liquibase. For a list of them and which jdbc driver, url, classpath etc. they need, please visit the [databases](databases.html) section.

## Step 4: Check Your Database ##

You will see that your database now contains a table called "department". Two other tables are created as well: "databasechangelog" and "databasechangeloglock". The databasechangelog table contains a list of all the statements that have been run against the database. The databasechangeloglock table is used to make sure two machines don't attempt to modify the database at the same time.

## Next Steps ##

* This quick-start guide is designed to get you started with Liquibase. For a full description of all its capabilities, see the [Liquibase Manual](documentation/index.html), read [the best practices](bestpractices.html) and visit the [forums](community/index.html).
* If you have an existing project you are looking to add Liquibase too, visit the [Existing Project](documentation/existing_project.html) page.
* If you are interested in commercial support, training or consulting visit datical.com.


text:
---
layout: post
title: Bioinformatics tools for profiling viral and bacterial communities
---

This week [Rhys](https://biological-sciences.uq.edu.au/profile/1083/rhys-parry) showed us a number of bioinfomatics tools and approaches to metagenomics analyses.

Rhys's slides are available [here](/pdf/2019-02-21-Rhys.pdf).


text:
---
title: About
date: 2017-01-01T00:00:00.000Z
permalink: /about/index.html
navtitle: About
tags:
  - nav
---

![Eric and Jenny Bear Lake Colorado](//i.etreacy.me/about/BearLake.jpg)

Me and my wife Jenny at Rocky Mountain National Park, Bear Lake, Colorado.

## Hi, I'm Eric!

I'm a chemist currently living in Marquette, Michigan working at [Peninsula Pharmacy](https://penpharm.com/)
and building software. I love science and technology — and this is my space on the web.

## The deets

I'm a polymath: proficiencies range from bench science to software development:

*From 2008 - 2015*, I oscillated my time between [National Jewish Health](https://www.nationaljewish.org/home) and [The University of Colorado — Anschutz Medical Campus](http://www.ucdenver.edu/anschutz/Pages/landing.aspx)
researching the Life Sciences in Pediatric Rheumatology and Immunology with [Philippa Marrack, PhD, FRS](https://www.nationaljewish.org/doctors-departments/providers/researchers/philippa-marrack) and
[Leonard Dragone, MD, PhD](https://www.linkedin.com/in/leonard-dragone-94125474/).

*From 2014 - current*, I work(ed) in Software Development for [The Texas Medical Association](https://www.texmed.org/), [Xeratec Corporation](https://xeratec.com/) and [Baby E's BBQ](https://babyesbbq.com) — and continue to
create & contribute to OSS for fun.

## What's with the site?

I enjoy design — and this space is my creative outlet. I design/engineer with code using various web technologies. In my personal time,
I love working with (S)CSS. Other Languages/platforms I enjoy — in a netshell — include HTML, JavaScript, Go, Ruby on Rails, ReactJS, ASP.Net, etc. Pretty much anything that will get me to where I need to be. I am always learning and
discovering.

## Contact

[mail<EMAIL_ADDRESS>
[twitter@erictreacy](//twitter.com/erictreacy)

## Colophon

This site is built with:
Vanilla (S)CSS, Eleventy, Nunjucts, Netlify, Cloud9, AWS CloudFront & GitHub.

repository: erictreacy/eleventy-netlify-boilerplate

repo_name: erictreacy/eleventy-netlify-boilerplate


text:
# ex_aequo

<!--
DO NOT EDIT THIS FILE
It has been generated from the template `README.md.eex` by Extractly (https://github.com/RobertDober/extractly.git)
and any changes you make in this file will most likely be lost
-->

[![CI](https://github.com/RobertDober/ex_aequo/actions/workflows/ci.yml/badge.svg)](https://github.com/RobertDober/ex_aequo/actions/workflows/ci.yml)
[![Coverage Status](https://coveralls.io/repos/github/RobertDober/ex_aequo/badge.svg?branch=master)](https://coveralls.io/github/RobertDober/ex_aequo?branch=master)
[![Hex.pm](https://img.shields.io/hexpm/v/ex_aequo.svg)](https://hex.pm/packages/ex_aequo)
[![Hex.pm](https://img.shields.io/hexpm/dw/ex_aequo.svg)](https://hex.pm/packages/ex_aequo)
[![Hex.pm](https://img.shields.io/hexpm/dt/ex_aequo.svg)](https://hex.pm/packages/ex_aequo)

# ExAequo Elixir Tools

### Installation:

```elxir
  { :ex_aequo, ">= 0.5.3" }
```

Meaning of the name. All nice latin expressions starting with _Ex_ are consumed at an alarming rate, so, all things
being equal, I choose this one.

## ExAequo.SimpleClaParser

A simple Command Line Argument Parser delivering syntactically but not semantically checked Commnad Line Arguments

Nothing in → Nothing out

```elixir
    iex(1)> parse([])
    {:ok, %{args: [], kwds: %{}}}
```

Positionals only

```elixir
    iex(2)> parse(~W[alpha beta gamma])
    {:ok, %{args: ~W[alpha beta gamma], kwds: %{}}}
```

Flags are indicated by a leading `:`

```elixir
    iex(3)> parse(~W[:verbose :help alpha beta gamma])
    {:ok, %{args: ~W[alpha beta gamma], kwds: %{verbose: true, help: true}}}
```

Keywords needing values are defined à la json with a trailing `:`

```elixir
    iex(4)> parse(~W[level: 42 :h name: Elixir])
    {:ok, %{args: ~W[], kwds: %{level: "42", h: true, name: "Elixir"}}}
```

A single `:` just ends keyword parsing

```elixir
    iex(5)> parse(~W[level: 42 : :h name: Elixir])
    {:ok, %{args: ~W[:h name: Elixir], kwds: %{level: "42"}}}
```

Beware of not giving values to keywords

```elixir
    iex(6)> parse(~W[level:])
    {:error, %{args: [], kwds: %{}, error: "Missing value for keyword arg level!" }}
```

```elixir
    iex(7)> parse(~W[level: : high])
    {:error, %{args: ~W[high], kwds: %{}, error: "Missing value for keyword arg level!" }}
```

## ExAequo.SemanticClaParser

This module allows to parse Command Line Arguments with attached semantics, that is

 **Constraints** and **Conversions**

## Errors from the `SimpleClaParser` are returned verbatim

```elixir
    iex(1)> parse(~W[a:])
    {:error, %{args: [], kwds: %{}, error: "Missing value for keyword arg a!"}}
```

Empty args might be ok

```elixir
    iex(2)> parse([])
    {:ok, %{args: [], kwds: %{}}}
```

or they might not

```elixir
    iex(3)> parse([], required: [:level])
    {:error, %{args: [], kwds: %{}, errors: [missing_required_kwd: :level]}}
```

## Constraints can also do conversions

```elixir
    iex(4)> parse(~W[value: 42], required: [value: :int])
    {:ok, %{args: [], kwds: %{value: 42}}}
```

and if they fail we get an error

```elixir
    iex(5)> parse(~W[value: 42a], required: [value: :int])
    {:error, %{args: [], kwds: %{value: "42a"}, errors: [{:bad_constraint_int, :value, "42a"}]}}
```

constraints can also be defined for optional values

```elixir
    iex(6)> parse(~W[value: 42], optional: [value: :int])
    {:ok, %{args: [], kwds: %{value: 42}}}
```

and then it is ok, not to provide them

```elixir
    iex(7)> parse([], optional: [value: :int])
    {:ok, %{args: [], kwds: %{}}}
```

but if we do so we must oblige

```elixir
    iex(8)> parse(~W[value: xxx], optional: [value: :int])
    {:error, %{args: [], kwds: %{value: "xxx"}, errors: [{:bad_constraint_int, :value, "xxx"}]}}
```

and constraints work for positionals too

```elixir
    iex(9)> parse(~W[10], optional: [{0, :int}])
    {:ok, %{args: [10], kwds: %{}}}
```

```elixir
    iex(10)> parse(~W[ten], optional: [{0, :int}])
    {:error, %{args: ~W[ten], kwds: %{}, errors: [{:bad_constraint_int, 0, "ten"}]}}
```

and as positionals are optional unless constrained with `needed:` this is ok

```elixir
    iex(11)> parse([], optional: [{0, :int}])
    {:ok, %{args: [], kwds: %{}}}
```

## Custom made constraints need either return `{:ok, value}`

```elixir
    iex(12)> always_42 = fn _, _ -> {:ok, 42} end
    ...(12)> parse(~W[value: hello!], optional: [value: always_42])
    {:ok, %{args: [], kwds: %{value: 42}}}
```

or `{:error, message}`

```elixir
    iex(13)> never_happy = fn val, key -> {:error, {:so_bad, key, "must not have #{val}"}} end
    ...(13)> parse(~W[value: hello!], optional: [value: never_happy])
    {:error, %{args: [], kwds: %{value: "hello!"}, errors: [{:so_bad, :value,  "must not have hello!"}]}}
```

## Memberships

### Ranges

```elixir
    iex(14)> int_range = &ExAequo.SemanticClaParser.Constraints.int_range/2
    ...(14)> parse(~W[42], optional: [{0, int_range.(41, 43)}])
    {:ok, %{args: [42], kwds: %{}}}
```

```elixir
    iex(15)> int_range = &ExAequo.SemanticClaParser.Constraints.int_range/2
    ...(15)> parse(~W[420], optional: [{0, int_range.(41, 43)}])
    {:error, %{args: ~W[420], kwds: %{}, errors: [{:not_in_int_range, 0, 420, 41..43}]}}
```

```elixir
    iex(16)> int_range = &ExAequo.SemanticClaParser.Constraints.int_range/2
    ...(16)> parse(~W[a], optional: [{0, int_range.(41, 43)}])
    {:error, %{args: ["a"], kwds: %{}, errors: [{:bad_constraint_int_range, 0, "a"}]}}
```

Note that we cannot specify the nth positional argument as required, we can however constrain the number of positional
argumentes

```elixir
    iex(17)> parse([], needed: 0..1)
    {:ok, %{args: [], kwds: %{}}}
```

```elixir
    iex(18)> parse(~W[one], needed: 0..1)
    {:ok, %{args: ["one"], kwds: %{}}}
```

```elixir
    iex(19)> parse(~W[:a one], needed: 0..1)
    {:ok, %{args: ["one"], kwds: %{a: true}}}
```

However

```elixir
    iex(20)> parse(~W[: :a one], needed: 0..1)
    {:error, %{args: [":a", "one"], kwds: %{}, errors: [{:illegal_number_of_args, 0..1, 2}]}}
```

We can even forbid positionals like that

```elixir
    iex(21)> parse(~W[a], needed: 0)
    {:error, %{args: ["a"], kwds: %{}, errors: [{:illegal_number_of_args, 0..0, 1}]}}
```

## ExAequo.File

## ExAequo.File

### ExAequo.File.files/1

### ExAequo.File.files_with_stat/1

expands `wc` and zips each matching file into a list of `{String.t, File.Stat.t}`

### ExAequo.File.readlines/1

read a file into lines

```elixir
    iex(0)> readlines(Path.join(~W[test fixtures a_simple_file.txt]))
    ["Line 1", "Line two", " Una terza linea"]
```

### ExAequo.File.today/1

expands `wc` and zips each matching file into a list of `{String.t, File.Stat.t}`, then
filters only the files from today

## ExAequo.Enum offers some extension functions for Elixir's Enum module

### Grouped Accumulation

Groupes accumulated values of an Enum according to a function that
indicates if two consequent items are of the same kind and if so
how to accumulate their two values.

The `grouped_reduce` function returns the groupes in reverse order, as,
during traversal of lists quite often reversing the result of the
classical "take first and push a function of it to the result" pattern
cancels out.

An optional, `reverse: true` keyword option can be provided to reverse
the final result for convenience.

```elixir
      iex(0)> add_same = fn {x, a}, {y, b} ->
      ...(0)>               cond do
      ...(0)>                 x == y -> {:cont, {x, a + b}}
      ...(0)>                 true   -> {:stop, nil} end end
      ...(0)> E.grouped_reduce(
      ...(0)>   [{:a, 1}, {:a, 2}, {:b, 3}, {:b, 4}], add_same)
      [{:b, 7}, {:a, 3}]
```

The `grouped_inject` function behaves almost identically to `grouped_reduce`,
however an initial value is provided.

```elixir
      iex(1)> sub_same = fn {x, a}, {y, b} ->
      ...(1)>               cond do
      ...(1)>                 x == y -> {:cont, {x, a - b}}
      ...(1)>                 true   -> {:stop, nil}
      ...(1)>               end
      ...(1)>            end
      ...(1)> E.grouped_inject(
      ...(1)> [{:a, 1}, {:b, 2}, {:b, 2}, {:c, 2}, {:c, 1}, {:c, 1}],
      ...(1)>  {:a, 43}, sub_same, reverse: true)
      [a: 42, b: 0, c: 0]
```

## ExAequo.Color

  ## Support for the 256 ANSI and full RGB colors

  **N.B.** Does, of course, respect the usage of the `$NO_COLOR` variable

  The most basic approach is to use the generated escape sequences directly in your code, e.g.

  ```elixir
    IO.puts(ExAequo.Color.rgb(250, 148, 13) <> "Brownish Orange" <> ExAequo.Color.reset)
  ```

### `rgb`

  The generated escape codes would be:

```elixir
    iex(1)> rgb(250, 148, 13)
    "\e[38;2;250;148;13m"
```

```elixir
    iex(2)> reset()
    "\e[0m"
```

### `format`

  But like `IO.ANSI` a convenience function called `format` is available

```elixir
    iex(3)> format(["Hello", "World"])
    ["Hello", "World"]
```

  As one can see it is tailor made for `IO.puts` and may be converted into a string by means of
  `IO.chardata_to_string`, this conversion can also be done by `format` itself

```elixir
    iex(4)> format(["Hello", "World"], to_string: true)
    "HelloWorld"
```

### `putc`

  A shortcut for

  ```elixir
      color_definition_list
      |> format
      |> IO.puts
  ```

#### RGB

  In order to get colors into the mix we can use, atoms (for named colors or instructions like reset)
  or triples for RGB colors

```elixir
    iex(5)> format([{100, 20, 150}, "Deep Purple (pun intended)", :reset])
    ["\e[38;2;100;20;150m", "Deep Purple (pun intended)", "\e[0m"]
```

#### 8 Color Space

  And here are some nice names, which shall work on **all** terminals

```elixir
    iex(6)> format([:red, "red", :blue, "blue"])
    ["\e[31m", "red", "\e[34m", "blue"]
```

  Oftentimes you will pass a variable to `format` and not a literal array, then the usage of the `reset: true` option
  might come in handy

```elixir
    iex(7)> some_values = [:azure1, "The sky?"]
    ...(7)> format(some_values, reset: true, to_string: true)
    "\e[38;2;240;255;255mThe sky?\e[0m"
```

#### 256 Colors

```elixir
    iex(8)> format([:color242, :color142, :color42])
    ["\e[38;5;242m", "\e[38;5;142m", "\e[38;5;42m"]
```

## Escript `ls_colors`

Test some colors

```sh
    ls_colors :red Red :reset 100,20,150 Deep Purple
```

Show some colors

```sh
    ls_colors -l|--list red_range green_range blue_range
```

## Tools to facilitate dispatching on keyword parameters, used in contexts like the following

      @defaults [a: 1, b: false] # Keyword or Map
      def some_fun(..., options \ []) # options again can be a Keyword or Map
        {a, b} = tuple_from_params(@defaults, options, [:a, :b])

### Merging defaults and actual parameters

Its most useful feature is that you will get a map whatever the mixtures of maps and keywords the
input was

```elixir
    iex(0)> merge_params([])
    %{}

```elixir
    iex(1)> merge_params([a: 1], %{b: 2})
    %{a: 1, b: 2}
```

```elixir
    iex(2)> merge_params(%{a: 1}, [a: 2, b: 2])
    %{a: 2, b: 2}
```
```

#### Strict merging

_Not implemented yet_

### Extracting params from the merged defaults and actuals

```elixir
    iex(3)> defaults = [foo: false, depth: 3]
    ...(3)> tuple_from_params(defaults, %{foo: true}, [:foo, :depth])
    {true, 3}
```

As defaults are required a missing parameter will raise an Error

```elixir
    iex(4)> try do
    ...(4)>   tuple_from_params([], [foo: 1], [:bar])
    ...(4)> rescue
    ...(4)>   KeyError -> :caught
    ...(4)> end
    :caught
```

Alternatively on can extract a map

```elixir
    iex(5)> map_from_params([], [hello: "world"], [:hello])
    %{hello: "world"}
```

This is the 2 param form which is identical to an empty default map

```elixir
    iex(6)> map_from_params(%{a: 1, b: 2}, [:a])
    %{a: 1}
```

This is the 2 param form which is identical to an empty default map

```elixir
    iex(7)> tuple_from_params(%{a: 1, b: 2}, [:b, :a])
    {2, 1}
```

    iex(0)> basename_without_ext("a/b/c.txt")
    "c"

```elixir
    iex(1)> basename_without_ext("a/b/c.txt.eex")
    "c.txt"
```

```elixir
    iex(2)> basename_without_ext("a/b/c")
    "c"
```

    iex(3)> fullname_without_ext("a/b/c.txt")
    "a/b/c"

```elixir
    iex(4)> fullname_without_ext("a/b/c.txt.eex")
    "a/b/c.txt"
```

```elixir
    iex(5)> fullname_without_ext("a/b/c")
    "a/b/c"
```

```elixir
    iex(6)> fullname_without_ext("/c")
    "/c"
```

<!-- SPDX-License-Identifier: Apache-2.0 -->


text:
![Clipper](https://raw.github.com/wincent/clipper/master/logo.png)

# Overview

Clipper is an OS X "launch agent" that runs in the background providing a
service that exposes the local clipboard to tmux sessions and other processes
running both locally and remotely.

# At a glance

    # Installation (using Homebrew; for non-Homebrew installs see below)
    brew install clipper # run this outside of a tmux session

    # Configuration for ~/.tmux.conf:
    # tmux < 1.8: bind <prefix>-y to forward to Clipper
    bind-key y run-shell "tmux save-buffer - | nc localhost 8377"

    # tmux >= 1.8: bind "Enter" in copy mode to both copy and forward to Clipper
    bind-key -t vi-copy Enter copy-pipe "nc localhost 8377"

    # Configuration for ~/.vimrc:
    # Bind <leader>y to forward last-yanked text to Clipper
    nnoremap <leader>y :call system('nc localhost 8377', @0)<CR>

    # Configuration for ~/.bash_profile, ~/.zshrc etc:
    # Pipe anything into `clip` to forward it to Clipper
    alias clip="nc localhost 8377"

    # Configuration for ~/.ssh/config:
    # Forward Clipper connection to remote host
    Host host.example.org
      RemoteForward 8377 localhost:8377

# Problem

You're running tmux, possibly on a remote machine via ssh, and want to copy
something using tmux copy mode into your local system clipboard.

You can hold down Option and click to make a selection, bypassing tmux and
allowing you to copy straight to the system clipboard, but that won't work if
you're using vertical splits (because the selection will operate across the
entire width of the terminal, crossing the splits) or if you want to grab more
than what is currently visible.

As a workaround for the vertical split problem, you can hold down Option +
Command to make a rectangular (non-contiguous) selection, but that will grab
trailing whitespace as well, requiring you to manually clean it up later.
Again, it won't work if you want to grab more than what is currently visible.

As a result, you often find yourself doing a tiresome sequence of:

1. Copy a selection using tmux copy mode on a remote machine
2. Still on the remote machine, open a new, empty buffer in Vim
3. Enter Vim paste mode (`:set paste`)
4. Paste the tmux copy buffer into the Vim buffer
5. Write the file to a temporary location (eg. `:w /tmp/buff`)
6. From the local machine, get the contents of the temporary file into the local
   system clipboard with `ssh user@host cat /tmp/buff | pbcopy` or similar

# Solution

OS X comes with a `pbcopy` tool that allows you to get stuff into the clipboard
from the command-line. We've already seen this at work above. Basically, we can
do things like `echo foo | pbcopy` to place "foo" in the system clipboard.

tmux has a couple of handy commands related to copy mode buffers, namely
`save-buffer` and `copy-pipe`. With these, you can dump the contents of a
buffer to standard out.

In theory, combining these two elements, we can add something like this to our
`~/.tmux.conf`:

    bind-key -t vi-copy Enter copy-pipe pbcopy

or, in version of tmux prior to 1.8 (which don't have the `copy-pipe` command):

    bind-key y run-shell "tmux save-buffer - | pbcopy"

In practice, this doesn't work because tmux uses the `daemon(3)` system call,
which ends up putting it in a different execution context from which it cannot
interact with the system clipboard. For (much) more detail, see:

- http://developer.apple.com/library/mac/#technotes/tn2083/_index.html

One workaround comes in the form of the `reattach-to-user-space` tool available
here:

- https://github.com/ChrisJohnsen/tmux-MacOSX-pasteboard

This is a wrapper which allows you to launch a process and have it switch from
the daemon execution context to the "user" context where access to the system
clipboard is possible. The suggestion is that you can add a command like the
following to your `~/.tmux.conf` to make this occur transparently whenever you
open a new pane or window:

    set-option -g default-command "reattach-to-user-namespace -l zsh"

Despite the fact that the wrapper tool relies on an undocumented, private API,
it is written quite defensively and appears to work pretty well. While this is a
workable solution when running on the local machine, we'll need something else
if we want things to work transparently both locally and remotely. This is where
Clipper comes in.

Clipper is a server process that you can run on your local machine. It will
listen on the network for connections, and place any content that it receives
into the system clipboard.

It can be set to run automatically as a "launch agent" in the appropriate
execution context, which means you don't have to worry about starting it, and it
will still have access to the system clipboard despite being "daemon"-like.

Through the magic of `ssh -R` it is relatively straightforward to have a shared
tmux configuration that you can use both locally and remotely and which will
provide you with transparent access to the local system clipboard from both
places.

# Setup

## Installing

For Homebrew users, install by running (outside of all tmux sessions):

    brew install clipper # and follow the prompts...

For non-Homebrew users, a 64-bit binary archive prepared on OS X 10.8 Mountain
Lion can be downloaded from:

- https://wincent.com/products/clipper

Alternatively, if you have a working Go environment on your system you can do:

    go get github.com/wincent/clipper

Finally, if you want to do things manually, you can clone from the authoritative
Git repo and build manually (which again requires a working Go environment):

    git clone git://git.wincent.com/clipper.git
    cd clipper
    go build clipper.go

### Additional steps for non-Homebrew installs

If you plan to use Clipper as a launch agent you'll either need to put it
somewhere the system can find it (ie. at a location in the standard PATH, such
as under `/usr/bin/`) or update the included property list file to specify the
full path to the location where you installed the Clipper executable.

The following example shows how you would install the built Clipper executable
to `/usr/bin/` after cloning the repo and performing a build. It also shows how
you would set up Clipper as a launch agent and start it running:

    sudo cp clipper /usr/bin
    cp com.wincent.clipper.plist ~/Library/LaunchAgents/
    launchctl load -w -S Aqua ~/Library/LaunchAgents/com.wincent.clipper.plist

Alternatively, if you'd like to run Clipper manually, you can do so with:

    ./clipper [--address=IP_ADDR] [--port=PORT] [--logfile=LOGFILE]

Note that both of these commands will fail to do the right thing inside of a
tmux session. Run `launchctl` from outside of tmux, otherwise Clipper will find
itself in the wrong execution context. Similarly, when running manually, either
run Clipper outside of tmux or use the aforementioned `reattach-to-user-space`
as a wrapper.

## Uninstalling

A Homebrew installation can be reversed with:

    brew uninstall clipper

A manual launch agent installation can be reversed with:

    launchctl unload ~/Library/LaunchAgents/com.wincent.clipper.plist
    rm ~/Library/LaunchAgents/com.wincent.clipper.plist
    sudo rm /usr/bin/clipper

As before, note that you should only run `launchctl` outside of a tmux session.

To kill a manually-launched instance of Clipper, just hit Control+C in the
terminal where it is running.

## Configuring tmux

Now we can use a slight modification of our command from earlier. Assuming we
kept the standard listen address (<IP_ADDRESS>) and port (8377), we can use a
command like this to send the last-copied text whenever we hit our tmux prefix
key followed by `y`:

    bind-key y run-shell "tmux save-buffer - | nc localhost 8377"

In tmux 1.8 or later, we have access to the new `copy-pipe` command and can use
a single key binding to copy text into the tmux copy buffer and send it to
Clipper and therefore the system clipboard at the same time:

    bind-key -t vi-copy Enter copy-pipe "nc localhost 8377"

Here we're using netcat (`nc`) to send the contents of the buffer to the
listening Clipper agent.

## Configuring Vim

There is nothing inherent in Clipper that ties it to tmux. We can use it from
any process, including Vim.

For example, we can add a mapping to our `~/.vimrc` to send the last-yanked text
to Clipper by hitting `<leader>y`:

    nnoremap <leader>y :call system('nc localhost 8377', @0)<CR>

## Configuring Zsh (or Bash)

By setting up an alias:

    alias clip="nc localhost 8377"

you can conveniently get files and other content into your clipboard:

    cat example.txt | clip
    ls /etc | clip

## Configuring SSH

Again, assuming default address and port, we can use `-R` like this:

    ssh -R localhost:8377:localhost:8377<EMAIL_ADDRESS>
With this, a tmux process running on the remote host can use the same
configuration file, and our `run-shell` from above will send the buffer
contents to localhost:8377 on the remote machine, which will then be forwarded
back over the SSH connection to localhost:8377 on the local machine, where
Clipper is listening.

See the "Security" section below for some considerations.

To make this automated, entries can be set up in `.ssh/config`:

    Host host.example.org
      RemoteForward 8377 localhost:8377

With this, forwarding is automatically set up any time you run:

    ssh<EMAIL_ADDRESS>
This works particularly well if you use the `ControlMaster`, `ControlPath` and
`ControlPersist` settings described in the `ssh_config` man page. These allow
you to set up a single forward, and re-use it each time you connect, even if you
have multiple concurrent connnections to a given server. An example
`~/.ssh/config` configuration that would give you this for all hosts would be
something like:

    Host *
      ControlMaster auto
      ControlPath ~/.ssh/%r@%h:%p
      ControlPersist 240

## Configuring Mosh

Mosh (http://mosh.mit.edu/) is an alternative to SSH that aims to be a superior
"mobile shell" than SSH. It is designed to handle intermittent connectivity, and
provides relatively intelligent local echoing of line editing commands, but it
doesn't yet support any kind of port forwarding (as of the current release,
which is version 1.2.4 at the time of writing).

One way to use Clipper with Mosh is to use Mosh for interactive editing but keep
using SSH for port forwarding. For example, just say you want to connect to a
remote machine with the alias "sandbox", you could have entries like this in
your `~/.ssh/config`:

    Host sandbox
      ControlMaster no
      ControlPath none
      Hostname sandbox.example.com

    Host sandbox-clipper
      ControlMaster no
      ControlPath none
      ExitOnForwardFailure yes
      Hostname sandbox.example.com
      RemoteForward 8377 localhost:8377

With this set-up, you can set up the tunnel with:

    ssh -N -f sandbox

SSH will connect to the server, set up the port fowarding and then go into the
background.

Then connect using Mosh (it will respect the settings in your `~/.ssh/config`
file because it uses SSH to bootstrap new connections):

    mosh sandbox

You could also set up a shell alias to make setting up the Clipper tunnel more
convenient; for example:

    alias clip-sandbox='ssh -N -f sandbox'

You should only need to re-run this command if the connection is interrupted for
some reason.

### Fixing `remote port forwarding failed for listen port 8377`

This message can be emitted when the remote host you're connecting to already
has something bound to the requested port. If there is a competing service that
you can't move to another port, Clipper can be configured to use a different
port with the `--port` switch, described above.

Another reason you might see this warning is because an old or stale SSH daemon
is lingering from a prior connection attempt. The following example commands
show how you can detect the PID of such a process (in this example, 29517) and
kill it off:

    $ sudo netstat -antpl | grep 8377 # look for offending PID (29517) in output
    $ ps auxww | grep 29517           # confirm it's your old sshd process
    $ kill 29517                      # kill off old process
    $ ps auxww | grep 29517           # confirm that process is really gone

For the bold and lazy, you can simply kill off all `sshd` process belonging to
your user with:

    $ killall -u $USER sshd

Do not do this as root, as you will lock yourself out of your server.

Consult the netstat man page for more details (supported options may vary
depending on the host operating system).

# "Reverse" Clipper

Clipper helps you get content into your local clipboard from other, possibly
remote, processes. To send content in the other direction, just paste normally.
Note that to make this pleasant in an envionment like Vim, you may want to set
up bracketed paste mode; see [my dotfiles for an
example](https://github.com/wincent/wincent/blob/3b0b2950cdcb09d23c87f0167c207d8c837cb1b2/.vim/plugin/term.vim#L93-114)
of how this can be done.

# Security

At the moment, Clipper doesn't employ any authentication. It does, by default,
listen only on the loopback interface, which means that random people on your
network won't be able to connect to it. People with access to your local
machine, however, will have access; they can push content into your clipboard
even if they can't read from it.

This may be fine on a single-user machine, but when you start using `ssh -R` to
expose your Clipper instance on another machine you're evidently increasing your
surface area. This may be ok, but my intention is to add an authentication
mechanism to the protocol in the near future in any case.

# Author

Clipper is written and maintained by Wincent Colaiuta<EMAIL_ADDRESS>
# Development

Development in progress can be inspected via the project's Git web-based
repository browser at:

- https://wincent.com/repos/clipper

the clone URL for which is:

- git://git.wincent.com/clipper.git

A mirror exists on GitHub; it is automatically updated once
per hour from the authoritative repository:

- https://github.com/wincent/clipper

Patches are welcome via the usual mechanisms (pull requests, email, posting to
the project issue tracker etc).

# Website

The official website for Clipper is:

- https://wincent.com/products/clipper

Bug reports should be submitted to the issue tracker at:

- https://wincent.com/issues

# Donations

Clipper is free software released under the terms of the BSD license. If you
would like to support further development you can make a donation via PayPal to
<EMAIL_ADDRESS>
-<EMAIL_ADDRESS>
# License

Copyright 2013 Wincent Colaiuta. All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

# History

## 0.2 (2 November 2013)

- Documentation updates
- Updated sample plist to use UTF-8 encoding by default

## 0.1 (19 February 2013)

- Initial release

repository: KSTechnologiesIndia/clipper

repo_name: KSTechnologiesIndia/clipper


text:
# duplicate-except (W0705)

*Catching previously caught exception type %s* Used when an except
catches a type that was already caught by a previous handler.

repository: codacy/codacy-pylint

gha_language: Python

repo_name: codacy/codacy-pylint


text:
# Johnny•Decimal Index Generator

Code for the [Johnny Decimal Index Generator](https://johnny-decimal-generator.netlify.app/) web app

- Design your [Johnny Decimal](https://johnnydecimal.com/) system with a drag & drop interface
- Generate the JD index in text format once you’re done
- [Web Share API](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/share) — Share easily from mobile devices
- PWA + [Workbox](https://developers.google.com/web/tools/workbox) — Install it and/or use it offline

## Develop

```bash
# clone from this repo or from your own fork
git clone https://github.com/ekafyi/johnnydecimal-index-generator.git
cd johnnydecimal-index-generator

# install dependencies (example with npm; you may also use yarn)
npm install

# run on develop mode
npm run start

# build to static "/build" directory
npm run build
```


text:
## Demolition Robot

Given a matrix with values 0 (trenches) , 1 (flat) , and 9 (obstacle) you have to find minimum distance to reach 9 (obstacle).

If not possible then return -1.

The demolition robot must start at the top left corner of the matrix, which is always flat, and can move on block up, down, right, left.

The demolition robot cannot enter 0 trenches and cannot leave the matrix.

Sample Input :
[
    [1, 0, 0],
    [1, 0, 0],
    [1, 9, 1]
]

Sample Output :
3

Explanation : [link](https://www.youtube.com/watch?v=KiCBXu4P-2Y)


text:
---
layout: default
---

# 1996-03-22 - Re: ASN.1 Tools/Compilers

## Header Data

From: Eric Young<EMAIL_ADDRESS>To: Frederick Zarndt<EMAIL_ADDRESS>Message Hash: 3a3ace99bdd09d49477beb1f3380a55587a313bed86ac1ce2c13c6117ab406e9

Message ID: \<Pine.SOL.3.91.960322125615.14909B-100000@orb\>

Reply To: \<s1512f9a.073@fromGW\>

UTC Datetime: 1996-03-22 10:20:42 UTC

Raw Date: Fri, 22 Mar 1996 18:20:42 +0800

## Raw message

```
{% raw  %}From: Eric Young<EMAIL_ADDRESS>Date: Fri, 22 Mar 1996 18:20:42 +0800
To: Frederick Zarndt<EMAIL_ADDRESS>Subject: Re: ASN.1 Tools/Compilers
In-Reply-To: <s1512f9a.073@fromGW>
Message-ID: <Pine.SOL.3.91.960322125615.14909B-100000@orb>
MIME-Version: 1.0
Content-Type: text/plain

On Thu, 21 Mar 1996, Frederick Zarndt wrote:
> Does anyone know of reliable ASN.1 tools/compilers suitable for use on a
> wide range platforms?

SSLeay contains a program asn1parse that will decompose ASN.1 structures.
It also has C routines to play with X509, CRL and certificate requests.
I did not write an ASN.1 compiler, I have written direct C code (using
macros).  I decided it would be easier that writing a compiler but it
has probably worked out about the same amount of effort.

eric
--
Eric Young                  | Signature removed since it was generating
AARNet<EMAIL_ADDRESS>  | more followups than the message contents :-)

{% endraw %}
```

## Thread

+ Return to [March 1996](/archive/1996/03)

+ Return to "[Eric Young <eay@mincom.oz.au>](/authors/eric_young_eay_at_mincom_oz_au_)"
+ Return to<EMAIL_ADDRESS>(Frederick Zarndt)](/authors/frederick_zarndt_at_novell_com_frederick_zarndt_)"

+ 1996-03-21 (Fri, 22 Mar 1996 05:20:32 +0800) - [ASN.1 Tools/Compilers](/archive/1996/03/4439fe41c86c5b92d3c45af2df38186143b56c3671170ba691d0187cf5354f8f) -<EMAIL_ADDRESS>(Frederick Zarndt)_
  + 1996-03-22 (Fri, 22 Mar 1996 18:20:42 +0800) - Re: ASN.1 Tools/Compilers - _Eric Young<EMAIL_ADDRESS>


text:
# Part A - Introducing Config Connector

## Introduction

Back in [Demo 1](/1-setup/), we used Terraform to set up a bunch of cloud resources, including multiple GKE clusters, IAM resources, Cloud SQL databases, and Secret Manager secrets. Terraform is great for bootstrapping hosted resources because like KRM, it uses declarative resource files like this —

```
resource "google_sql_database" "cymbal-dev-ledger-db" {
  project = var.project_id
  name     = "ledger-db"
  instance = google_sql_database_instance.cymbal-dev.name
}
```

— rather than imperative commands like `gcloud sql databases create...`. Chances are if you're not using Kubernetes, Terraform is a solid config management solution for your hosted resources.

But if you *do* use Kubernetes, you'll end up having two data formats, and two toolchains - Terraform for your cloud resources, and Kubernetes for your Kubernetes resources. Bringing cloud resources from Terraform (or another config management tool) into a KRM format has several benefits:

- Continuous reconciliation for cloud resources - the Kubernetes Controller model will make sure your cloud-hosted resources are always alive and in sync with the desired state.
- Unified toolchain (eg. use kustomize and CI/CD to populate all resources, both Kubernetes and cloud)
- 1 config format for developers to learn
- 1 config format to lint and validate
- Integration with Config Sync (Git source of truth will always match what's running in the cloud)
- Integration with Policy Controller (compliance checks for cloud-hosted resources, in addition to Kubernetes resources)

Of course, every organization has different needs, and if you're already invested in Terraform, it might make sense to continue using that alongside KRM.

In any case, let's learn how Config Connector works with GCP-hosted resources.

## Installation

Let's install Config Connector onto our GKE environment. We'll lifecycle cloud-hosted resources from the `cymbal-admin` cluster, so we'll install Config Connector there.

### 1. `cd` into the `5-hosted-resources/` directory from the root of this repository.

```
cd 5-hosted-resources/
```

### 2. **Set variables.**

```
export PROJECT_ID=your-project-id
export GITHUB_USERNAME=your-github-username
```

### 3. **Open `configconnector.yaml` and in line 8, replace `PROJECT_ID` with your Project ID.**

### 4. **Run the setup script.**

```
./setup-config-connector.sh
```

Expected output:

```
✅ Finished installing Config Connector on all clusters.
```

This script does the following:
1. Uninstalls Config Sync from the `cymbal-admin` cluster. (**Note** - currently a bug causes Config Sync and Config Connector to conflict with each other. In the future, you will be able to use Config Sync to deploy your Config Connector resources)
2. Grants Config Connector IAM permissions to lifecycle GCP resources in your project
3. Installs Config Connector on the `cymbal-admin` cluster.

grants Config Connector (running in the GKE cluster) the IAM permissions it needs to create and update GCP resources in your project, and deploys Config Connector onto the cluster.

### 5. **Verify that Config Connector is installed on the admin cluster.**

```
kubectx cymbal-admin
kubectl get pods -n cnrm-system
```

Expected output:

```
NAME                                            READY   STATUS    RESTARTS   AGE
cnrm-controller-manager-0                       2/2     Running   0          37s
cnrm-deletiondefender-0                         1/1     Running   0          3d19h
cnrm-resource-stats-recorder-68648fd95d-rpqcw   2/2     Running   0          3d19h
cnrm-webhook-manager-7d5b995bbc-bqvcs           1/1     Running   0          3d19h
cnrm-webhook-manager-7d5b995bbc-xpx65           1/1     Running   0          3d19h
```

## Creating a Compute Engine Instance with Config Connector

Let's start with a basic example of creating a GCP-hosted resource using Config Connector, declared with KRM. Let's say that one of the security admins in CymbalBank only has access to a Windows machine, and they want to start working with the platform team to study and create org-wide policies using the Policy Controller constraints we learned about in part 4. Because some of the tools we've learned don't support Windows yet, we can spin up a Linux host for them so they have access to a full development environment.

![screenshot](screenshots/secadmin-gce.jpg)

### 1. **View the GCE KRM resources.**

```
cat compute-engine/instance.yaml
```

Expected output:

```
apiVersion: compute.cnrm.cloud.google.com/v1beta1
kind: ComputeInstance
metadata:
  annotations:
    cnrm.cloud.google.com/allow-stopping-for-update: "true"
    configsync.gke.io/cluster-name-selector: cymbal-admin
  name: secadmin-debian
  labels:
    created-from: "image"
    network-type: "subnetwork"
spec:
  machineType: n1-standard-1
  zone: us-west1-a
  bootDisk:
    initializeParams:
      size: 24
      type: pd-ssd
      sourceImageRef:
        external: debian-cloud/debian-9
...
```

This KRM resource defines one Compute Engine instance, along with a Compute Disk and some networking resources. Notice how the KRM looks a lot like a Deployment YAML - it has a name, metadata with some labels, and a spec, with info specifically about a GCE instance. Config Connector knows how to read this `ComputeEngine` resource type, and take action on it - in this case, create a Compute Engine instance in our GCP project.

### 2. Apply the Compute Engine resources to the admin cluster.

```
kubectx cymbal-admin
kubectl apply -f compute-engine/instance.yaml
```

### 3. **Get the status of the deployed resources on the cymbal-admin cluster**

```
kubectl get gcp
```

Expected output:

```
NAME                                                                               AGE     READY   STATUS     STATUS AGE
computesubnetwork.compute.cnrm.cloud.google.com/computeinstance-dep-cloudmachine   5m57s   True    UpToDate   5m3s

NAME                                                            AGE    READY   STATUS     STATUS AGE
computeinstance.compute.cnrm.cloud.google.com/secadmin-debian   6m1s   True    UpToDate   4m3s

NAME                                                                            AGE     READY   STATUS     STATUS AGE
computenetwork.compute.cnrm.cloud.google.com/computeinstance-dep-cloudmachine   5m59s   True    UpToDate   5m48s

NAME                                                                          AGE   READY   STATUS     STATUS AGE
computedisk.compute.cnrm.cloud.google.com/computeinstance-dep1-cloudmachine   6m    True    UpToDate   5m44s
computedisk.compute.cnrm.cloud.google.com/computeinstance-dep2-cloudmachine   6m    True    UpToDate   5m48s

NAME                                                                AGE     READY   STATUS     STATUS AGE
iamserviceaccount.iam.cnrm.cloud.google.com/inst-dep-cloudmachine   5m58s   True    UpToDate   5m57s
```

Note - it may take a few minutes for the resources to be created. In the meantime, you may see `UpdateFailed` or `DependencyNotReady`. This is expected.

### 4. **Open the Cloud Console and navigate to [Compute Engine > VM Instances](https://console.cloud.google.com/compute/instances).**

Filter on `name:secadmin`. You should see the new GCE instance in the list.

![screenshots](screenshots/secadmin-gce-console.png)

**🌈 Nice job!** You just deployed your first cloud-hosted resource with KRM!

You'll notice that we (the platform admin) had to manually write the GCE resource as KRM, and deploy it to the admin cluster. In a real-life scenario, the platform team might even set up a self-service system with a basic web UI, so that Cymbal Bank employees can request a GCE instance. This web app would take in parameters (like choose an operating system from a drop-down menu, disk size, etc.), and generate a JSON or YAML file with the GCE KRM, then commit it to the policy repo, then have Config Sync apply the resource automatically. This would provide a hands-off way of allowing users to set up their own resources, while maintaining a centralized, auditable source of truth in Git.

**[Continue to Part B.](partB-cloud-policies.md)**

repository: raghu-manne/build-a-platform-with-krm

repo_name: raghu-manne/build-a-platform-with-krm


text:
# Reddit-Video-Moments-Generator
A script that goes through subreddits, gets a list of some of the videos and downloads them, concatenates them using FFmpeg and (when it's programmed in) posts the result to YouTube.

## Note:
This is an old project that is somewhat buggy and contains many dependencies. This was just a prototype/proof of concept so the code is more sloppy than it should be.