text:
# Spring-boot-jsonapi

  Receives a String and returns JSON formatted Geocode information from maps.googleapis.

## Getting Started

These instructions will get you a copy of the project up and running on your local machine for development and testing purposes.

### Prerequisites

JDK8 or later and Maven 3.0+

### Installing

Clone the project
```
git clone https://github.com/fcruz/spring-boot-jsonapi.git

```

Run with maven
```
cd spring-boot-jsonapi
mvn spring-boot:run
```

If you prefer create a jar and execute with java command
```
cd spring-boot-jsonapi
mvn package
java -jar target/fcruz-0.0.1-SNAPSHOT.jar

```

### Usage

Access following URL on your favorite browser

```
http://localhost:8080/location?address=Dam Square Amsterdam
```

Or use curl
```
POST: curl -d address=Dam+Square+Amsterdam http://localhost:8080/location
GET: curl http://localhost:8080/location?address=Dam+Square+Amsterdam
```

Expected Response

```
{"formatted_address":"Dam Square, Dam, 1012 JL Amsterdam, Netherlands","latitude":"52.3730677","longitude":"4.8926390"}
```

## Running the tests

class can be omitted if you want
```
mvn test or

```
or
```
mvn -Dtest=com.example.fcruz.LocationControllerTest test

```

## Swagger enabled API

http://localhost:8080/swagger-ui.html

## Built With

* [SpringBoot](https://projects.spring.io/spring-boot/) - The web framework used
* [Apache Camel](https://github.com/apache/camel/blob/master/README.md) - Used to build the integration
* [Maven](https://maven.apache.org/) - Dependency Management

## Author

* **Fabio Cruz** - [fcruz](https://github.com/fcruz)

## License

This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details

repository: fcruz/spring-boot-jsonapi

repo_name: fcruz/spring-boot-jsonapi


text:
# SwiftUI Verify API Test App

<img src="https://developer.nexmo.com/assets/images/Vonage_Nexmo.svg" height="48px" alt="Nexmo is now known as Vonage" />

This is a SwiftUI App that shows you how you can add Two-Factor Authentication with the Vonage Verify API. The app was built along side a [vapor swift server](https://github.com/nexmo-community/swift-vapor-verify). To learn more about it you can checkout the blog post.

## Welcome to Vonage

If you're new to Vonage, you can [sign up for a Vonage API account](https://dashboard.nexmo.com/sign-up?utm_source=DEV_REL&utm_medium=github&utm_campaign=swiftui-two-factor-app) and get some free credit to get you started.

## Running the project

- After cloning the project to your machine, open it in Xcode.
- Replace the `baseURL` with the URL of your server.
- Build and run (CMD + R) and the app will run on your simulator/device.

## Getting Help

We love to hear from you so if you have questions, comments or find a bug in the project, let us know! You can either:

* Open an issue on this repository
* Tweet at us! We're [@VonageDev on Twitter](https://twitter.com/VonageDev)
* Or [join the Vonage Developer Community Slack](https://developer.nexmo.com/community/slack)

## Further Reading

* Check out the Developer Documentation at <https://developer.nexmo.com>

license: MIT

repository: nexmo-community/swiftui-two-factor-app

branch_name: refs/heads/main

extension: md

license_type: permissive

repo_name: nexmo-community/swiftui-two-factor-app


text:
---
layout: "podcast-or-interview"

mp3_bytes: "57504000"
mp3_duration: "59:53"

guest: "Mubashar Iqbal"
guest_avatar: "mubashar-iqbal"
guest_website: "https://podhunt.app/"
guest_twitter: "mubashariqbal"

category: "podcast"
tags:
  - "laravel"
  - "php"
  - "vue"
  - "digitalocean"
  - "lets-encrypt"
  - "mysql"
  - "nginx"
  - "rds"
  - "redis"
  - "sentry"
  - "slack"
  - "uptime-robot"
  - "webpack"

title: "Pod Hunt Helps You Find Great Podcast Episodes to Listen To"
description:
  Mubs goes over building his podcast episode finding app with Laravel and PHP.
  It's hosted on DigitalOcean using Forge.
---

In this episode of Running in Production, {{ page.guest }} talks about building
a site to find podcast episodes with Laravel and PHP. It's hosted on
DigitalOcean using Forge and has been up and running since mid 2019.

Mubs talks about using a bit of Vue as needed, not upgrading to the latest
Laravel immediately, interesting problems around parsing RSS feeds, how Forge
lets him easily host his site, understanding the nuances of your app's domain
and more.

## Topics Include

- 4:50 -- Motivation for using Laravel and PHP over a bunch of other choices
- 8:20 -- It's using Laravel 6 with VueJS on the front-end for some parts
- 11:30 -- The app will get updated to the TALL stack but not quite yet
- 13:04 -- It's a monolithic app in 1 git repo
- 16:07 -- It's mostly using Blade templates with Vue thrown in where needed
- 19:12 -- MySQL is powering the database which is managed by RDS
- 21:09 -- Reading in RSS feeds in background jobs and processing Open Graph images
- 26:07 -- You need to get approved by Mubs before you can submit episodes
- 28:35 -- Redis is powering the background jobs
- 33:11 -- nginx / Let's Encrypt and it's hosted on DigitalOcean using Forge
- 39:06 -- The deployment process from development to production
- 45:49 -- There's about 3k lines of PHP code and a few hundred lines of JS
- 47:16 -- Secrets are managed through an env file that you put on your server
- 48:41 -- Database backups happen every day and everything else is backed up too
- 51:38 -- Sentry is in charge of exception handling and Uptime Robot for site monitoring
- 55:26 -- Best tips? Understand the nuances of the app you're building
- 56:30 -- Web tech is moving fast, will HTML over the wire be main stream soon?
- 59:06 -- Mubs has his own site at <https://mubs.me> and [he's on Twitter too](https://twitter.com/{{ page.guest_twitter }})

## Links

###### 📄 References

- <https://transistor.fm/>
- <https://twitter.com/taylorotwell> (creator of Laravel)
- <https://twitter.com/calebporzio/> (creator of Livewire)
- <https://twitter.com/jeffrey_way> (creator of Mix / Laracasts)
- <https://forge.laravel.com/>
- <https://podcastindex.org/>

###### ⚙ Tech Stack

{% include services-used.html %}

###### 🛠 Libraries Used

- <https://github.com/spatie/browsershot>

branch_name: refs/heads/master

gha_language: HTML

gha_license_id: MIT


text:
A common use of go-env is
to load a configuration struct with values set in the environment variables.

## Requirements

Go 1.13 or above.

## Getting Started

### Installation

Run the following command to install the package:

```
go get github.com/qiangxue/go-env
```

### Loading From Environment Variables

The easiest way of using go-env is to call `env.Load()`, like the following:

```go
package main

import (
	"fmt"
	"github.com/qiangxue/go-env"
	"os"
)

type Config struct {
	Host string
	Port int
}

func main() {
	_ = os.Setenv("APP_HOST", "<IP_ADDRESS>")
	_ = os.Setenv("APP_PORT", "8080")

	var cfg Config
	if err := env.Load(&cfg); err != nil {
		panic(err)
	}
	fmt.Println(cfg.Host)
	fmt.Println(cfg.Port)
	// Output:
	// <IP_ADDRESS>
	// 8080
}
```

### Environment Variable Names

When go-env populates a struct from environment variables, it uses the following rules to match
a struct field with an environment variable:
- Only public struct fields will be populated
- If the field has an `env` tag, use the tag value as the name, unless the tag value is `-` in which case it means
  the field should NOT be populated.
- If the field has no `env` tag, turn the field name into snake format and use that as the name. For example,
  a field name `HostName` will be turned into `Host_Name`, and `MyURL` becomes `My_URL`.
- Names are turned into upper case and prefixed with the specified prefix when they are used to look up
  in the environment variables.

By default, prefix `APP_` will be used. You can customize the prefix by using `env.New()` to create
a customized loader. For example,

```go
package main

import (
	"fmt"
	"github.com/qiangxue/go-env"
	"log"
	"os"
)

type Config struct {
	Host     string `env:"ES_HOST"`
	Port     int    `env:"ES_PORT"`
	Password string `env:"ES_PASSWORD,secret"`
}

func main() {
	_ = os.Setenv("API_ES_HOST", "<IP_ADDRESS>")
	_ = os.Setenv("API_ES_PORT", "8080")
	_ = os.Setenv("API_ES_PASSWORD", "test")

	var cfg Config
	loader := env.New("API_", log.Printf)
	if err := loader.Load(&cfg); err != nil {
		panic(err)
	}
	fmt.Println(cfg.Host)
	fmt.Println(cfg.Port)
	fmt.Println(cfg.Password)
	// Output:
	// <IP_ADDRESS>
	// 8080
	// test
}
```

In the above code, the `Password` field is tagged as `secret`. The log function respects this flag by masking
the field value when logging it in order not to reveal sensitive information.

By setting the prefix to an empty string, you can disable the name prefix completely.

### Data Parsing Rules

Because the values of environment variables are strings, if the corresponding struct fields are of different types,
go-env will convert the string values into appropriate types before assigning them to the struct fields.

- If a struct contains embedded structs, the fields of the embedded structs will be populated like they are directly
under the containing struct.

- If a struct field type implements `env.Setter`, `env.TextMarshaler`, or `env.BinaryMarshaler` interface,
the corresponding interface method will be used to load a string value into the field.

- If a struct field is of a primary type, such as `int`, `string`, `bool`, etc., a string value will be parsed
accordingly and assigned to the field. For example, the string value `TRUE` can be parsed correctly into a
boolean `true` value, while `TrUE` will cause a parsing error.

- If a struct field is of a complex type, such as map, slice, struct, the string value will be treated as a JSON
string, and `json.Unmarshal()` will be called to populate the struct field from the JSON string.


text:
# Remarks Client

This project demonstrates a simple approach to save Comments and Annotations into a remote server.

- Developed using Android Studio 2.2 preview 5.

## Comment and Annotation classes

These value classes use [AutoValue](https://github.com/google/auto/tree/master/value), they have less code without the need to worry about toString(), equals(), hashCode().
With the use of AutoValue and its practices the class holds the information assigned at creation time, becomes immutable, and its properties cannot be changed by other external methods accessing it.
Here are a few other [benefits](http://ryanharter.com/blog/2016/03/22/autovalue/) on why to use AutoValue.

Comment class has the following properties:

`String comment`: to store the text associated with the Comment instance.

`long timestamp`: indicates a UTC timestamp for this comment.

Annotation class has the following properties:

`String annotation`: to store the text associated with the Annotation instance.

`long timestamp`: indicates a UTC timestamp for this comment.

With the use of AutoValue extensions like [AutoValue: Moshi](https://github.com/rharter/auto-value-moshi) these classes can be converted to JSON for network communication.

These classes are using the [Builder Pattern] (http://www.informit.com/articles/article.aspx?p=1216151&seqNum=2). This pattern allows instantiation of objects using different number of parameters, specially when a parameter could easily use its default value, like the current timestamp when not provided. It's easier to add new properties to the class without the need to create a new constructor with a different combination of parameters.

### Alternative implementation

It is clear that it it's possible to create an abstract super class, call it Remark, containing these common properties, from which both Comment and Annotation would extend. Finally use a factory to construct a Remark, and given the parameters the returning object instance could be either a Comment or Annotation.

The current approach using AutoValue limits that extensibility, so it was a trade-off between having a more robust class, with better extensibility to add more properties in the future, versus having a bit more complex class hierarchy with less duplicate code.

This approach can be check at this [branch](https://github.com/sapuglha/remarks-client/tree/factory-pattern).

## TextInterface

Comment and Annotation classes implement this interface, and these are the methods they are required to implement:

`getText()`:  retrieves the message associated with the remark.

`getTimestamp()`: retrieves the timestamp associated with the remark.

An user interface can display a combination of both Comments and Annotations, and easily retrieve the text and timestamp associated with these two different objects.

## Networking

The use of AutoValue and its Moshi extension allowed for an easy integration with Retrofit 2.
All REST calls were implemented in the Rest class. This class is a singleton that holds an instance of an HTTP client. This client is initialized using a dynamic BASE_URL value according to the currently selected build variant.

New REST calls will benefit from less data usage, specially if using TLS since the HTTP client will need to perform that negotiation only on the first call.

It's possible to create new networking classes that would communicate to different backends, as long as it possible to convert the models to an input format that will be sent to the new backend. It's already possible to export the data as JSON, there is another AutoValue extension that would allow to export the data as Parcelable [AutoValue: Parcel extension](https://github.com/rharter/auto-value-parcel).

# Pending improvements

## Local data storage

Every new Comment or Annotation the user creates should be stored locally before sending to the remote store. Mark the item as not synchronized while storing locally, and on network sucess change the status to synchronized. A SQLite could be used to store the items.

More details on things to pay attention while synchronizing local and remote items: [Android Application Architecture (Android Dev Summit 2015)](https://youtu.be/BlkJzgjzL0c?t=2m29s)

## UI/UX

* Change main activity to open a list showing a list of previous Comments and Annotations.
* Use a FAB ([floating action button](https://material.google.com/components/buttons-floating-action-button.html)) on main activity to add a new item, on press it should show a list of possible options (Comment, Annotation)
* Upon new item type selection, start the AddActivity already knowing which item type is going to be added

## Crash reporting

Applications installed on users's devices do not provide remote access to troubleshoot defects. A good crash reporting tool will allow a better understanding of the app behaviour trough the use of logs, handled and unhandled exceptions. [Crashlytics](http://fabric.io/https://fabric.io/kits/android/crashlytics) is a simple to use tool that will meet all these listed requirements.

## Analytics

Fabric also provides [Answers] (https://fabric.io/kits/android/answers), it collects information about app usage, session counts, session length, user location.

repository: sapuglha/remarks-client

repo_name: sapuglha/remarks-client


text:
React Storage
==============

Storage Component for React.

## Demo & Examples

Live demo: [yuanyan.github.io/react-image](http://yuanyan.github.io/react-storage/)

To build the examples locally, run:

```
npm install
gulp dev
```

Then open [`localhost:9999`](http://localhost:9999) in a browser.

## Installation

The easiest way to use `react-storage` is to install it from NPM and include it in your own React build process (using [Browserify](http://browserify.org), etc).

You can also use the standalone build by including `dist/react-storage.js` in your page. If you use this, make sure you have already included React, and it is available as a global variable.

```
npm install react-storage --save
```

## Usage

```
var React = require('react');
var Storage = require('react-storage');
var App = React.createClass({

    render: function() {
        return (
            <Storage name={"foo"} value={"bar"}/>
        );
    }

});
```

## Properties

Attribute  | Options                   | Default             | Description
---        | ---                       | ---                 | ---
`name`      | *string*                  | `null`               | The key to the data stored in localforage.
`value`      | *string*                  | `null`               | The data associated with the specified name.
`useRaw`      | *boolean*                  | `false`               | If true, the value is stored and retrieved without JSON processing.
`autoSave`      | *boolean*                  | `true`               | If false, auto save is disabled.

repository: leviluo/qizFollow

repo_name: leviluo/qizFollow


text:
# Redux

This is a feature branch of `react-universally` that is up to with version `v11.0.1`.

It provides you with an example implementation of redux with simple custom data prefetching technique that works for the server and client.
=======
# Glamor

This is a feature branch of `react-universally` that is currently built against `v11.0.1`.

It provides you with a simple Glamor integration.

# About

  This is the `react-universally-glamor` feature repository for `react-universally` starter kit.

  It provides you with the build tooling and configuration you need to kick off your next universal react project with full support for Glamor.

  Look into `Header` and `Menu` components to check how the wrappers for these are styled using Glamor.

## What is Glamor?

  [Glamor](https://github.com/threepointone/glamor) is an Inline CSS for React components.

## Maintainer

  - [Lucian Lature](https://github.com/lucianlature)

# License

  MIT


text:
# Creating javascript plots in Python
This is a library that provides access to Matlab-like functions for easily creating javascript plots from within Python.

No need to deal with HTML, Javascript, or CSS to get some plots with multiple linestyles, colors, markers, and labels. The currently supported Javascript plotting libraries are Flot and NVD3 (which is a wrapper around D3).

One use case for this library is to have Python scripts running automatically and updating websites that serve Javascript plots to visitors. For example, we used this library to create and update the plots on [prespredict.com](http://prespredict.com). During US presidential election seasons, a cron job calls the plotting script daily, which automatically updates the plots on the website with data from the latest polls.

The currently supported plotting functions are:

    figure, clf, plot, title, xlabel, ylabel, grid, hold, legend, close

These functions are to be used with

    output_to_flot, output_to_nvd3, output_to_matplotlib

in order to visualize your plots.

This library works with the [matlab_utils_for_python](https://github.com/sendos/matlab_utils_for_python) library which also provides access to several Matlab-like functions and syntax, such as:
* Matlab-like arrays, which allow 1-based indexing and also Matlab-like slices
```python
    x = marray(some_list)
    y = x[1:3]
    z = x[1:2:end]
```
* Matlab-like ranges
```python
    for x in mrange[1:3:10]:
        fprintf('%d\n', x)
```

Note:
* The current code creates plots that can be viewed only in Firefox, because the json files are stored locally, and browsers like Chrome do not allow reading local files.
   * If you put the json files on a web server, then the plots can be viewed in other browsers.
* You can also use output_to_matplotlib to visualize the plots with matplotlib, mainly for use in initial development and debugging.

## Installation and Usage

* Download the files from [matlab_utils_for_python](https://github.com/sendos/matlab_utils_for_python) to your current folder or anywhere in Python's load path.
* Download the files of this library to your current folder or anywhere in Python's load path.
* Make sure you have NumPy installed with your Python.
* If you will use output_to_matplotlib for visualization, make sure matplotlib is installed.

Then, in your Python scripts add the following
```python
from matlab_plot_functions import *
```
and use the functions included in the module. Some sample code is shown below:
```python
from matlab_plot_functions import *

y1 = marray([99.86 , 95.60 , 104.21, 106.10, 113.05, 113.54, 110.52, 115.82, 121.35, 136.99, 143.66, 141.05]);
y2 = marray([118.81, 114.28, 123.94, 126.12, 128.27, 130.99, 118.42, 115.05, 130.32, 135.54, 142.05, 139.39]);
x1 = mrange[1:length(y1)]
x2 = mrange[1:length(y2)]

figure(1)
clf()
plot(x1,y1,'r')
hold('on')
plot(x2,y2,'b')
grid('on')

legend('AAPL','FB','Location','northwest')
xlabel('Month')
ylabel('Stock price')
title('AAPL vs FB stock')

figure(2)
clf()
plt_str = marray('b^','rs','g--s','m^','c+','k')
for Is in mrange[1:5]:
    y = randn(1,10)
    x = mrange[1:length(y)]
    plot(x,y,plt_str[Is])
    hold('on')
grid('on')
legend('Bob','Mike','Mary','Joanne','Will', 'Location','northwest')
xlabel('This is the xlabel text')
ylabel('This is the ylabel text')
title('The title of the plot')

figure(3)
clf()
y1 = randn(1,100)
y2 = randn(1,50) + linspace(0,5,50)
x1 = mrange[1:length(y1)]
x2 = mrange[1:2:length(y1)]
plot(x1,y1,'b-')
hold('on')
plot(x2,y2,'r--^')
legend('X','Y')
title('Some data')
xlabel('Time')

# To visualize the plots, uncomment one of the following output options
output = 'flot'
# output = 'NVD3'
# output = 'matplotlib'

num_figures = length(get_active_figures())

if output == 'matplotlib':
    plt.ion()
    for fig in mrange[1:num_figures]:
        output_to_matplotlib(fig)

    raw_input("Press ENTER to continue")

elif output == 'flot' or output == 'NVD3':
    output_to_html = output_to_flot if output == 'flot' else output_to_nvd3

    for fig in mrange[1:num_figures]:
        output_html_file = sprintf('test_plot_%s_%i.html', output, fig)

        output_to_html(fig, output_html_file)

        open_html_file(output_html_file)

else:
    error('Invalid value for output')
```

### Sample output
Below are the plots you get from the above code, using Flot as the output format.

## Authors

* **Andrew Sendonaris** - [sendos](https://github.com/sendos)

## License

This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details


text:
# Documentation

## Construct
```php
$messengerBot = new SlimMessenger\Controller($verifyToken, $appToken);
```

## Verify Webhook
When receive `GET` request, Slim Messenger Controller will automatically assume that it is request send by facebook
to verify webhook and will react accordingly.

## Events
Slim Messenger Controller class extends [Evenement EventEmitter](https://github.com/igorw/evenement) to manage
events and it's callbacks
```php
// receive message
$messengerBot->on('message', function($senderId, $messageText, $timestamp) { ... });

// receive attachment (image, video, ...)
$messengerBot->on('attachment', function($senderId, $attachmentObject, $timestamp) { ... });

// receive postback like when user click button from card that bot send
$messengerBot->on('postback', function($senderId, $postbackPayload, $timestamp) { ... });
```

repository: thirafidide/slim-messenger-controller

repo_name: thirafidide/slim-messenger-controller


text:
# Turing Pi Cluster - 7-node K3s Raspberry Pi Cluster

DEPRECATED: Please see my [pi-cluster](https://github.com/geerlingguy/pi-cluster) project for active development.

[![CI](https://github.com/geerlingguy/turing-pi-cluster/workflows/CI/badge.svg?branch=master&event=push)](https://github.com/geerlingguy/turing-pi-cluster/actions?query=workflow%3ACI)

This repository is a companion to a YouTube series by Jeff Geerling in 2020:

  - **Episode 1**: [Introduction to Clustering](https://www.youtube.com/watch?v=kgVz4-SEhbE) ([blog post](https://www.jeffgeerling.com/blog/2020/raspberry-pi-cluster-episode-1-introduction-clusters))
  - **Episode 2**: [Setting up the Cluster](https://www.youtube.com/watch?v=xNndbfxMCLo) ([blog post](https://www.jeffgeerling.com/blog/2020/raspberry-pi-cluster-episode-2-setting-cluster))
  - **Episode 3**: [Installing K3s on the Turing Pi](https://www.youtube.com/watch?v=N4bfNefjBSw) ([blog post](https://www.jeffgeerling.com/blog/2020/pi-cluster-episode-3-installing-k3s-kubernetes-on-turing-pi))
  - **Episode 4**: [Minecraft, Pi-hole, Grafana + MORE!](https://www.youtube.com/watch?v=IafVCHkJbtI) ([blog post](https://www.jeffgeerling.com/blog/2020/raspberry-pi-cluster-episode-4-minecraft-pi-hole-grafana-and-more))
  - **Episode 5**: [Benchmarking the Turing Pi](https://www.youtube.com/watch?v=IoMxpndlDWI) ([blog post](https://www.jeffgeerling.com/blog/2020/raspberry-pi-cluster-episode-5-benchmarking-turing-pi))
  - **Episode 6**: [Turing Pi Review](https://www.youtube.com/watch?v=aApByQWqnV0) ([blog post](https://www.jeffgeerling.com/blog/2020/raspberry-pi-cluster-episode-6-turing-pi-review))

You might also be interested in another Raspberry-Pi cluster I've maintained for years, the [Raspberry Pi Dramble](https://www.pidramble.com), which is a Kubernetes Pi cluster in my basement that hosts [www.pidramble.com](https://www.pidramble.com).

## Compatibility

This cluster configuration has been tested with the following Raspberry Pi and OS combinations:

  - Raspberry Pi 4 model B and HypriotOS
  - Raspberry Pi 4 model B and Raspberry Pi OS (32-bit)
  - Raspberry Pi 4 model B and Raspberry Pi OS (64-bit)
  - Raspberry Pi Compute Module 3+ and HypriotOS

Other models of Raspberry Pi and Compute Modules may or may not work, but the main thing you need is a cluster with at least 7 GB of RAM and at least 12 available CPU cores (every current Pi has 4 CPU cores), otherwise not all of the software will be able to run well.

This configuration will _definitely not_ run on the Pi Zero, or on Pis older than the Raspberry Pi 2 model B.

## Usage

First, you need to make sure you have K3s running on your Pi cluster. Instructions for doing so are in Episodes 2 and 3 (linked above).

When you run the K3s Ansible playbook, make sure you have `extra_server_args: "--node-taint k3s-controlplane=true:NoExecute"` in your K3s `group_vars/all.yml`, so pods are not scheduled on the master node, and that all your nodes have unique hostnames (e.g. on Pi OS, run `sudo hostnamectl set-hostname worker-01` to set a Pi to `worker-01`).

Then, you can deploy _all_ the applications configured in this repository with the `main.yml` playbook:

  1. Make sure you have [Ansible](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) installed.
  2. Install Ansible requirements:

     ```
     ansible-galaxy role install -r requirements.yml
     ansible-galaxy collection install -r requirements.yml
     ```

     These commands can be consolidated into one `ansible-galaxy install` command once Ansible 2.10 is released.

  3. Copy the `example.hosts.ini` inventory file to `hosts.ini`. Make sure it has the `master` and `node`s configured correctly.
  4. Edit the `ingress_server_ip` and `load_balancer_server_ip` in `group_vars/all.yml` and set them each to an IP address of one of the nodes. (Change any other variables in that file as necessary.)
  5. Run the playbook:

     ```
     ansible-playbook main.yml
     ```

Once that's done, there will be variety of applications running on your cluster, for example:

| Software | Address | Notes |
| -------- | ------- | ------- |
| Prometheus | http://prometheus.<IP_ADDRESS>.nip.io/ | N/A |
| AlertManager | http://alertmanager.<IP_ADDRESS>.nip.io/ | N/A |
| Grafana | http://grafana.<IP_ADDRESS>.nip.io/ | Default login is `admin`/`admin` |
| Drupal | http://drupal.<IP_ADDRESS>.nip.io/ | N/A |
| Wordpress | http://wordpress.<IP_ADDRESS>.nip.io/ | N/A |
| Minecraft | (`kubectl get service -n minecraft`) | See EULA in [Minecraft chart repo](https://github.com/helm/charts/tree/master/stable/minecraft) |
| Pi-hole | http://pi.hole/ | See [pihole role README](roles/pihole/README.md) |

The exact URLs will vary in your cluster; refer to the output of the Ansible playbook, which lists each service's exact URL.

## Caveats

They are a'plenty.

First of all, the configurations in this repository were built for local demonstration purposes. There are some things that are insecure (like storing some database passwords in plain text), and other things that are just plain crazy (like trying to run all the above things on one tiny Pi-based cluster!).

There are a few architectural decisions that were made that are great for 'day one' setup, but if you tried to flex K3s' muscle and drop/replace nodes while the cluster is running, you'd likely start running into some, shall we say, 'fun' problems.

For example, the MariaDB PVCs are tied to the local node on which they were first deployed, and if you do something that results in the MariaDB Deployment to change nodes for the deployed Pod... you may run into warnings like `FailedScheduling: 3 node(s) had volume node affinity conflict.`

Therefore, if you want to use this project as a base, and are planning on doing anything more than a local demo cluster, you are responsible for making changes to support a more production-ready setup, with better security and better configuration of persistent volumes and multi-pod scalability.

To do these things _correctly_ with Kubernetes takes a lot of work. It's usually _very_ easy—maybe deceptively easy—to get something working. It's harder to get it working reliably in an automated fashion when rebuilding the cluster from scratch (that's about the level where this repository is). And harder still is getting it working reliably with easy maintenance, fault-tolerance, and scalability.

Kubernetes is no substitute for a thorough knowledge of system architecture and engineering!

## Resetting the cluster

You'll likely want to blow away all the changes you've made in a cluster and start fresh every now and then. If you made a mistake, or something broke terribly, that problem goes away. Or, if you want to make sure you've automated the entire cluster build properly, it's best practice to rebuild a cluster frequently.

Regardless of the reason, here's how to quickly wipe the cluster clean (without re-flashing all the Raspberry Pis from scratch):

  1. In the `k3s-ansible` repository directory (which you used to set up the cluster), run:

     ```
     ansible-playbook -i inventory/hosts.ini reset.yml
     ```

     This command will likely have a few failures relating to files that can't be cleaned up until after a reboot.

  2. Reboot the Raspberry Pis (in the same directory):

     ```
     ansible -i inventory/hosts.ini all -m reboot -b
     ```

  3. Run the reset playbook a second time, to clean up the stragglers:

     ```
     ansible-playbook -i inventory/hosts.ini reset.yml
     ```

  4. Re-install K3s on the cluster:

     ```
     ansible-playbook -i inventory/hosts.ini site.yml
     ```

Now you can go back to the steps above under 'Usage' to set up applications inside the cluster!

> Important note: Any files that were downloaded for this repository, like the monitoring repository, still exist in the `pirate` (HypriotOS) or `pi` (Raspberry Pi OS) user's home directory. For a more complete reset, also delete all those files and directories. Or to go thermonuclear, re-flash all the Pi's eMMC or microSD cards.

## Author

The repository was created in 2020 by [Jeff Geerling](https://www.jeffgeerling.com), who writes [Ansible for DevOps](https://www.ansiblefordevops.com) and [Ansible for Kubernetes](https://www.ansibleforkubernetes.com).

gha_language: Jinja


text:
The JWT object
==============

The JWT object is the base of output objects after loading (see [JWS](jws.md) and [JWE](jwe.md).

Important note: A JWT object is immutable and you cannot modify it.

This object provides the following methods:

* `getHeaders()`: Returns the headers of the JWT object (protected and unprotected).
* `hasHeader($key)`: Returns true if the header (protected or unprotected) identified by `$key` exists, else false.
* `getHeader($key)`: Returns the header (protected or unprotected) identified by the key `$key`. If the header does not exists, an exception is thrown.
* `getProtectedHeaders()`: Returns the protected headers of the JWT object.
* `hasProtectedHeader($key)`: Returns true if the protected header identified by `$key` exists, else false.
* `getProtectedHeader($key)`: Returns the protected header identified by the key `$key`. If the header does not exists, an exception is thrown.
* `getUnprotectedHeaders()`: Returns the unprotected headers of the JWT object.
* `hasUnprotectedHeader($key)`: Returns true if the unprotected header identified by `$key` exists, else false.
* `getUnprotectedHeader($key)`: Returns the unprotected header identified by the key `$key`. If the header does not exists, an exception is thrown.
* `hasHeaderOrClaim($key)`: Returns true if the JWT object contains a header or a claim identified by the key `$key`, else false.
* `getHeaderOrClaim($key)`: Returns the header or the claim identified by the key `$key`. If it does not exists, an exception is thrown.
* `hasClaims()`: Returns true if the payload may contain claims (i.e. the payload is an array).
* `getClaims()`: Returns all claims. This method throws an exception if the payload is not an array.
* `hasClaim($key)`: Returns true if the claim identified by the key `$key` exists, else false.
* `getClaim($key)`: Returns the claim identified by the key `$key`. If it does not exists, an exception is thrown.
* `getPayload()`: Returns the payload.

Internally, the library uses the following methods:

* `getInput()`: Returns the input as passed to the `Loader` object

repository: gitter-badger/jose

repo_name: gitter-badger/jose


text:
# Blackjack Game Strategy Simulator

This is an ongoing project to create a basic console based multi-player simulator to verify the results of playing different strategies when playing Blackjack.

## Background

The idea was to compare random play with basic strategy and card counting.

## Implementation

This is an example of a simulation featuring: 2 players playing randomly, with 1 deck, that is run 1000 times:

    blackjack = Blackjack(1000, 1, Rules())

    players = [Player(StrategyType.Random),Player(StrategyType.Random)]
    players = blackjack.play(players)

    for counter, player in enumerate(players):
        print("player_" + str(counter + 1), " ", player.get_score().to_string(), " ", player.get_strategy_name())

## Things to complete

- Implement full Basic Strategy
- Complete unit tests
- Allow game rules to be configured via the Rules object
- Export each round in simulation to csv


text:
# GAREN-2.0
 Program used to calculate optimal ultimate damage of Garen from the popular game League Of Legends

The app is a pretty straightforward command line app, you just have to insert your ultimate level, the total amount of health and it will display the optimal amount of damage you can make with it. For a GUI app see also: garen_gui

TODO:

-Explain the formula of ultimate damage

-Add information about garen ultimate and reasons to use the program

-And more

Instructions to compile:

For windows use "gcc main.c -D windows"

For Linux/MacOS use "gcc main.c -D unix"

Updated as of LoL patch 11.14.

This is a fan-made app and all rights are reserved to Riot Games based in Santa Monica, California.

license: Unlicense

gha_language: C

gha_license_id: Unlicense


text:
---
layout: post
title: "Well-founded Recursion"
excerpt: "Generalizing structural recursion for languages with termination checker, part 1"
category: ["recursion", "induction", "type theory"]
modified: 2021-10-01
---

## Introduction

As we (may) know recursion is one of the most important elements in functional
programming, and one of the charm of recursion, usually paired with
algebraic data types is that the computation can be guaranteed to terminate
by the compiler, if implemented in a specific way, a.k.a. the
"[Structural Recursion](https://en.wikipedia.org/wiki/Structural_induction)".

For example:

```haskell
data Tree = Leaf | Branch Tree Int Tree

treeSum :: Tree -> Int
treeSum Leaf = 0
treeSum (Branch l x r) = treeSum l + x + treeSum r
```

`treeSum` could be guaraneteed that it terminates regardless of
the input (although haskell doesn't do that by default), because the argument of
the recursive call `treeSum l` and `treeSum r` is _strictly smaller_ than the
parameter, in the sense that `l` and `r` are the "sub-structure" of the input
`Branch l x r`.

The structural recursion is even more important in theorem provers like Agda
and Coq, and the structural condition is strictly enforced by those compilers,
because otherwise we would be able to prove anything with an infinite loop.

```coq
(* Of course this would be rejected by Coq *)
Definition anything_is_true (A : Prop) : A := anything_is_true A.
```

However, the structural restriction is sometimes a bit too strong, even though
sometimes it's "easy" to tell that the structure of the arguments for the
recursive call should be decreasing, consider this famous sorting algorithm:

```haskell
quickSort :: Ord a => [a] -> [a]
quickSort [] = []
quickSort (x : xs) = quickSort l ++ [x] ++ quickSort r
  where
    l = filter (<= x) xs
    r = filter (>  x) xs
```

Of course haskell doesn't argue with us about this recursive definition, but it
should be clear that this is **not** a structural recursion, as `l` and `r` here are
not necessarily structurally smaller than the argument `x : xs`. And language
like "Coq" would mercilessly reject a similar definition. Although coq is being
reasonable rejecting this definition, how do we convince the compiler that this
is indeed a safe recursive call, given the `filter` is implemented properly.
Years ago I implemented a similar thing in agda, and what I did is use a compiler
pragma to bypass the structural termination check, which surely is not a very
reliable way if we are going to implement something more complicated than this.

In these two (or three) articles, I'm going to share some of the interesting
techniques I learned which enable us to implement less restricted recursions,
without violating the structural recursion restriction.

For the sake of visual clarity I would use Idris (instead of Coq) as the sample
langauge which has a similar syntax to Haskell.

## Well-founded Recursion/Induction

### Well-founded Relation and the Finitely Descending Chain

Our first technique, probably the most practical one we are going to explore
, makes use of this set theory concept "[Well-founded Relation](https://en.wikipedia.org/wiki/Well-founded_relation)",
frankly the mathematical definition looks quite scary for those unfamiliar with the notations.
But the idea is, given a set $$ S $$ with a binary relation $$ R $$, and
with an arbitrary element $$ {a~|~a \in S} $$, we can find a chain with relation $$ R $$:
$$ R~a_0~a $$, $$ R~a_1~a_0 $$ , $$ R~a_2~a_1 $$ and it goes on.
If for any element $$ a \in S $$, this chain starts from $$ a $$ **stops** at some point,
i.e. $$ R~a_{n+1}~a_n $$ , but there does **NOT** exist $$ \{m~|~m \in S \land R~m~a_{n+1} \} $$,
then we say the relation is well-founded. For example, the "less-than"
($$ < $$) relation on natural number set is well-founded, because for any
arbitrarily chosen number $$ n $$ and an arbitrarily chosen "less-than chain",
the chain always stops at 0, because there isn't any natural number that is
less than 0.

Why is this useful? Well, not immediately, but it gives us a tangible approach
to convince someone who doesn't trust intuition (the compilers) that some recursive
call terminates: if we are given a natural
number `x` as argument for some recursive function `f`, then as long as we guarantee
the argument of all the recursive calls are _less than_ `x`, we guarantee the
recursion terminates, because "less-than" is a well-founded relation, and as
long as we follows the "chain" when making recursive calls, the chain has to
terminate at some point to respect the mathematical truth.

And we can conceptualize the "chain" with something like this:

```haskell
data ChainOf : (a -> a -> Type) -> a -> Type where
  Stop : (x : a) -> ((y : a) -> Not (DPair a (\y => r y x))) -> ChainOf r x
  GoOn : (x : a) -> (y : a) -> r y x -> ChainOf r y -> ChainOf r x

f : ChainOf r a -> ()
f (Stop x p) = ()                    -- do something with base case
f (GoOn x y p subChain) = f subChain -- do something between x and y
```

And we can safely define a recursive function with respect to the structure of
the chain constrained by the relation `r`, breaking free from having to recurse
on the structure of the exact value (`y` doesn't have to be a sub-structure of `x`,
yet the recursive call shift the argument from something about `x` to something about `y`).

However this definition of `ChainOf` isn't that practically useful, since we have
no control over the value of the sub-case of recursion,
we are given `y` and a proof that `r y x` holds, but when defining recursive function like `quickSort`,
what we want is a specific value of argument for sub-cases
(from `x : xs` to `filter (<=) xs`, for example), an arbitrary pre-selected choice wouldn't do.

### `Acc` and its Recursion Operator

So instead of recursing on a specific chain, we need a collection of chains from
which we can select the ones that suits our need. In most of the cases
the potential choices could be infinite, so we could do something like this:

```haskell
-- Acc is short for "Accessible"
data Acc : (a -> a -> Type) -> a -> Type where
  MkAcc : (x : a) -> ((y : a) -> r y x -> Acc r y) -> Acc r x
```

Here `Acc r x` reads: `x` is _accessible_ (from the end of the chain) using relation `r`.
The function `(y : a) -> r y x -> Acc r y` gives us a way to select the next step of recursion,
but of course we cannot just select an arbitrary value in the set (of type `a`), we need
to provide a proof that the `y` we choose indeed satisfies `r y x`.
So this simple, eh, probably not, this minimal definition captures all the
possible chains from the end of the chain to `Acc r x`.

But wait, how this single constructor expresses where the chain stops? The chain
stops when there isn't any `y : a` such that `r y x`, so the selection pool for
"next steps" is practically empty as we wouldn't be able to access any next
step `Acc r y` if we cannot prove any `r y x`.

And for those of you who are familiar with inductive/recursive principles, the
recursive principle for this type, or the fixpoint operator we are looking for is:

```haskell
accRec : {P : a -> Type}
      -> ((x : a) -> ((y : a) -> r y x -> P y) -> P x)
      -> {x : a} -> Acc r x -> P x
accRec rec (MkAcc x f) = rec x $ \y, ryx => accRec rec (f y ryx)
```

From the perspective of the definition of this operator, ignoring the the
longest parameter type, the type of the function says:
if `x` is _accessible_ with a certain `r`, when you give me _something_ (the parameter with the longest type),
I can help you run the recursive procedure and give you the final result (`P x`).
And the longest parameter type says: for all the possible `x`,
if you can show me how to compute the result for all `y` which is the next step
of the chain, I can show give you the result for `x`.

Then the definition is rather short since we only have one case to deal with,
the key is to show the recursive procedure (`rec`) that, starting from an
arbitrary sub-case (`y : a` with `r y x`), how to compute the result about `x` (`P x`),
which is indeed possible because the accessibility condition (`Acc r x`) helps
us prove that any sub-case `y` is accessible given `r y x`.
Then the recursive call of `accRec` handles the rest.

Before delving into the important details of this recursive definition, let's quickly
formulate the "well-founded" condition, and show you how they are used:

```haskell
wellFounded : (r : a -> a -> Type) -> Type
wellFounded {a} r = (x : a) -> Acc r x

-- simply delegates to accRec
-- as `wellFounded` says any value of `a` is accessible
wfRec : {P : a -> Type}
     -> ((x : a) -> ((y : a) -> r y x -> P y) -> P x)
     -> wellFounded r -> (x : a) -> P x
wfRec rec wf x = accRec rec (wf x)
```

### Well-founded Recursion and Revisiting Quicksort

Now let's go back to the quicksort and think about what are we doing with the list.
The well-founded relation we can find here, is that the argument lists for the
recursive call is guaranteed to be shorter than the the original argument.
And we know that the length of finite lists can only decrease finitely,
hence a comparison on length of the two lists is a well-founded relation.

So first we are going to define a relation about the lengths of two lists, and
convince our compiler that the relation is indeed well-founded.

```haskell
LengthLT : {a : Type} -> List a -> List a -> Type
LengthLT xs ys = LT (length xs) (length ys)

wfLengthLT : {a : Type} -> wellFounded (LengthLT {a})
wfLengthLt = ...
```

I omit the proofs here, but if you are interested you
can find them [here](https://github.com/VinaLx/playground/blob/master/WellFoundedInd.idr)

Then the implementation for quicksort follows:

```haskell
quickSort : Ord a => List a -> List a
quickSort {a} = wfRec {P = const (List a)} quickSort' wfLengthLT
  where
    quickSort' : (xs : List a)
              -> ((ys : List a) -> LengthLT ys xs -> List a)
              -> List a
    quickSort' [] _ = []
    quickSort' (x :: xs) rec
      =  rec (filter (\v => v <= x) xs) (LTESucc (filterSmaller _))
      ++ [x]
      ++ rec (filter (\v => v > x) xs) (LTESucc (filterSmaller _))
```

Unlike the complex-looking types of the fixpoint operator and quicksort itself,
the actual definition is rather clean. We delegate the implementation of quicksort
to a application of the well-foundedness recursive operator `wfRec`. Like using a
conventional fixpoint operator, we accept the recursive version of the function
as a parameter (`rec`), but here the recursive call is guarded by the condition
that the argument have to be shorter than the argument of parent call (`LengthLT ys xs`).
And we have to provide the proof of such relation holds upon making the recursive
call (`LTESucc (filterSmaller _)`). In this case we guarantee that the whatever
comes out of the `filter` must not be longer than whatever goes in (idris
generously provide exactly what we need in the library (`filterSmaller`)), hence the
argument of the recursive call is at least shorter by one than the argument of
the caller. Then the rest is only that you convincing yourself calling the `rec`
is indeed making a recursive call.

Although it looks like we are doing exactly the same thing as in the intro, this
definition perfectly conforms the structural restriction, hence is guaranteed by
the compiler that it terminates with all possible inputs. Quite impressive isn't it?

### The Mystery of Structural Recursion

Apparently we achieve all these with the conventional structural recurison, but
if you looking carefully at the definition of our essential operator:

```haskell
accRec : {P : a -> Type}
      -> ((x : a) -> ((y : a) -> r y x -> P y) -> P x)
      -> {x : a} -> Acc r x -> P x
accRec rec (MkAcc x f) = rec x $ \y, ryx => accRec rec (f y ryx)
```

The argument of the recursive call is `f y ryx`. How is it a sub-structure of
`MkAcc x f` when it's a return value of a function call? And more importantly
this definition doesn't look terminating when there is only one case, and it's
a recursive case.

Well, it definitely should terminate as that's what mathematics tells us.
~~The most straightforward way to look at it is that it's an generalized inductive
type (or reflexive data type) that the function represents a mapping from an
generalized index to a sub-structure.~~ But probably easier to understand, another
way is realizing that the function is not arbitrary, it comes from a correctly
constructed value of inductive types, which is obligated to find a function
that correctly construct the "sub-structure" whose procedure has to be finite
(with the structural restriction enforced). So in the end, it _will_ go down
to the end of the chain, where any further descend will lead to a
contradiction. For example when constructing (Acc (<) 0), it's impossible to find
any natural number `a` such that `a < 0`, hence the definition of
`(a : Nat) -> a < 0 -> Acc (<) a` is trivial.

That's also how a (seemingly) single case of recursion covers both base case
and recursive case. When reaching the end of the chain, where there is no `y`
such that `r y x`, `r y x` is isomorphic to $$ \bot $$ (a type with no value),
so whatever we do when constructing `(y : a) -> r y x -> P y` is trivial
since it's impossible to find its arguments and the recursion will never be called.


text:
📦 nodeployed

  Automatically deploy your code to server after push to repository.

[![NPM version](https://img.shields.io/npm/v/nodeployed.svg?style=for-the-badge)](https://www.npmjs.com/package/nodeployed)
[![License](https://img.shields.io/npm/l/nodeployed.svg?style=for-the-badge)](https://github.com/Kurzdor/nodeployed/blob/master/LICENSE)
[![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=for-the-badge)](#contributors)

## Another deployer?!

I wanted to make the process of deploying code to server easier on each push to repository. I tried almost all suggested ways to do it but they didn't work. So I created this package. It supports Ubuntu servers and GitHub/GitLab/Bitbucket repos.

## Uses

Nodeployed uses [Fastify](https://www.fastify.io) as Node.js server, [Execa](https://github.com/sindresorhus/execa) to run such commands to deploy code and [Minimist](https://github.com/substack/minimist) to parse command arguments.

## Server preparation

To be able to use it sucessfully, you need:

- Install Node.js and npm on your server

* Setup your Apache/NGINX server to _reverse proxy_ all requests to `http://localhost:YOUR_PORT` in `location` block:

* For `NGINX` change your server block config to something like this:

```nginx
# Your server in /etc/nginx/sites-available/example.com
server {
...
    location /deploy/ {
        proxy_pass http://localhost:YOUR_PORT;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
...
}
```

- For `Apache2`:

```apache
<VirtualHost *:*>
    ProxyPass /deploy/ http://<IP_ADDRESS>:3000/
    ServerName localhost
</VirtualHost>
```

- Optionally: [Install LetsEncrypt](https://www.digitalocean.com/community/tutorials/how-to-secure-nginx-with-let-s-encrypt-on-ubuntu-18-04) on that domain that you will use.
- Clone repository that you want to work with with `git clone`
- Run `sudo chown -R yourusername:webserverusername you-repo-dir-name/` for your repository directory to make script able to fully use `git` commands.

## Usage

Install package globally from `NPM repo` via `npm` and start the process with [pm2](http://pm2.keymetrics.io/):

```sh
$ npm i -g nodeployed pm2
$ pm2 start nodeployed -- --port 8234 --dir /absolute/path/to/git/dir/ --command "command1_to_run && command2_to_run ..."
```

Go to `http://example.com/deploy`.
If script is properly working then you should see this message:

```plain
Nodeployed is working! You should set this link in your Webhooks configuration for your repository!
```

We will configure our repository later in `Configure repository for nodeployed` section.

Also if you want to run `nodeployed` as system service `pm2` can help you. For that run next commands:

```sh
$ pm2 startup systemd
```

And then `copy the command from the output` and run it, example:

```sh
$ sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u user --hp /home/user
```

You can save current configuration of running applications if you run multiple instances of `nodeployed`:

```sh
$ pm2 save
```

Then you can see the status of `pm2 system service` by running:

```sh
$ systemctl status pm2-user
```

or start it:

```sh
$ sudo systemctl start pm2-user
```

or stop it by running next command:

```sh
$ sudo systemctl stop pm2-user
```

where user – username that gave you `pm2` from running the `pm2 startup systemd` command.

## Configure repository for nodeployed

### GitHub:

1. Go to the directory for which you would like to setup autodeploy to your server.
2. Go to `Settings` page.
3. Go to `Webhooks` page => `Add webhook`.
4. Type in your GitHub password if prompted
5. Setup webhook:

- Payload: http://example.com/deploy/?token=YOUR_TOKEN_FROM_ARGUMENT
- Content Type: application/json
- Which events would you like to trigger this webhook? Just the push event.
- Active: check it
- Press `Add webhook`

6. Now on any push to this GitHub repository `nodeployed` should pull changes on server and run deploy commands.

### GitLab:

1. Go to the directory for which you would like to setup autodeploy to your server.
2. Go to `Settings` => `Integrations`.
3. Setup webhook:

- URL: http://example.com/deploy/?token=YOUR_TOKEN_FROM_ARGUMENT
- Secret Token: `leave it empty`
- Trigger events: Push events
- Enable SSL verification: check it if you have installed `LetsEncrypt`
- Press `Add webhook`

4. Now on any push to this GitLab repository `nodeployed` should pull changes on server and run deploy commands.

### Bitbucket:

1. Go to the directory for which you would like to setup autodeploy to your server.
2. Go to `Settings` => `Webhooks` => `Add webhook`.
3. Setup webhook:

- Title: any value, e.g. `nodeployed` to recognize it
- URL: http://example.com/deploy/?token=YOUR_TOKEN_FROM_ARGUMENT
- Skip certificate verification: check it if you haven't installed `LetsEncrypt`
- Enable request history collection: check it
- Triggers: Repository push
- Press `Save`

4. Now on any push to this Bitbucket repository `nodeployed` should pull changes on server and run deploy commands.

## Options

### --port [PORT]

Default: `9000`\
Maximum: `65535`\
Type: `number`

Sets IPv4 port on which server will be running and listening for requests.

### --token [TOKEN]

Type: `string:required`

Sets the token to validate server request.

### --dir [DIR_PATH]

Type: `string:required`

Sets the `absoulte` path to target deploy GIT repository.

### --command [COMMANDS]

Default: `bash ./deploy.sh`\
Type: `string`

Pass commands that needs to run after pull from repository/to deploy, e.g. `--command "npm install && npm run build"`.
If nothing passed to `--command` it will fallback to command `bash ./deploy.sh` so you need to manually create this script with all needed commands.

### --branch [BRANCH_NAME]

Default: `master`\
Type: `string`

Sets the working branch for target deploy GIT repository.

## LICENSE

MIT
## Contributors

Thanks goes to these wonderful people ([emoji key](https://github.com/all-contributors/all-contributors#emoji-key)):

Paul Ekshmidt
💻 📖 🚧 🤔
Vladislav
💻 🚇

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!

repository: kennycaiguo/nodeployed

repo_name: kennycaiguo/nodeployed


text:
# ZAPP

Zapp gives you easy access to a large number of German public broadcasting live streams. Watch ARD, ZDF and other channels live. Zapp makes it easy to quickly switch between channels.

![ZAPP logo](app/src/main/res/mipmap-xxxhdpi/ic_launcher.png)

repository: meonwax/zapp

repo_name: meonwax/zapp


text:
* Title:	StatefulSet Basics - Kubernetes
  * Url:	https://kubernetes.io/docs/tutorials/stateful-application/basic-stateful-set/

* Title:	Dynamic Volume Provisioning - Kubernetes
  * Url:	https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/

### Dynamically provision PersistentVolumes
```
$ microk8s.kubectl get all
$ microk8s.kubectl apply -f dynProvPersVols.yaml
$ microk8s.kubectl apply -f dynProvPersVols.web.yaml
$ microk8s.kubectl get sc
```

* Title:	DNS is crashlooping · Issue #67 · ubuntu/microk8s
  * Url:	https://github.com/ubuntu/microk8s/issues/67

```
$ sudo ufw allow in on cbr0 && sudo ufw allow out on cbr0
```

 ### Create the Headless Service and StatefulSet defined in web.yaml.

```
$ microk8s.kubectl get all
$ microk8s.kubectl delete -f web.yaml
$ microk8s.kubectl delete pvc www-web-0
$ microk8s.kubectl create -f web.yaml

service/nginx created
statefulset.apps/web created
```

The command above creates two Pods, each running an NGINX webserver.
Get the nginx Service and the web StatefulSet to verify that they were
created successfully.

### Ordered Pod Creation
For a StatefulSet with N replicas, when Pods are being deployed, they are created sequentially, in order from {0..N-1}. Examine the output of the kubectl get command in the first terminal. Eventually, the output will look like the example below.

```
$ microk8s.kubectl get all
$ microk8s.kubectl get pods -w -l app=nginx
```

### Pods in a StatefulSet
Pods in a StatefulSet have a unique ordinal index and a stable network identity.

Examining the Pod’s Ordinal Index
Get the StatefulSet’s Pods.

```
$ microk8s.kubectl get all
$ microk8s.kubectl get pods -l app=nginx
$ microk8s.kubectl logs web-0
$ microk8s.kubectl delete -f web.yaml
$ microk8s.kubectl create -f web.yaml
```

As mentioned in the StatefulSets concept, the Pods in a StatefulSet have a sticky, unique identity.
This identity is based on a unique ordinal index that is assigned to each Pod by the StatefulSet controller.
The Pods’ names take the form <statefulset name>-<ordinal index>.
Since the web StatefulSet has two replicas, it creates two Pods, web-0 and web-1.

### Using Stable Network Identities
Each Pod has a stable hostname based on its ordinal index. Use kubectl exec to execute the hostname command in each Pod.

```
$ microk8s.kubectl get all
$ for i in 0 1; do microk8s.kubectl exec web-$i -- sh -c 'hostname'; done
```


text:
# <%= projectName %>

**COMPONENT DESCRIPTION GOES HERE**

## Demo & Examples

Live demo: [<%= ghUser %>.github.io/<%= packageName %>](http://<%= ghUser %>.github.io/<%= packageName %>/)

To develop and see this component in action, please check the [README](../../README.md) at the top level of this repo for instructions.

If you want to run test for this component locally, please run:

```bash
$ clap check
```

## Installation

The easiest way to use <%= packageName %> is to install it from NPM and include it in your own React build process.

```bash
$ npm install <%= packageName %> --save
```

This component is designed to work with React application built with [Electrode].

## Usage

**EXPLAIN USAGE HERE**

```js
var <%= componentName %> = require('<%= packageName %>');

<<%= componentName %>>Example</<%= componentName %>>
```

### Properties

-   **DOCUMENT PROPERTIES HERE**

### Notes

**ADDITIONAL USAGE NOTES**

## Development (`src`, `lib` and the build process)

**NOTE:** The source code for the component is in `src`. A transpiled CommonJS version (generated with Babel) is available in `lib` for use with node.js and webpack. A UMD bundle is also built to `dist`, which can be included without the need for any build system.

## License

**PUT LICENSE HERE**

Copyright (c) <%= currentYear %> <%= developerName %>.

[Electrode]: https://docs.electrode.io/overview/what-is-electrode.html

repository: friederbluemle/electrode

gha_license_id: NOASSERTION

repo_name: friederbluemle/electrode


text:
# ML-rock-paper-scissors

Machine learning application for game Rock-Paper-Scissors

## What is it?

Main purpose is to make algorithm to classify picture of hand to certain class, which is rock, paper or scissors.
Alternatively application can be used for any set of pictures.

## Used technologies:

```
$ Python
$ joblib
$ matplotlib
$ numpy
$ pandas
$ Pillow
$ scikit-learn
```

## Installation

It is best to use the python `virtualenv` tool to build locally:

```
$ git clone https://github.com/BartekStok/ML-rock-paper-scissors
$ cd 05_ml_rps_game
$ virtualenv -p python3 venv
$ source venv/bin/activate
$ pip3 install -r requirements.txt
```

## Usage

1. First go to `settings.py` and set path to picture folders. Then set
 names for labels. Folders must be named just like the labels to recognize.
Lastly choose size of picture.

2. Go to `preprocess.py` and run the program. Be aware that all pictures
in given paths will be resized to chosen size! In data folder inside rps_model
will appear files named after folder name.

3. Run file `model_train.py`. There should appear plot with random samples
like:

![random](rps_model/data/example_pic.png)

Plot with amounts of data to process:

![amounts](rps_model/data/amounts.png)

And Confusion matrix with model data as is and in percentage:
![cmx](rps_model/data/conf_matrix.png)

Also in python console will be printed all model scores i.e. Accuracy, Precision,
Recall, and F1 Score.

4. If You want to run full cross validation with various solvers,
then in `model_train.py` is a section with cross validation
function, uncomment it and run file. Be aware that it takes long
time to compute, depending from amount of data.

5. At the very bottom of the `model_train.py` file, there
is a section to train final model with all data available, and
to export model to a file. Uncomment for execution.

6. Next step is `varia.py`, where, after running the file, and
with given results from cross validation, two plots should appear:

![cv_comp1](rps_model/data/cv_comparison_1.png)
![cv_comp2](rps_model/data/cv_comparison_2.png)
It is a comparison of data from cross validation with different
solvers.

7. Last step is to predict. File `predict.py` is for that, it loads
saved model, then after setting up proper path to an image,
prediction should be made.

## License

This project is licensed under the MIT License

- Copyright 2020 © Bartłomiej Stokłosa

repository: BartekStok/ML-rock-paper-scissors

gha_language: Python

repo_name: BartekStok/ML-rock-paper-scissors


text:
---
title: 624. I Want Jesus to Walk With Me - Seventh Day Adventist Hymnal
metadata:
    description: |
      SDAH 624. I Want Jesus to Walk With Me. 1.  I WANT JESUS TO WALK WITH ME
#### Seventh Day Adventist Hymnal

```txt

1.
I want Jesus to walk with me.
(walk with me)
I want Jesus to walk with me.
(walk with me)
All along my pilgrim journey,
I want Jesus to walk with me.
(walk with me)

2.
In my trials, Lord walk with me.
(walk with me)
In my trials, Lord walk with me.
(walk with me)
When the shades of life are falling,
I want Jesus to walk with me.
(walk with me)

3.
In my sorrows, Lord walk with me.
(walk with me)
In my sorrows, Lord walk with me.
(walk with me)
When my heart within is aching,
I want Jesus to walk with me.
(walk with me)

```

- |   -  |
-------------|------------|
Title | I Want Jesus to Walk With Me |
Key |  |
Titles | undefined |
First Line | I want Jesus to walk with me. |
Author |
Year |
Composer|  |
Hymnal|  - |
Tune|  |
Metrical pattern | |
# Stanzas |  |
Chorus |  |
Chorus Type |  |
Subjects |  |
Texts |  |
Print Texts |
Scripture Song |  |

repository: GospelSounders/adventhymnals

repo_name: GospelSounders/adventhymnals


text:
# Projects, build with NVIDIA Jetson Nano

# Cases
[N100-v9 case is compatible with both Jetson Nano A02 and B01](https://raspberrypiwiki.com/index.php/N100)

repository: satr/nvidia-jetson-nano

repo_name: satr/nvidia-jetson-nano


text:
# deathsticks

An iOS/android/web app to help people quit smoking.

## Goal

Help people quit smoking. Eventually use app components to build larger goal / activity tracking app.

The Game:
A visualized algorithm to incentivize healthy activity with a point based reward system.

Rules:
- A player in this game presses a button every time they smoke a cigarette.
- However many cigarettes are smoked that first day,
  this becomes the daily 'nadir' (N) of the player: the most amount cigarettes they've smoked in a day, ever (while playing the game).
- The next day, or the next time the player logs in and presses the button,
  the previous daily N is inherited by this new day.
- If a player's daily smoke count becomes greater than N, this new 'nadir' replaces that daily N value.
- Points are given as follows:
  Each day a player will receive a score, from 0 (worst) to 100 (best).
  If a player smokes 0 times in a day, their daily score is 100.
  When a player has smoked enough cigarettes to reach their daily N value (the most cigarettes they have smoked in a day while playing),
    their score is 0. Any additional amout above N is also 0.

Example:
 Lets say on the first day a player smokes 10 cigarettes. They get 0 points, since this is the most they've recorded while playing.
  On the second day, they smoke 15 times. They had a rough day. They again get 0 points.
  On the third day (or fourth or fifth), they smoke 9 times. In this case they get (1 - ( 9 / 15 )) * 100 points, or 40 points,
    since 15 is the most they've recorded while playing on that day.
  Finally, on the last day, they smoke 0 times. They get (1 - (0 / N_max)) * 100, or 100 points,
    where N_max is the most they've ever smoked in a day while playing the game.
  They have won the game 🎉

- Formula:
  Y_d: daily score {0, 100}
  X: amount of cigarettes smoked by a player
  N_d: daily nadir value.

  y_d = (1 - (- x / n_d)) * 100


text:
# Rebilly SDK for PHP

[![Latest Version on Packagist][ico-version]][link-packagist]
[![Software License][ico-license]](LICENSE)
[![GitHub Actions status][ico-github-actions]][link-github]
[![Total Downloads][ico-downloads]][link-downloads]
[![Coverage Status][ico-coveralls]][link-coveralls]

The **Rebilly SDK for PHP** makes it easy for developers to access
[Rebilly REST APIs][link-api-doc] in their PHP code.
You can get started in minutes by installing the SDK through Composer or by downloading
a single zip file from our [latest release](https://github.com/Rebilly/rebilly-php/releases).

## Installation

Using [Composer](http://getcomposer.org/) is the recommended way to install the Rebilly SDK for PHP.
To get started, you need run the Composer commands (assume you're in the project's root directory).

- Install the latest stable version of the SDK:

```bash
composer require rebilly/client-php
```

_You can find out more on how to install Composer, configure autoloading,
and other best-practices for defining dependencies at [getcomposer.org](http://getcomposer.org/)._

## Requirements

* PHP 7.1+.
* CURL (verify peer requires a root certificate authority -- if you have not configured php curl to use one, and your system libs aren't linked to one, you may need to do a [manual configuration](http://stackoverflow.com/questions/17478283/paypal-access-ssl-certificate-unable-to-get-local-issuer-certificate/19149687#19149687) to use the appropriate certificate authority)
* PHPUnit (tests only)

## Quick Examples

Create a Rebilly Client

```php
use Rebilly\Client;

// Instantiate Rebilly client.
$client = new Client([
  'apiKey' => ApiKeyProvider::env(),
  'baseUrl' => Client::SANDBOX_HOST,
]);
```

Create a Customer

```php
$form = new Customer();
$form->setFirstName('Sarah');
$form->setLastName('Connor');

try {
  $customer = $client->customers()->create($form);
} catch (DataValidationException $e) {
  var_dump($e->getErrors());
}
```

### Mock Rebilly Client for Test purposes

If you use Guzzle jump to the 2nd example, for regular usage the example with custom handler is below.

#### Custom handler
```php
use Rebilly\Http\HttpHandler;

MockHandler implements HttpHandler {

    private $responses;

    public function append($response)
    {
        $this->responses[] = $response;
    }

    public function __invoke(Request $request)
    {
        return array_shift($this->responses);
    }
};

$httpHandler = new MockHandler();

new RebillyClient(['httpHandler' => $httpHandler]);

// Here is mocked part
$httpHandler->append($response);
```

#### Guzzle handler
```php
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\Psr7\Response;
use Rebilly\Client as RebillyClient;
use Rebilly\Http\GuzzleAdapter;

$mockHandler = new MockHandler();
$guzzleAdapter = new GuzzleAdapter(
    new Client(
        [
            'handler' => $mockHandler,
        ]
    )
);

new RebillyClient([
    'httpHandler' => $guzzleAdapter
]);

// Here is mocked part
$response = new Response(204);
$mockHandler->append($response);
```

If RebillyClient does several sequenced requests in the code you need to cover,
responses have to be appended in the same order as RebillyClient is called:
```php
// Send several sequenced requests
...
$transaction = $rebillyClient->transactions()->load($id);
$refundedTransaction = $rebillyClient->transactions()->refund($id, $amount);
$transactionWithCustomer = $rebillyClient->transactions()->load($id, ['expand' => 'customer']);
...
```
Tests become:
```php
$response = new Response(200, [], json_encode($transaction));
$responseWithCustomer = new Response(200, [], json_encode($transactionWithCustomer));

/**
 * hint: if you receive an error message 'Cannot create resource by URI "..."' during the tests
 * most probably the created Response misses appropriate "Location" header.
 *
 * Below is an example of mocked POST response `/transactions/{transactionId}/refund` which is not listed in `Rebilly\Entities\Schema`
 * because it can be simply mapped by "Location" header from the response.
 * The "Location" header shows Client which Schema to use to create an object out of the response content.
 */

$responseRefund = new GuzzleResponse(201, ['Location' => 'transactions/{transactionId}'], json_encode($transaction));

// Now append them in the same order as it is called in the code
$mockHandler->append($response);
$mockHandler->append($responseRefund);
$mockHandler->append($responseWithCustomer);
```

## Documentation

Read [Rebilly REST APIs documentation][link-api-doc] for more details.

## Tests

```bash
# install required files
$ composer self-update
$ composer install

# run the test
phpunit
```

[ico-version]: https://img.shields.io/packagist/v/rebilly/client-php.svg
[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg
[ico-github-actions]: https://github.com/Rebilly/rebilly-php/workflows/Tests/badge.svg
[ico-downloads]: https://img.shields.io/packagist/dt/rebilly/client-php.svg
[ico-coveralls]: https://coveralls.io/repos/Rebilly/rebilly-php/badge.svg?branch=main&service=github

[link-api-doc]: https://api-reference.rebilly.com/
[link-packagist]: https://packagist.org/packages/rebilly/client-php
[link-github]: https://github.com/Rebilly/rebilly-php
[link-downloads]: https://packagist.org/packages/rebilly/client-php
[link-coveralls]: https://coveralls.io/github/Rebilly/rebilly-php?branch=main

repository: Rebilly/rebilly-php

gha_language: PHP

repo_name: Rebilly/rebilly-php


text:
# Library
## [Animal Shelter](../lib/src/main/java/codechallenges/Queue/AnimalShelter.java)
- Create a class called AnimalShelter which holds only dogs and cats.
- The shelter operates using a first-in, first-out approach.
### Methods:
#### enqueue
- Arguments: animal
- animal can be either a dog or a cat object.
#### dequeue
- Arguments: pref
- pref can be either "dog" or "cat"
- Return: either a dog or a cat, based on preference.
- If pref is not "dog" or "cat" then return null.

## Unit Tests
- Happy Path
- Expected Failure
- Edge Cases

  [Back to Original README](../../README.md)

gha_language: Java


text:
---
title: Code Academy lesson 4
layout: post
author: charlie.hinds
permalink: /code-academy-lesson-4/
source-id: 11LZowzwlZKxxg1qYsTV36Psd6GrKFUYE7sVq54aUqwI
published: true
---

    Title
    Learning python. Further work on PYG python and functions.
    Date
    31/5/17

    Starting point:
    23% of the Python syllabus

    Target for this lesson?
    28% through the Python syllabus

    Did I reach my target?
(add details to "Lesson Review")
    Yes I got up to 29%

    Lesson Review

    How did I learn? What strategies were effective?

     This lesson I worked the same as the last few weeks and with the addition of of using last week's 3 step plan to remind you this is how it goes. Step 1 - Engage my brain, step 2 - Ask a friend and the final step step 3 - is google the exercise. When googled In will have the answer and work out how that answer was derived. This was great and it accelerated my progress greatly and I learnt lots more.

    What limited my learning? Which habits do I need to work on?

     This lesson’s work was easier than last weeks and I worked well with nothing in my way so I will work the same as this lesson. Meaning that there was little that limited my learning and next lesson I won’t have to change my working pattern.

    What will I change for next time? How will I improve my learning?

    For the next lesson I don't plan on changing anything as I was fast and efficient so next lesson I will only change my learning by accident and won't have planned it.


text:
# Samurai
Samurai is an analysis tool for Java thread dumps / GC logs.

[#samuraiApp](https://twitter.com/search?q=%23samuraiApp&src=typed_query&f=live)

## What does it offer?
- Tail log files

Just drag and drop files you want to tail.

![Samurai](images/tailLogs.png)

- Take thread dumps of local processes

From File > Local Processes

![Samurai](images/localThreadDump.png)

- Visualize thread dumps

![Samurai](images/threadDumpAnalysis.png)

- Visualize GC logs

![Samurai](images/gclogs.png)

repository: mhatano/samurai

repo_name: mhatano/samurai


text:
# chef-serverdensity

This cookbook provides an easy way to install the [Server Density agent](https://github.com/serverdensity/sd-agent/) and manage server specific alerts.

## Requirements

### Cookbooks

This cookbook has dependencies on the following cookbooks:

 * [apt](https://github.com/opscode-cookbooks/apt)
 * [yum::epel](https://github.com/opscode-cookbooks/yum)

### Platforms:

 * Ubuntu
 * Debian
 * RHEL
 * CentOS
 * Fedora

## Usage

### Basic

  1. Include `recipe[serverdensity::alerts]` in a run list

  2. Then:
    * Override the `node['serverdensity']['agent_key']` attribute on a [higher level](http://wiki.opscode.com/display/chef/Attributes#Attributes-AttributesPrecedence). *recommended*
    * **or** use the API to query for devices matching the node's hostname or create a new one if not found, by setting the [config options](#optional-api-config).

### Advanced (recommended)

  1. Add `serverdensity` as a dependency to another cookbook

  2. Use `include_recipe 'serverdensity'` to install `sd-agent`

  3. Call the LWRP as described [below](#lwrp) to dynamically configure `sd-agent`

  4. Call the `serverdensity_plugin` [LWRP](#serverdensity_plugin) to configure plugins

  5. Call the `serverdensity_alert` [LWRP](#serverdensity_alert) to configure custom alerts

## Attributes

### Basic Config

 * `node['serverdensity']['account']` **required**
   Your Server Density subdomain, i.e. `companyname.serverdensity.io`
 * `node['serverdensity']['agent_key']`
   Your Server Density agent key (don't set this if you want to use the API to handle querying nodes/creating nodes)
 * `node['serverdensity']['enabled']`
   Should `sd-agent` be running, *default* `true`

### Optional API Config

If you don't set `agent_key` then set these parameters and new servers will be automatically created in your account.

*If your account URL ends in .com you are using v1*

 * `node['serverdensity']['username']`
   Username for authenticating with the v1 API (if `agent_key` isn't set)
 * `node['serverdensity']['password']`
   Password for authenticating with the v1 API (if `agent_key` isn't set)

*If your account URL ends in .io you are using v2*

 * `node['serverdensity']['token']`
    Your API token from Preferences > Security in Server Density.

### Optional Advanced Config

 * `node['serverdensity']['sd_url']`
   By default this will be "https://#{node.serverdensity.account}", avoid setting manually where possible.

 * `node['serverdensity']['device_group']`
    Sets the group for the device to be created in, to inherit alerts automatically.

 * `node['serverdensity']['apache_status_url']`
    URL to get the Apache2 status page from (e.g. `mod_status`), disabled if not set
 * `node['serverdensity']['apache_status_user']`
    Username to authenticate to the Apache2 status page, required if `apache_status_url` is set
 * `node['serverdensity']['apache_status_pass']`
    Password to authenticate to the Apache2 status page, required if `apache_status_url` is set

 * `node['serverdensity']['mongodb_server']`
    Server to get MongoDB status monitoring from, this takes a full [MongoDB connection URI](http://docs.mongodb.org/manual/reference/connection-string/) so you can set username/password etc. details here if needed, disabled if not set
 * `node['serverdensity']['mongodb_dbstats']`
    Enables MongoDB stats if `true` and `mongodb_server` is set, *default*: `false`
 * `node['serverdensity']['mongodb_replset']`
    Enables MongoDB replset stats if `true` and `mongodb_server` is set, *default*: `false`

 * `node['serverdensity']['mysql_server']`
    Server to get MySQL status monitoring from, disabled if not set
 * `node['serverdensity']['mysql_user']`
    Username to authenticate to MySQL, required if `mysql_server` is set
 * `node['serverdensity']['mysql_pass']`
    Password to authenticate to MySQL, required if `mysql_server` is set

 * `node['serverdensity']['nginx_status_url']`
    URL to get th Nginx status page from, disabled if not set

 * `node['serverdensity']['rabbitmq_status_url']`
    URL to get the RabbitMQ status from via [HTTP management API](http://www.rabbitmq.com/management.html), disabled if not set
 * `node['serverdensity']['rabbitmq_user']`
    Username to authenticate to the RabbitMQ management API, required if `rabbitmq_status_url` is set
 * `node['serverdensity']['rabbitmq_pass']`
    Password to authenticate to the RabbitMQ management API, required if `rabbitmq_status_url` is set

 * `node['serverdensity']['tmp_directory']`
    Override where the agent stores temporary files, system default tmp will be used if not set
 * `node['serverdensity']['pidfile_directory']`
    Override where the agent stores it's PID file, temp dir (above or system default) is used if not set

 * `node['serverdensity']['logging_level']`
    Set the logging level for the agent

 * `node['serverdensity']['alerts']`
    This should be an array of hashes, each of which defines an alert, keys should match those exposed by the [alert LWRP](#serverdensity_alert) and will be created by the alerts recipe.

 * `node['serverdensity']['plugin_dir']`
    Sets the directory the agent looks for plugins, if left blank it is ignored
 * `node['serverdensity']['plugin_options']` **deprecated**
    _Use the [plugin LWRP](#serverdensity_plugin) where possible, this exists for legacy reasons only._
    A hash of optional named plugin options if you have agent plugins you want to configure, simple key-values will be added to the `[Main]` section of the config while sub-hashes will be generated into sections e.g. `{'Beanstalk'=>{'host'=>'localhost'}}` becomes:

```ini
[Beanstalk]
host = localhost
```

## Recipes

### default

Installs the sd-agent, ready for the LWRP based setup.

### alerts

Configures sd-agent from attributes rather than LWRPs, and creates attribute based alerts defined in the `['serverdensity']['alerts']` hash. Here is an example of an alert (for API v1):

```rb
node['serverdensity']['alerts']['high-load'] = {
  'metadata' => {
    :userId => ['group'],
    :notificationType => ['email'],
    :checkType => 'loadAvrg',
    :comparison => :>,
    :triggerThreshold => 3,
    :notificationFixed => true,
    :notificationDelay => 5,
    :notificationFrequencyOnce => true
  }
}
```

## LWRP

### serverdensity

#### Actions

  - `clear`
    remove all alerts from device
  - `configure`
    write agent config, get token (see below)
  - `disable`
    stop agent if running
  - `enable`
    start agent if not running
  - `setup`
    initialize API for future calls
  - `sync`
    synchronize device metadata
  - `update` **(default)**
    setup api, either configure and enable or disable agent, sync metadata if API is available

#### Getting Device Token

The configure action of this LWRP facilitates the dynamic configuration the `sd-agent`. The `agent_key` for the device can be acquired by various methods, in order attempts are made to:

  1. use the `agent_key` passed into LWRP
  2. use `agent_key` defined in attributes
  3. read the `agent_key` from `/etc/sd-agent-key` on the server
  4. extract `agent_key` from EC2's internal metadata API
  5. find the device in Server Density and request the `agent_key`
  6. create the device in Server Density and request the `agent_key`

Which of these steps take place depends on the various parameters passed in (see below), and when the `agent_key` is found. As soon as it is acquired no further steps are run.

##### Default

The default recipe will use steps **2-4** to find an `agent_key`

##### Manual

```rb
# step 1 only
serverdensity node.name do
  agent_key '00000000000000000000000000000000'
end
```

##### API v1

```rb
# steps 2-6
serverdensity node.name do
  username 'foo'
  password 'bar'
end
```

##### API v2
```rb
# steps 2-6
serverdensity node.name do
  token '00000000000000000000000000000000'
end
```

#### Other settings

##### Device

By default, step **5** will use the hostname of the device to match against those stored in Server Density, however occasionally it makes more sense to match on something else, for example when using EC2:

```rb
# v2 only (v1 only supports name and hostname keys)
serverdensity node.name do
  token '00000000000000000000000000000000'
  device :providerId => node.ec2.instance_id
end
```

##### Metadata

The LWRP also supports writing metadata (via the sync action) to devices during creation via the API. Updating metadata is also supported by API v2.

```rb
serverdensity node.name do
  token '00000000000000000000000000000000'
  metadata :group => 'chef-lwrp'
end
```

##### Settings

Settings is a hash used to override configuration options set in the attributes before the agent config file is written. Take a look at [this template](/templates/default/agent.cfg.erb) to see which settings can be defined.

### serverdensity\_alert

This is used to create alerts for your newly minted device, it currently just acts as a wrapper for API calls and as such, v1 and v2 usage is significantly different, the hope is to give them a shared DSL in the future.

**This LWRP requires that API credentials (v1 or v2) have been provided, if they have not, it will throw an error.**

#### API v1

```rb
# create v1 alert (https://github.com/serverdensity/sd-api-docs/blob/master/sections/alerts.md#add)
serverdensity_alert 'high-cpu' do
  metadata(
    :userId => ['group'],
    :notificationType => ['email'],
    :checkType => 'loadAvrg',
    :comparison => :>,
    :triggerThreshold => 3,
    :notificationFixed => true,
    :notificationDelay => 5,
    :notificationFrequencyOnce => true
  )
end
```

#### API v2

```rb
# create v2 alert
serverdensity_alert 'high-cpu' do
  metadata(
    # params as described here https://apidocs.serverdensity.com/Alerts/Alert_Configs/Creating
  )
end
```

### serverdensity\_plugin

This is used to install and configure plugins, it creates a new plugin config file inside `/etc/sd-agent/conf.d` and symlinks the file specified in `path` to the `plugin_dir`. Currently plugins must be placed on the server outside of this LWRP and then referenced (with `path`). A future goal is to allow plugin installation directly via
[plugins.serverdensity.com](https://plugins.serverdensity.com/).

#### API (both versions)

```rb
# install Supervisord plugin, configure it, and restart the sd-agent
serverdensity_plugin 'Supervisord' do
  path '/opt/my-company/sd-plugins/Supervisord.py'
  config(
    rpc_url: 'unix:///var/run/supervisor.sock'
  )
  notifies :restart, 'service[sd-agent]'
end
```

The config file will namespace configurations so that they do not clash between plugins. The example above would produce the following config file:

```ini
[Supervisord]
rpc_url = unix:///var/run/supervisor.sock
```

**IMPORTANT**: Some older plugins may require global settings, if this is the case it is possible to use the `plugin_options` attribute to set these, however it is recommended to upgrade the plugin where possible.

## Notes

As this cookbook depends on a few [other cookbooks](#cookbooks) it's recommended you use a library like [Berkshelf](http://berkshelf.com/), [librarian-chef](https://github.com/applicationsonline/librarian-chef) or [knife-github-cookbooks](https://github.com/websterclay/knife-github-cookbooks) to automatically manage and install them.

## Publishing on the Chef Supermarket

https://supermarket.getchef.com/cookbooks/serverdensity

1. Clone the repo to `~/Desktop/serverdensity`
2. From CWD `~/Desktop` run `knife cookbook site share serverdensity "Monitoring & Trending" --cookbook-path ~/Desktop`

## References

  * [Server Density home page](http://www.serverdensity.com/)
  * [akatz/chef-serverdensity](https://github.com/akatz/chef-serverdensity)
  * [Jonty/chef-serverdensity](https://github.com/Jonty/chef-serverdensity)
  * [serverdensity/chef-serverdensity](https://github.com/serverdensity/chef-serverdensity)

## Authors

  * Original Author: Avrohom Katz<EMAIL_ADDRESS>  * Modified by: Jonty Wareing<EMAIL_ADDRESS>  * Modified by: Server Density<EMAIL_ADDRESS>  * Rewritten by: Mal Graty<EMAIL_ADDRESS>
## License

[MIT](/LICENSE)

repository: OwnLocal/chef-serverdensity

gha_language: Ruby

repo_name: OwnLocal/chef-serverdensity


text:
Mysteries of vernacular:
Robot,
a machine capable of carrying out
a programmable series of actions.
The origin of the word robot
dates back more than a thousand years
to the era of serfdom in central Europe
when servitude was the currency for rent.
In those days,
the Old Church Slavonic word rabota
described the forced labor of the people.
A slight adjustment of spelling,
and rabota became the Czech robota,
which, in addition to defining the toil of the serfs,
was also used figuratively
to describe any kind of hard work or drudgery.
In 1920, Czech writer Karel Capek published
a science fiction play called "R.U.R.",
short for "Rossum's Universal Robots."
The story featured automated machines
with distinctly human features
that, until they revolt,
catered to the whims of the people of Earth.
Capek originally considered
calling these hard-working machines labori
from the Latin word for labor,
but he worried it sounded a bit too scholarly.
He opted, instead, to emphasize their enslaved state
by naming them roboti,
or robot in English.
"R.U.R." was wildly successful,
and when it was translated into English in 1923,
the word robot was enthusiastically embraced.
Though most of today's robots look
quite different than Capek imagined,
they've become just as popular as he predicted.
Unlike in "R.U.R.", though,
our robots haven't risen up against us,
and here's hoping it stays that way!

repository: prewittdavon/TEDVis

repo_name: prewittdavon/TEDVis


text:
# HertzScript

:seedling: This project is in early alpha.

HertzScript (abbreviated "HzScript") is a [Babel](https://babeljs.io/) plugin which takes your regular existing JavaScript source code as input, and transforms it into an interruptable coroutine system with voluntary preemption. This project is part of a larger effort to implement preemptively multitasked Green threads in (and only in) JavaScript, and was initially created as the core executor of the [Hertzfeld Kernel](https://github.com/Floofies/hertzfeld-kernel).

## FAQ

**Q:** *What problem does HertzScript solve?*

**A:** In regular JavaScript, if another function is busy executing just as a `setTimeout` timer reaches it’s scheduled deadline, then that timer will miss the deadline. If you want to have reliable multitasking in a single process, this problem presents a significant roadblock, and reduces the overall multitasking capacity while adding significant jitter to the system.

**Q:** *How does it solve that problem?*

**A:**  By adding preemptive multitasking support to your existing JavaScript source code, automatically transforming all subroutines into interruptible coroutines, and eliminating run-time blocking by giving you the ability to interrupt/preempt/pause any JavaScript function's execution at nearly any point in the control flow. Preparation of the input source code is not neccesary, so you can continue to write regular JavaScript without changing anything.

**Q:** *Why would I need this?*

**A:** HzScript allows developers to reliably multitask on a single thread without manually implementing it, so you can easily write multiple JavaScript programs and execute them in the same multitasking environment. If you're already manually writing cooperatively multitasked source code, and/or need reliable single-process multitasking, HzScript could take over this responsibility for you. If you're implementing [Green threads](https://en.wikipedia.org/wiki/Green_threads), then the HzScript dispatcher could serve as an executor for each thread.

## High-Level Synopsis

HzScript consists of a [Babel](https://babeljs.io/) transformation plugin utilizing the visitor pattern, and a coroutine dispatcher with which to run the resulting source code. The source code HzScript produces can be a fully portable, platform-agnostic JavaScript module, which transparently integrates with existing software.

Normally, coroutines are reserved for cooperative multitasking, but HzScript implements a special type named voluntary preemptive multitasking. In regular cooperative-style programmers must declare points at which programs will yield, and HzScript extends this concept by automating it, transforming every function call into a voluntary preemption point. Function calls are re-interpreted as yielded kernelized instructions. In plain english, HzScript transforms JavaScript functions into instruction streams ("function dispensers") which yield functions instead of invoking them. To facilitate such a transformation while preserving normal JavaScript execution, a coroutine dispatcher which implements the instruction specification must be used to run the compiled source code.

The theory of operation behind this system is such that the coroutine dispatcher need not be complex. A simple stack machine is sufficient to interpret the instruction set, which consists of function invocation, returns, yields, and throws. The instruction set corresponds with stack operations which push and pop the coroutines from a simple Array-based virtual stack, taking most of the responsibilities of stack management away from userland source code. Supplied with a time-slice quantum in nanoseconds, the coroutine dispatcher will attempt to return at the end of that specified duration.

While the dispatcher does not re-implement the the invocation operator, it does change how the "real" stack is stored in a JavaScript runtime, limiting the stack to a set size. The stack will generally consist of the coroutine dispatcher and any other parent callers from user code, with the currently executing coroutine residing at the end of the stack; the stack does not grow past this point except during function calls which were initiated by many of JavaScript's standard operators which are not the invocation operator. Efforts are also underway to implement forced preemption by targeting such operators, in which each atomic operation in an expression is transformed into an individual coroutine.

## Example Use Case - Preventing Run-Time Blocking

Due to the single-threaded nature of JavaScript, only one function may be run at any time.

All JavaScript is executed in a single synchronous thread, so there are no guarantees that the deadlines you set will ever be met, making the reliability of event loop multitasking uncertain. This means that if a function is busy executing as a `setTimeout` timer reaches it’s scheduled deadline, that timer will miss the deadline. At best, sometimes your callbacks will run later than you expect; at worst, your entire process will hang. The following JavaScript source code is a good example of how this delay occurs.

In the below example, we schedule two `setTimeout` callbacks. `block` is scheduled to run as soon as possible and simulates a long-running callback that runs for 1000ms, while the other callback is scheduled to run after 500ms.

```JavaScript
// Blocks for 1000ms
function block() {
	var start = performance.now();
	spin: while ((performance.now() - start) < 1000);
	console.log("Ran blocker for " + (performance.now() - start) + "ms.");
}

// Schedule blocker to run ASAP
setTimeout(block, 0);

// Schedule timer to run in 500ms
var start = performance.now();
setTimeout(function () {
	console.log("Took " + (performance.now() - start) + "ms to run timer.")
}, 500);
```

As an aside, setting the setTimeout delay to 0 does not cause the callback to execute right there and then; instead, the event loop must wait until the currently executing function returns, which is the exact same behavior that causes the aforementioned problem.

After running the above source code in either NodeJS or a web browser, the console may then contain something like the below:

```
Ran blocker for 1000ms.
Took 1000ms to run timer.
```

In web browsers, you may also see a `[Violation]` log notifying you of the long-running callback:

```
[Violation] 'setTimeout' handler took 1000ms
```

These numbers indicate that the second callback was delayed by 500ms because it was forced to wait until the first callback had completed. The second callback failed to run at the scheduled deadline of 500m and ran at 1000ms instead, right after the first callback returned.

### The Solution

HzScript solves this problem by making it possible to interrupt functions and perform context switching, all from within JavaScript.

If we run `block` after it has been compiled with HzScript, we can then execute it in chunks and run other code in between every interruption of it. We can then advance the Generator in recursive `setTimeout` callbacks like in the below example:

```JavaScript
// Our blocker source code:
const blockSource = `
	var start = performance.now();
	spin: while ((performance.now() - start) < 1000);
	console.log("Ran blocker for " + (performance.now() - start) + "ms.");
`;
// Compile into a live Generator function with HzScript:
const blocker = HzScript.hotCompile(block)();

// Runs the blocker, and schedules itself to run in the async event queue ASAP:
function runBlocker () {
	if (!blocker.next().done) {
		setTimeout(runBlocker, 0);
	}
}
// Schedule the blocker to run in the async event queue ASAP:
setTimeout(runBlocker, 0);
// Schedule timer to run in 500ms
var start = performance.now();
setTimeout(function () {
	console.log("Took " + (performance.now() - start) + "ms to run timer.")
}, 500);
```

In the above example, each time we call blocker.next() a single iteration of the `spin` loop is executed and control is yielded, at which point the event loop is free to execute other callbacks when they reach their deadlines.

The above code would then log something like this, most likely with a very small margin of error:

```
Took 500ms to run timer.
Ran blocker for 1000ms.
```

repository: trgwii/HertzScript

repo_name: trgwii/HertzScript