text:
---
title: Manual Server Installation
---

ATTENTION! Please post any questions to: [<https://groups.google.com/forum/?hl=en>\#!forum/sana-users Sana users group.]

We recommend using [Debian Packages](/Installation "wikilink") to install the server software. If you need to perform a manual installation, please use the steps outlined below.

Setup Linux Environment
-----------------------

The full server platform requires a linux environment. Ubuntu is the only distribution officially supported but others should work as well for those more comfortable working in with them.

;

Dedicated physical host or virtual machine running Ubuntu Linux 14.04 LTS. For running on a VM, any virtual machine manager capable of running Ubuntu, such as VMWare or VirtualBox should work. Please consult documentation for your VM manager if you have any questions about installation.

;

### OS and Virtual Machine Manager References

#### Ubuntu

1.  [Ubuntu Installation](https://help.ubuntu.com/14.04/installation-guide/index.html)

#### VMWare

-   [VMWare Workstation Installation Guide](http://pubs.vmware.com/guestnotes/wwhelp/wwhimpl/js/html/wwhelp.htm)
-   [VM Tools Installation](https://help.ubuntu.com/community/VMware/Workstation)

#### VirtualBox

-   [Documentation](https://www.virtualbox.org/wiki/Documentation)
-   [Download](https://www.virtualbox.org/wiki/Downloads)

#### Required Ubuntu Packages

The simplest method for installing the required software is to do the following on the Ubuntu OS

##### General Server Software

Open Terminal window and execute these commands, in bold, as root user. This will install the Apache and Tomcat web servers and MySQL database.

1.  **sudo tasksel**
    1.  Select LAMP Server and Tomcat
    2.  Enter root MySQL password when prompted.

**Note 1:** Using the **tasksel** is not necessary if installing Ubuntu Server. **Note 2:** Using the **tasksel** command installs a number of dependencies which are required by the LAMP and Tomcat selection. If you want to manually install everything using **apt-get** and skip using the **tasksel** entirely, you will need to consult the the Apache, MySQL, and Tomcat packages for a full list of their requirements-see this link for details[Ubuntu Package Search](http://packages.ubuntu.com/).

##### Additional Server Software Requirements(Using **apt-get**)

1.  **sudo apt-get install libapache2-mod-wsgi**
2.  **sudo apt-get install libapache2-mod-jk**
3.  **sudo apt-get install python-django**
4.  **sudo apt-get install python-django-piston**
5.  **sudo apt-get install python-mysqldb**
6.  **sudo apt-get install python-cjson**
7.  **sudo apt-get install python-libxml2**
8.  **sudo apt-get install python-lxml**
9.  **sudo apt-get install sqlite3**

##### Setup and Configure Tomcat

1.  Edit Tomcat Configuration files
    1.  **sudo nano /etc/tomcat6/tomcat-users.xml**
        (Or use your favorite editor to make the file appear as shown below. Make sure to uncomment this part of the file.)
        <tomcat-users>
            <role rolename="admin"/>
            <role rolename="manager"/>
            <role rolename="tomcat"/>
            <user username="test" password="test" roles = "admin,manager,tomcat"/>
        </tomcat-users>
    2.  **sudo nano /etc/default/tomcat6**
        (Turn off tomcat security flag in "/etc/init.d/tomcat6" file. Uncomment the following line and set value to no.)
        TOMCAT6_SECURITY=no
    3.  **sudo nano /etc/tomcat6/policy.d/03catalina.policy**
        (Add the following lines to the policy file.)
        grant codeBase "file:\${catalina.home}/openmrs/-" {
            permission java.security.AllPermission;
        };
    4.  **sudo mkdir /usr/share/tomcat6/.OpenMRS**
        (Fix application data directory)
    5.  **sudo chown -R tomcat6:tomcat6 /usr/share/tomcat6/.OpenMRS**
        (Note the space between root and /usr)
    6.  **sudo service tomcat6 restart**
        Check that it works by going to <http://localhost:8080/>
        The webpage should say “It works!”

2.  Click on the link to '''manager webapp” or go to <http://localhost:8080/manager/html>
    Username: test
    Password: test (from tomcat users xml file)

OpenMRS
-------

### Download and install OpenMRS Web app

1.  Download OpenMRS Version 1.9.7 WAR file from website
    <http://openmrs.org/download>
2.  Open the Tomcat manager page listed below and scroll down to “WAR file to deploy.”
    <http://localhost:8080/manager/html>
3.  Browse and find the WAR file you just downloaded and deploy it. “/openmrs” should now show up in the list of applications.

### Initial Setup Wizard for OpenMRS

1.  Click the “/openmrs” link to start the OpenMRS setup wizard.
2.  For Do you have an OpenMRS DB installed, select “No” call it “openmrs” and set the password to be the MySQL root password you created earlier.
3.  For page 2, select "Yes" you want the demo data loaded in. Then select “Yes” and enter the username “root” and the MySQL root password.
4.  Use the default values and continue.
5.  When selecting a password for the login page of OpenMRS, the password has to contain uppercase characters and a number.
6.  Use the default values and continue.
7.  Click Finish. Let it install which will take about 10 minutes and then it will automatically redirect you to the OpenMRS login page. (Note: even if the browser page says Done or the page says Error - get Service Context is null, it should be fine. If you wait a couple more minutes, it should still continue making progress.)
8.  Troubleshooting: If the initial setup wizard doesn't work, you might have to start again. Check whether the openmrs database is already created:
    1.  mysql -u root -p
    2.  show databases;
    3.  If openmrs shows up, then drop database by doing the following command
    4.  drop database openmrs;
    5.  Go back to initial setup page and start again

9.  Login to OpenMRS with the admin user and password created above. Leave this window open for upcoming steps.
10. If this doesn't work the first time, try again, but this time on page 1, say "Yes" the database called "openmrs" is already created and go through and try again making sure that you enter "root" and the root password for MySQL.

### Load in Required Sana modules for OpenMRS

1.  Download Modules
    1.  [Sana Module](http://demo.sana.csail.mit.edu/downloads/openmrs/sana.encounterqueue-module-current.omod)

2.  Install The modules
    1.  Login to OpenMRS \> Administration \> Manage Modules \> Click on "Add or Upgrade"
    2.  Install from Module Repository WebServices.REST module
    3.  Install from Module Repository HTMLFormEntry module
    4.  Install from Module Repository LogManager module
    5.  **Add Module** select "Choose File" and select the .omod file you just downloaded.

### Additional OpenMRS Configuration for Sana

Execute all the steps to [setup OpenMRS for Sana](/OpenMRS_Configuration "wikilink") (creating new concepts, setting up roles and privileges, setting global properties, etc..).

#### Additional OpenMRS References

Installing An OpenMRS Server on Linux <http://openmrs.org/wiki/Installing_An_OpenMRS_Server_On_Linux>

OpenMRS Step-by-Step Installation for Implementers <http://openmrs.org/wiki/Step-by-Step_Installation_for_Implementers>

Mobile Dispatch Server (MDS)
----------------------------

The procedure from the Sana client application on the Android phone is put into JSON format and then sent to the Mobile Dispatch server (MDS) in chunks. The MDS then waits for all the chunks to arrive and assembles them together into a patient encounter with the patient ID, description of the visit, and etc.. Then the MDS logs into OpenMRS and creates a new patient if the patient ID doesn't already exist in the medical record system. Then the MDS will create a new encounter (patient visit) for that patient ID, uploading the images/audio/video files as complex observations and the each text question/answer pair as an observation.

### Download and Install Current MDS Release

1.  Download the [MDS current release](http://demo.sana.csail.mit.edu/downloads/mds-current.zip)

Execute the following in a terminal window:

1.  Extract the archive **unzip mds-current.zip**
2.  Follow the installation instructions in either the INSTALL or UPGRADE files.

### Create MySQL database for MDS

From a command prompt:

1.  **mysql –u root –p** (enter root password when prompted)
2.  **create database mds;**
3.  **create user 'mds'@'localhost' identified by '<enter mds password>';**
4.   TO 'mds'@'localhost';**

##### Configure MDS (Update settings file)

1.  cd /opt/sana
2.  sudo mv settings.py.tmpl settings.py
3.  sudo nano settings.py
    Example settings:
    1.  DATABASE_ENGINE = 'mysql'
    2.  DATABASE_NAME = 'mds'
    3.  DATABASE_USER = 'mds'
    4.  DATABASE_PASSWORD = '<put in your mds password from above>'
    5.  DATABASE_HOST = ''
    6.  DATABASE_PORT = ''
    7.  MEDIA_URL = '/mds/media'
    8.  MEDIA_ROOT = '/opt/sana/media'
    9.  ADMIN_MEDIA_PREFIX = '/mds/media/admin'
    10. OPENMRS_SERVER_URL='<http://><IPaddress>:8080/openmrs/'
         (Remember the trailing slash!)

        TEMPLATE_DIRS = (
        '/opt/sana/templates',
        )

4.  **./manage.py syncdb** Will create the mds databasetables
5.  You may create a login account (for accessing the Django admin interface)

##### Configure Apache to serve the MDS

1.  sudo nano /etc/apache2/sites-enabled/000-default
    1.  Add a handler for the /mds location. Insert this <Location> block somewhere inside the <VirtualHost> block.

        <Location "/mds">

        SetHandler python-program

        PythonHandler django.core.handlers.modpython

        PythonDebug On

        SetEnv DJANGO_SETTINGS_MODULE sana.settings

        PythonPath "['/opt'] + sys.path"

        PythonInterpreter mds

        PythonOption django.root /mds

        </Location>

        <Location "/mds/media">

        SetHandler none

        </Location>

2.  sudo ln -s /opt/sana /var/www/
3.  sudo ln -s /usr/local/lib/python2.6/dist-packages/django/contrib/admin/media /opt/sana/media/admin
     (or sudo ln -s /usr/lib/pymodules/python2.6/django/contrib/admin/media/ /opt/sana/media/admin)
     If you're using Python 2.5, replace python2.6 in this path with python2.5
4.  sudo apache2ctl restart

You should now be able to verify that the MDS is running on Apache by navigating with a browser to: <http://localhost/mds/> You should see the same 'Sanamobile MDS Online' message that was shown before in the Development Server step, except now the MDS is being served by Apache, which is more suitable for production purposes.

##### Make sure OpenMRS on public IP address

1.  sudo nano /etc/tomcat6/server.xml
2.  Add address tag with the IP address
    1.  <Connector port="8080" protocol="HTTP/1.1"
 address="<IP_ADDRESS>"
         connectionTimeout="20000"
         redirectPort="8443" /\>

3.  sudo /etc/init.d/tomcat6 restart

##### Test request to verify MDS / OpenMRS Connection

To verify that the MDS and OpenMRS are successfully connected, you can use this test request to have the MDS connect to the OpenMRS and verify the credentials provided. Make sure to replace <your OpenMRS admin password> with the password for the OpenMRS admin account. The MDS should respond with a JSON file -- if you open it up, it should have information about whether the request succeeded.

1.  You can check that it works by <http://><ipaddress>/mds/json/validate/credentials/?username=admin&password=<your OpenMRS admin password>

##### Setup SMS Messaging with the MDS

1.  Make sure you have an SMS gateway hooked up to your MDS. You can get a clickatell account for sending SMS messages by applying here: <http://www.clickatell.com/login.php>
    1.  Sign up for a Clickatell Central API account
    2.  Buy SMS credits
    3.  Setup a "moca mds" HTTP connection, which should give you a numerical API ID, which you need to enter below in the settings.py file

2.  In the MDS settings.py file, you'll need to fill in the appropriate values here according to your registered account:
    1.  CLICKATELL_URI = "<http://api.clickatell.com/http/sendmsg>?%s"
    2.  CLICKATELL_USER = ''
    3.  CLICKATELL_PASSWORD = ''
    4.  CLICKATELL_API = ''

3.  Make sure you have a SIM card in your phone, and in the Moca phone app settings page, the Phone Number field should be the phone number of the phone you're using. When you upload a case to Moca, it should show up in the Queue with contact \# being the phone number of the phone.
    1.  Make sure the phone number is entered properly with the country code found here: <http://www.clickatell.com/products/test_gateway.php>
    2.  Example, a US phone number that is<PHONE_NUMBER> would be entered in the phone as<PHONE_NUMBER>8 because the US country code is 1.


text:
# Amazing Gatsby website

Repository containing code for my personal website at https://daviddonahue.netlify.com

## How was it made?

This website was made using a combination of HTML, CSS, and React, powered by the Gatsby platform and hosted on netlify.com.

Most presentation elements of the website were made using HTML with CSS elements for styling. React was used to form the main shell of the program, and to implement social media icons and special features. Overall, the code is not well organized as I was learning react for the first time. Check it out!

license: MIT

branch_name: refs/heads/master

extension: md

gha_language: JavaScript

gha_license_id: MIT

license_type: permissive


text:
+++
title = "PHP Development"
weight = 20
app_library = "default"
app_category = "Groups"
app_typ = "meta"
app_ns = "Bench.Group"
app_id = "Bench.Group.PHPDevelopment"
app_version = "latest"
app_categories = ["Groups"]
app_libraries = ["default"]
app_types = ["meta"]
+++

**ID:** `Bench.Group.PHPDevelopment`
**Version:** latest
<!--more-->

[Back to all apps](/apps/)

## Source

* Library: [`default`](/app_libraries/default)
* Category: [Groups](/app_categories/groups)
* Order Index: 20

## Properties

* Namespace: Bench.Group
* Name: PHPDevelopment
* Typ: `meta`
* Dependencies: [PHP 7](/apps/Bench.PHP7), [Apache](/apps/Bench.Apache), [MySQL](/apps/Bench.MySQL), [MySQL Workbench](/apps/Bench.MySQLWB), [Eclipse for PHP](/apps/Bench.EclipsePHP)


text:
# Utterances

To use Utterances you need to have a public repository on Github with [Utterances](https://github.com/apps/utterances) installed, then you need to add the script with the desired settings.

For implementations with ReactJS this Issue can help: [Utterances with ReactJS](https://github.com/utterance/utterances/issues/161)

repository: yuribmontez/spacetraveling

repo_name: yuribmontez/spacetraveling


text:
# AKAN NAMES
#### This is a web app that outputs user's Akan names, 15-06-2021
#### By **Johnstone Otenyo Omundi**
## Description
This web application takes a user's birthday and calculates the day of the week they were born and then depending on their gender outputs their Akan Name.
Live link: https://o-tenyo.github.io/user-story/
## Setup/Installation Requirements
* Use any text editor such as atom or vs code
* Preferred browser is chrome
* No need to install an external server yet
* No need to set up any databases
## Known Bugs
There aren't any bugs yet, as long as you use the most compatible browsers such as chrome or mozilla
## Technologies Used
* HTML - structural build
* CSS -used for styling
* JavaScript programming language

## Support and contact details
Contact<EMAIL_ADDRESS>### License
Copyright (c) 2021 **Johnstone Omundi**

repository: o-tenyo/user-story

repo_name: o-tenyo/user-story


text:
# Security
We take the security, integrity, availability of our services, and the privacy of our users seriously. We appreciate all security concerns brought forth and are constantly striving to keep on top of the latest threats. Being proactive rather than reactive to emerging security issues is a fundamental belief at Delta Exchange. Every day new security issues and attack vectors are created. Delta Exchange strives to keep abreast of the latest state-of-the-art security developments by working with independent security researchers. We appreciate the community's efforts in creating a more secure world.

## Targets In scope
- https://*.delta.exchange

Any domain/property of Delta Exchange Network not listed in the targets section is out of scope. This includes any/all subdomains not listed above.

## How to access
- You will access the Delta Exchange service using test accounts and unauthenticated guests.
- Please create a Delta Exchange test account on your own using your test email address. Your email must contain keyword 'test' for example<EMAIL_ADDRESS>
- All emails will go to the email address associated with your account. You will need to activate your account by confirming receipt of the activation email.
- NOTE: Once a vulnerability is found please file a submission immediately. Our security team will investigate and assess the impact.

## Reward range
Focus Areas

- User Data / User information Leaks
- Injection attacks (Server/Client side)
- RCE(Remote Code Execution)
- Authentication bypass/validation (Client/Server side)
- Privilege escalation (Vertical/Horizontal)

| Technical  | Severity  | Reward |
|---|---|---|
| P1  | Critical  | Decided by internal team, can be from ($10-$1000)  |
| P2  | Severe  | Decided by internal team, can be from ($10-$1000)  |
| P3  | Moderate  |  $10 - $100 |

## Rules of engagement
We are interested in hearing about security issues in Production/Dev Delta Exchange environments.
There are some things we explicitly ask you not to do

- Do not run automated scans without checking with us first. They are often very noisy.(If running any automated testing tools, be sure to keep well under 75-100 requests per second - otherwise you're likely to get locked out.)
- Do not test the physical security of Delta Exchange offices, employees, equipment, etc.
- Do not run Full fledged exploits which can cause application crashes and affect integrity of our active services. (If you believe you have a exploit that need serious fixes please email us, and we will provide you with said instance for said service.)
- Do not test using social engineering techniques (phishing, vishing, etc.)
- Do not test against any type of customer account without explicit permission from our side.
- Do not access, Destroy or otherwise negatively impact any residential or business customers, or customer data in any way.
- Do not perform DoS or DDoS attacks (Application level, Network Level DOS / DDOS / port flooding attacks are strictly not appreciated as this can cause delay in delivery of our services to our users we suggest you to not to use such methodologies).
- Do not engage In any way attack our end users, or in the trade of stolen user credentials.
- Interacting with real customers or real customer accounts is forbidden.

## Rules of reporting
We take our Internal process and workflow seriously, We have a dedicated security team working and testing round the clock, so we would like you to send your reports to only<EMAIL_ADDRESS>and follow below said rules or not following will void you from our bug bounty benefits, Also we would like you to encrypt emails sent to us with a PGP key provided below if the Vulnerability is Severe or Critical.

- We recommend you to use emails which contain test as a keyword in the email address for example<EMAIL_ADDRESS>- For testing and reporting so that we can identify your activity on our environments, also whitelist for IDS/FDS blocks)
- Do not CC or tag other staff while reporting.
- Do not callout on social media or make blog posts to report or without reporting (this can lead to legal actions to be taken against you.)
- Do not discuss this with any, but only Delta Exchange technical staff.
- Do not send us external-links/executable/scripts in report if possible attach a text file or pdf. Without zipp'ing or rar'ing it.
- Screenshots are accepted if only in PNG and JIF formats for internal security reasons.
- POC Videos are accepted if only in MP4,AVI, WEBM, MOV formats for internal security reasons.
- Any or All reports must only reach<EMAIL_ADDRESS>

## Recommended Reporting format
Summary

Help us get an idea of what this vulnerability is about.

(eg. "hey i have found a xss on your server")

Target

Select the vulnerable target Domain name / Subdomain name

(eg. "so and so on https://example.delta.exchange")

Vulnerability details

What is the Bug/Vulnerability. And URL / Location of vulnerability .

(eg. because of unfiltered characters the url [/search.php?q=<here>] path /search.php on q parameter)

Description of Technical severity

Help us understand the bug/vulnerability technical details
Describe the vulnerability and its impact.

(eg. client side executes the javascript which is rendering through /search.php?q=somescript)

Recreation

Provide a proof of concept or replication steps.

(eg. steps to be used by our team in order to recreate the attack scenario)

Additional information

Provide us with Request and Response dump / trace dump / HTTP request

Attachments (recommended)

Attach proof-of-concept scripts, screenshots, screen recordings, etc.

## Ineligible issues
These issues Will be closed as out of scope hence not rewardable.

- Theoretical vulnerabilities without actual proof of concept
- Open redirects (through headers and parameters) / Lack of security speed bump when leaving the site.
- Internal IP address / version disclosure.
- Email verification deficiencies, expiration of password reset links, and password complexity policies
- Invalid or missing SPF (Sender Policy Framework) records (incomplete or missing SPF/DKIM/DMARC)
- Click jacking/UI redressing with minimal security impact
- Text/code injection without any impact.
- Email or mobile enumeration (E.g. the ability to identify emails via password reset)
- Information disclosure with minimal security impact (E.g. stack traces, path disclosure, directory listings, logs)
- Internally known issues, duplicate issues, or issues which have already been made public
- Rate limiting issues / Tab-nabbing
- Non url Selfless / HTMLi
- Known CVE without proper testing.
- Vulnerabilities only exploitable on out-of-date browsers or platforms
- CSRF issues that don't impact the integrity of an account (e.g. log in or out, contact forms and other publicly accessible forms)
- Vulnerabilities related to auto-fill web forms
- Use of known vulnerable libraries without actual proof of concept
- Lack of security flags in cookies
- Issues related to unsafe SSL/TLS cipher suites or protocol version
- Session expiry / Cookie issues / Content spoofing
- Cache-control related issues
- Missing security headers that do not lead to direct exploitation
- CSRF with negligible security impact (E.g. adding to favorites, adding to cart, subscribing to a non-critical feature)
- Vulnerabilities that require root/jailbreak
- Vulnerabilities that require physical access to a user's device
- Issues that have no security impact (E.g. Failure to load a web page)
- Phishing (E.g. HTTP Basic Authentication Phishing)
- Any activity (like DoS/DDoS) that disrupts our services
- Installation Path Permissions
- Reports from automated tools or scans

Not following any one of the above rule will disqualify you from our bug bounty program.

If any doubts related to your submissions or creative dialogue please feel free to email<EMAIL_ADDRESS>or<EMAIL_ADDRESS>

repository: delta-exchange/slate

gha_license_id: NOASSERTION

repo_name: delta-exchange/slate


text:
GigaStorm Style Guide
==============

The style guide is hosted on the `gh-pages` branch, located at http://gigastorm.github.io/gs-style-guide.

repository: gigastorm/gs-style-guide

repo_name: gigastorm/gs-style-guide


text:
# Dotfiles

Files that start with a dot.

## Installation

### 1. Install Homebrew

```sh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
```

### 2. Bundle Brewfile

```sh
git clone https://github.com/kirillgashkov/dotfiles.git ~/.dotfiles
brew bundle --file ~/.dotfiles/Brewfile
```

### 3. Setup Dotfiles

```sh
cd ~/.dotfiles
sh ./bootstrap.sh
zsh
```

### 4.  Setup apps

#### Built-in

  Finder

  - Visibility
    - Make `~/Library` visible
    - Make hidden files visible
  - Extensions
    - Make extensions visible
    - Suppress warnings when changing extensions
  - Miscellaneous
    - Make new tabs start at `~/`
    - Enable snap to grid

  Safari

  - Show `Develop` menu

#### External

  iTerm

  - Turn on custom folder preferences

  Sublime Text

  - Copy settings to `User/Packages`
  - Install package control
  - Copy to `User` [Russian-English Bilingual](https://github.com/titoBouzout/Dictionaries) dictionary (`.aff` and `.dic`).

  Xcode

  - Add developer account
  - Set ruler at 80 characters
  - Disable source control

  Karabiner

  - Copy complex modifications to config folder
  - Enable Caps Lock to switch languages

### 6. Setup SSH

#### Generating a new SSH key

> [Generating a new SSH key](https://help.github.com/en/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent)

```sh
ssh-keygen -t rsa -b 4096 -C<EMAIL_ADDRESS>```

#### Add SSH key to GitHub account

> [Add SSH key to GitHub account](https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account)

Start with copying the public key.

```sh
pbcopy < ~/.ssh/id_rsa.pub
```

Continue with opening settings of your GitHub account and pasting the key there.

## License

Distributed under the MIT License. See the [LICENSE.md](LICENSE.md) for details.

## Acknowledgments

- [ptb's dotfiles](https://github.com/ptb/mac-setup)
- [kevinSuttle's dotfiles](https://github.com/kevinSuttle/dotfiles)
- [mathiasbynens's dotfiles](https://github.com/mathiasbynens/dotfiles)
- [caarlos0's dotfiles](https://github.com/caarlos0/dotfiles)

repository: kirillgashkov/dotfiles

gha_language: Shell

repo_name: kirillgashkov/dotfiles


text:
# StructuredQueries

*a generic query representation framework for Julia.*

[![Project Status: WIP - Initial development is in progress, but there has not yet been a stable, usable release suitable for the public.](http://www.repostatus.org/badges/latest/wip.svg)](http://www.repostatus.org/#wip) [![Build Status](https://travis-ci.org/davidagold/StructuredQueries.jl.svg?branch=master)](https://travis-ci.org/davidagold/StructuredQueries.jl)
[![StructuredQueries](http://pkg.julialang.org/badges/StructuredQueries_0.5.svg)](http://pkg.julialang.org/?pkg=StructuredQueries)
[![StructuredQueries](http://pkg.julialang.org/badges/StructuredQueries_0.6.svg)](http://pkg.julialang.org/?pkg=StructuredQueries)
[![codecov](https://codecov.io/gh/davidagold/StructuredQueries.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/davidagold/StructuredQueries.jl)

## Installation

StructuredQueries.jl is registered in [METADATA.jl](https://github.com/JuliaLang/METADATA.jl). Install it with

```
julia> Pkg.add("StructuredQueries")
```

This package supports Julia 0.5.

## Objectives

The present package aims to support a querying framework that is

* Generic -- the framework should be able to support multiple backends.

* Modular -- the framework should encourage modularity of collection machinery.

* Extensible -- the framework should be easily extensible to represent (relatively) arbitrary manipulations.

* Ergonomic -- the framework should allow users to express their intentions easily.

## Documentation

... Is currently offline, since I just (as of 11/16/16) redesigned much of this package. Documentation will catch up in December, once this academic quarter is over.


text:
:warning: This repository is no longer mantained consider using [Room](https://developer.android.com/topic/libraries/architecture/room) as an alternative :warning:

![Downloads](https://jitpack.io/v/VictorAlbertos/RxCache/month.svg)

[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-RxCache-green.svg?style=true)](https://android-arsenal.com/details/1/3016)

# RxCache

> [**中文文档**](http://www.jianshu.com/p/b58ef6b0624b)

_For a more reactive approach go [here](https://github.com/VictorAlbertos/ReactiveCache/tree/2.x)_.

The **goal** of this library is simple: **caching your data models like [Picasso](https://github.com/square/picasso) caches your images, with no effort at all.**

Every Android application is a client application, which means it does not make sense to create and maintain a database just for caching data.

Plus, the fact that you have some sort of legendary database for persisting your data does not solves by itself the real challenge: to be able to configure your caching needs in a flexible and simple way.

Inspired by [Retrofit](http://square.github.io/retrofit/) api, **RxCache is a reactive caching library for Android and Java which turns your caching needs into an interface.**

When supplying an **`observable`, `single`, `maybe` or `flowable` (these are the supported Reactive types)** which contains the data provided by an expensive task -probably an http connection, RxCache determines if it is needed
to subscribe to it or instead fetch the data previously cached. This decision is made based on the providers configuration.

```java
Observable<List<Mock>> getMocks(Observable<List<Mock>> oMocks);
```

## Setup

Add the JitPack repository in your build.gradle (top level module):
```gradle
allprojects {
    repositories {
        jcenter()
        maven { url "https://jitpack.io" }
    }
}
```

And add next dependencies in the build.gradle of the module:
```gradle
dependencies {
    compile "com.github.VictorAlbertos.RxCache:runtime:1.8.3-2.x"
    compile "io.reactivex.rxjava2:rxjava:2.1.6"
}
```

Because RxCache uses internally [Jolyglot](https://github.com/VictorAlbertos/Jolyglot) to serialize and deserialize objects, you need to add one of the next dependency to gradle.

```gradle
dependencies {
    // To use Gson
    compile 'com.github.VictorAlbertos.Jolyglot:gson:0.0.4'

    // To use Jackson
    compile 'com.github.VictorAlbertos.Jolyglot:jackson:0.0.4'

    // To use Moshi
    compile 'com.github.VictorAlbertos.Jolyglot:moshi:0.0.4'
}
```

## Usage

Define an `interface` with as much methods as needed to create the caching providers:

```java
interface Providers {

        @ProviderKey("mocks")
        Observable<List<Mock>> getMocks(Observable<List<Mock>> oMocks);

        @ProviderKey("mocks-5-minute-ttl")
        @LifeCache(duration = 5, timeUnit = TimeUnit.MINUTES)
        Observable<List<Mock>> getMocksWith5MinutesLifeTime(Observable<List<Mock>> oMocks);

        @ProviderKey("mocks-evict-provider")
        Observable<List<Mock>> getMocksEvictProvider(Observable<List<Mock>> oMocks, EvictProvider evictProvider);

        @ProviderKey("mocks-paginate")
        Observable<List<Mock>> getMocksPaginate(Observable<List<Mock>> oMocks, DynamicKey page);

        @ProviderKey("mocks-paginate-evict-per-page")
        Observable<List<Mock>> getMocksPaginateEvictingPerPage(Observable<List<Mock>> oMocks, DynamicKey page, EvictDynamicKey evictPage);

        @ProviderKey("mocks-paginate-evict-per-filter")
        Observable<List<Mock>> getMocksPaginateWithFiltersEvictingPerFilter(Observable<List<Mock>> oMocks, DynamicKeyGroup filterPage, EvictDynamicKey evictFilter);
}
```

RxCache exposes `evictAll()` method to evict the entire cache in a row.

RxCache accepts as argument a set of classes to indicate how the provider needs to handle the cached data:

* A Reactive type is the only object required to create a provider. This Reactive type must be equal to the one specified by the returning value of the provider.
* [EvictProvider](https://github.com/VictorAlbertos/RxCache/blob/master/core/src/main/java/io/rx_cache/EvictProvider.java) allows to explicitly evict all the data associated with the provider.
* [@ProviderKey](https://github.com/VictorAlbertos/RxCache/blob/master/core/src/main/java/io/rx_cache/ProviderKey.java) is an annotation for provider methods that is highly recommended to use and proguard users MUST use this annotation, if not used the method names will be used as provider keys (cache keys) and proguard users will quickly run into problems, please see [Proguard](proguard) for detailed information. Using the annotaiton is also useful when not using Proguard as it makes sure you can change your method names without having to write a migration for old cache files.
* [EvictDynamicKey](https://github.com/VictorAlbertos/RxCache/blob/master/core/src/main/java/io/rx_cache/EvictDynamicKey.java) allows to explicitly evict the data of an specific [DynamicKey](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/DynamicKey.java).
* [EvictDynamicKeyGroup](https://github.com/VictorAlbertos/RxCache/blob/master/core/src/main/java/io/rx_cache/EvictDynamicKeyGroup.java) allows to explicitly evict the data of an specific [DynamicKeyGroup](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/DynamicKeyGroup.java).
* [DynamicKey](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/DynamicKey.java) is a wrapper around the key object for those providers which need to handle multiple records, so they need to provide multiple keys, such us endpoints with pagination, ordering or filtering requirements. To evict the data associated with one particular key use `EvictDynamicKey`.
* [DynamicKeyGroup](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/DynamicKeyGroup.java) is a wrapper around the key and the group for those providers which need to handle multiple records grouped, so they need to provide multiple keys organized in groups, such us endpoints with filtering AND pagination requirements. To evict the data associated with the key of one particular group, use `EvictDynamicKeyGroup`.

Supported annotations:

* [@LifeCache](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/LifeCache.java) sets the amount of time before the data would be evicted. If `@LifeCache` is not supplied, the data will be never evicted unless it is required explicitly using [EvictProvider](https://github.com/VictorAlbertos/RxCache/blob/master/core/src/main/java/io/rx_cache/EvictProvider.java), [EvictDynamicKey](https://github.com/VictorAlbertos/RxCache/blob/master/core/src/main/java/io/rx_cache/EvictDynamicKey.java) or [EvictDynamicKeyGroup](https://github.com/VictorAlbertos/RxCache/blob/master/core/src/main/java/io/rx_cache/EvictDynamicKeyGroup.java) .
* [@Actionable](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/Actionable.java) offers an easy way to perform write operations using providers. More details [here](#actionable_section)
* [@SchemeMigration](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/SchemeMigration.java) and [@Migration](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/Migration.java) provides a simple mechanism for handling migrations between releases. More details [here](#migrations_section)
* [@Expirable](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/Expirable.java) determines if that provider will be excluded from the evicting process or not. More details [here](#expirable_section)
* [@EncryptKey](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/EncryptKey.java) and [@Encrypt](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/Encrypt.java) provides a simple way to encrypt/decrypt the data on persistence layer. More details [here](#encryption_section)

### Build an instance of Providers and use it

Finally, instantiate the Providers `interface` using `RxCache.Builder` and supplying a valid file system path which would allow RxCache to write on disk.

```java
File cacheDir = getFilesDir();
Providers providers = new RxCache.Builder()
                            .persistence(cacheDir, new GsonSpeaker())
                            .using(Providers.class);
```

### Putting It All Together

```java
interface Providers {

    @ProviderKey("mocks-evict-provider")
    Observable<List<Mock>> getMocksEvictProvider(Observable<List<Mock>> oMocks, EvictProvider evictProvider);

    @ProviderKey("mocks-paginate-evict-per-page")
    Observable<List<Mock>> getMocksPaginateEvictingPerPage(Observable<List<Mock>> oMocks, DynamicKey page, EvictDynamicKey evictPage);

    @ProviderKey("mocks-paginate-evict-per-filter")
    Observable<List<Mock>> getMocksPaginateWithFiltersEvictingPerFilter(Observable<List<Mock>> oMocks, DynamicKeyGroup filterPage, EvictDynamicKey evictFilter);
}
```

```java
public class Repository {
    private final Providers providers;

    public Repository(File cacheDir) {
        providers = new RxCache.Builder()
                .persistence(cacheDir, new GsonSpeaker())
                .using(Providers.class);
    }

    public Observable<List<Mock>> getMocks(final boolean update) {
        return providers.getMocksEvictProvider(getExpensiveMocks(), new EvictProvider(update));
    }

    public Observable<List<Mock>> getMocksPaginate(final int page, final boolean update) {
        return providers.getMocksPaginateEvictingPerPage(getExpensiveMocks(), new DynamicKey(page), new EvictDynamicKey(update));
    }

    public Observable<List<Mock>> getMocksWithFiltersPaginate(final String filter, final int page, final boolean updateFilter) {
        return providers.getMocksPaginateWithFiltersEvictingPerFilter(getExpensiveMocks(), new DynamicKeyGroup(filter, page), new EvictDynamicKey(updateFilter));
    }

    //In a real use case, here is when you build your observable with the expensive operation.
    //Or if you are making http calls you can use Retrofit to get it out of the box.
    private Observable<List<Mock>> getExpensiveMocks() {
        return Observable.just(Arrays.asList(new Mock("")));
    }
}
```

## Use cases
* Using classic API RxCache for read actions with little write needs.
* Using actionable API RxCache, exclusive for write actions.

## Classic API RxCache:

Following use cases illustrate some common scenarios which will help to understand the usage of `DynamicKey` and `DynamicKeyGroup` classes along with evicting scopes.

### List

List without evicting:
```java
Observable<List<Mock>> getMocks(Observable<List<Mock>> oMocks);
```

List evicting:
```java
Observable<List<Mock>> getMocksEvictProvider(Observable<List<Mock>> oMocks, EvictProvider evictProvider);
```

> Runtime usage:

```java
//Hit observable evicting all mocks
getMocksEvictProvider(oMocks, new EvictProvider(true))

//This line throws an IllegalArgumentException: "EvictDynamicKey was provided but not was provided any DynamicKey"
getMocksEvictProvider(oMocks, new EvictDynamicKey(true))
```

### List Filtering

List filtering without evicting:
```java
Observable<List<Mock>> getMocksFiltered(Observable<List<Mock>> oMocks, DynamicKey filter);
```

List filtering evicting:
```java
Observable<List<Mock>> getMocksFilteredEvict(Observable<List<Mock>> oMocks, DynamicKey filter, EvictProvider evictDynamicKey);
```

> Runtime usage:

```java
//Hit observable evicting all mocks using EvictProvider
getMocksFilteredEvict(oMocks, new DynamicKey("actives"), new EvictProvider(true))

//Hit observable evicting mocks of one filter using EvictDynamicKey
getMocksFilteredEvict(oMocks, new DynamicKey("actives"), new EvictDynamicKey(true))

//This line throws an IllegalArgumentException: "EvictDynamicKeyGroup was provided but not was provided any Group"
getMocksFilteredEvict(oMocks, new DynamicKey("actives"), new EvictDynamicKeyGroup(true))
```

### List Paginated with filters

List paginated with filters without evicting:
```java
Observable<List<Mock>> getMocksFilteredPaginate(Observable<List<Mock>> oMocks, DynamicKey filterAndPage);
```

List paginated with filters evicting:
```java
Observable<List<Mock>> getMocksFilteredPaginateEvict(Observable<List<Mock>> oMocks, DynamicKeyGroup filterAndPage, EvictProvider evictProvider);
```

> Runtime usage:

```java
//Hit observable evicting all mocks using EvictProvider
getMocksFilteredPaginateEvict(oMocks, new DynamicKeyGroup("actives", "page1"), new EvictProvider(true))

//Hit observable evicting all mocks pages of one filter using EvictDynamicKey
getMocksFilteredPaginateEvict(oMocks, new DynamicKeyGroup("actives", "page1"), new EvictDynamicKey(true))

//Hit observable evicting one page mocks of one filter using EvictDynamicKeyGroup
getMocksFilteredPaginateInvalidate(oMocks, new DynamicKeyGroup("actives", "page1"), new EvictDynamicKeyGroup(true))
```

As you may already notice, the whole point of using `DynamicKey` or `DynamicKeyGroup` along with `Evict` classes is to play with several scopes when evicting objects.

The above examples declare providers which their method signature accepts `EvictProvider` in order to be able to concrete more specifics types of `EvictProvider` at runtime.

But I have done that for demonstration purposes, you always should narrow the evicting classes in your method signature to the type which you really need. For the last example, I would use `EvictDynamicKey` in production code, because this way I would be able to paginate the filtered items and evict them per its filter, triggered by a pull to refresh for instance.

Nevertheless, there are complete examples for [Android and Java projects](https://github.com/VictorAlbertos/RxCacheSamples).

## Actionable API RxCache:

**Limitation: This actionable API only support `Observable` as Reactive type.**

This actionable api offers an easy way to perform write operations using providers. Although write operations could be achieved using the classic api too, it's much complex and error-prone. Indeed, the [Actions](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/ActionsList.java) class it's a wrapper around the classic api which play with evicting scopes and lists.

In order to use this actionable api, first you need to add the [repository compiler](https://github.com/VictorAlbertos/RxCache/tree/master/compiler) as a dependency to your project using an annotation processor. For Android, it would be as follows:

Add this line to your root build.gradle:

```gradle
dependencies {
     // other classpath definitions here
     classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
 }
```

Then make sure to apply the plugin in your app/build.gradle and add the compiler dependency:

```gradle
apply plugin: 'com.neenbedankt.android-apt'

dependencies {
    // apt command comes from the android-apt plugin
    apt "com.github.VictorAlbertos.RxCache:compiler:1.8.3-2.x"
}
```

After this configuration, every provider annotated with [@Actionable](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/Actionable.java) `annotation`
will expose an accessor method in a new generated class called with the same name as the interface, but appending an 'Actionable' suffix.

The order in the params supplies must be as in the following example:

```java
public interface RxProviders {
    @Actionable
    Observable<List<Mock.InnerMock>> mocks(Observable<List<Mock.InnerMock>> message, EvictProvider evictProvider);

    @Actionable
    Observable<List<Mock>> mocksDynamicKey(Observable<List<Mock>> message, DynamicKey dynamicKey, EvictDynamicKey evictDynamicKey);

    @Actionable
    Observable<List<Mock>> mocksDynamicKeyGroup(Observable<List<Mock>> message, DynamicKeyGroup dynamicKeyGroup, EvictDynamicKeyGroup evictDynamicKey);
}
```

The observable value must be a `List`, otherwise an error will be thrown.

The previous RxProviders `interface` will expose the next accessors methods in the generated `RxProvidersActionable` class.
```java
RxProvidersActionable.mocks(RxProviders proxy);
RxProvidersActionable.mocksDynamicKey(RxProviders proxy, DynamicKey dynamicKey);
RxProvidersActionable.mocksDynamicKeyGroup(RxProviders proxy, DynamicKeyGroup dynamicKeyGroup);
```

These methods return an instance of the `Actions` class, so now you are ready to use every write operation available in the [Actions](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/ActionsList.java) class. It is advisable to explore the [ActionsTest](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/test/java/io/rx_cache/internal/ActionsListTest.java) class to see what action fits better for your case. If you feel that some action has been missed please don't hesitate to open an issue to request it.

Some actions examples:

```java
ActionsProviders.mocks(rxProviders)
    .addFirst(new Mock())
    .addLast(new Mock())
    //Add a new mock at 5 position
    .add((position, count) -> position == 5, new Mock())

    .evictFirst()
    //Evict first element if the cache has already 300 records
    .evictFirst(count -> count > 300)
    .evictLast()
    //Evict last element if the cache has already 300 records
    .evictLast(count -> count > 300)
    //Evict all inactive elements
    .evictIterable((position, count, mock) -> mock.isInactive())
    .evictAll()

    //Update the mock with id 5
    .update(mock -> mock.getId() == 5, mock -> {
        mock.setActive();
        return mock;
    })
    //Update all inactive mocks
    .updateIterable(mock -> mock.isInactive(), mock -> {
        mock.setActive();
        return mock;
    })
    .toObservable()
    .subscribe(processedMocks -> {})
```

Every one of the previous actions will be execute only after the composed observable receives a subscription. This way, the underliyng provider cache will be modified its elements without effort at all.

## Migrations

RxCache provides a simple mechanism for handling migrations between releases.

You need to annotate your providers `interface` with [@SchemeMigration](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/SchemeMigration.java). This `annotation` accepts an array of [@Migration](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/Migration.java) annotations, and, in turn, `@Migration` annotation accepts both, a version number and an array of `Class`es which will be deleted from persistence layer.

```java
@SchemeMigration({
            @Migration(version = 1, evictClasses = {Mock.class}),
            @Migration(version = 2, evictClasses = {Mock2.class}),
            @Migration(version = 3, evictClasses = {Mock3.class})
    })
interface Providers {}
```

You want to annotate a new migration only when a new field has been added in a class model used by RxCache.

Deleting classes or deleting fields of classes would be handle automatically by RxCache, so you don't need to annotate a new migration when a field or an entire class has been deleted.

For instance:

A migration was added at some point. After that, a second one was added eventually.

```java
@SchemeMigration({
            @Migration(version = 1, evictClasses = {Mock.class}),
            @Migration(version = 2, evictClasses = {Mock2.class})
    })
interface Providers {}
```

But now `Mock` class has been deleted from the project, so it is impossible to reference its class anymore. To fix this, just delete the migration `annotation`.

```java
@SchemeMigration({
            @Migration(version = 2, evictClasses = {Mock2.class})
    })
interface Providers {}
```

Because RxCache has an internal process to clean memory when it is required, the data will be evicted eventually.

## Encryption

RxCache provides a simple mechanism to encrypt the data.

You need to annotate your providers `interface` with [@EncryptKey](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/EncryptKey.java). This `annotation` accepts a string as the `key` necessary to encrypt/decrypt the data. But you will need to annotate your provider's records with [@Encrypt](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/Encrypt.java) in order to saved the data encrypted. If no [@Encrypt](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/Encrypt.java) is set, then no encryption will be held.

**Important:** If the value of the `key` supplied on [@EncryptKey](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/EncryptKey.java) is modified between compilations, then the previous persisted data will not be able to be evicted/retrieved by RxCache.

```java
@EncryptKey("myStrongKey-1234")
interface Providers {
        @Encrypt
        Observable<List<Mock>> getMocksEncrypted(Observable<List<Mock>> oMocks);

        Observable<List<Mock>> getMocksNotEncrypted(Observable<List<Mock>> oMocks);
}
```

## Configure general behaviour

RxCache allows to set certain parameters when building the providers instance:

### Configure the limit in megabytes for the data to be persisted

By default, RxCache sets the limit in 100 megabytes, but you can change this value by calling setMaxMBPersistenceCache method when building the provider instance.

```java
new RxCache.Builder()
            .setMaxMBPersistenceCache(maxMgPersistenceCache)
            .persistence(cacheDir)
            .using(Providers.class);
```

This limit ensure that the disk will no grow up limitless in case you have providers with dynamic keys which values changes dynamically, like filters based on gps location or dynamic filters supplied by your back-end solution.

When this limit is reached, RxCache will not be able to persist in disk new data. That's why RxCache has an automated process to evict any record when the threshold memory assigned to the persistence layer is close to be reached, even if the record life time has not been fulfilled.

But provider's record annotated with [@Expirable](https://github.com/VictorAlbertos/RxCache/blob/master/runtime/src/main/java/io/rx_cache/Expirable.java) annotation and set its value to false will be excluded from the process.

```java
interface Providers {
    @Expirable(false)
    Observable<List<Mock>> getMocksNotExpirable(Observable<List<Mock>> oMocks);
}
```

### Use expired data if loader not available

By default, RxCache will throw a RuntimeException if the cached data has expired and the data returned by the observable loader is null,
preventing this way serving data which has been marked as evicted.

You can modify this behaviour, allowing RxCache serving evicted data when the loader has returned null values, by setting as true the value of useExpiredDataIfLoaderNotAvailable

```java
new RxCache.Builder()
            .useExpiredDataIfLoaderNotAvailable(true)
            .persistence(cacheDir)
            .using(Providers.class);
```

## Android considerations

To build an instance of the interface used as provides by RxCache, you need to supply a reference to a file system. On Android, you can get the File reference calling getFilesDir() from the [Android Application](http://developer.android.com/intl/es/reference/android/app/Application.html) class.

Also, it is recommended to use this Android Application class to provide a unique instance of RxCache for the entire life cycle of your application.

In order execute the Observable on a new thread, and emit results through onNext on the main UI thread, you should use the built in methods provided by [RxAndroid](https://github.com/ReactiveX/RxAndroid).

Check the [Android example](https://github.com/VictorAlbertos/RxCacheSamples/tree/master/sample_android)

## Retrofit

RxCache is the perfect match for Retrofit to create a repository of auto-managed-caching data pointing to endpoints.
You can check an [example](https://github.com/VictorAlbertos/RxCacheSamples/blob/master/sample_data/src/main/java/sample_data/Repository.java) of RxCache and Retrofit working together.

## Internals

RxCache serves the data from one of its three layers:

* A memory layer -> Powered by [Apache ReferenceMap](https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/map/ReferenceMap.html).
* A persisting layer -> RxCache uses internally [Jolyglot](https://github.com/VictorAlbertos/Jolyglot) for serialize and deserialize objects.
* A loader layer (the observable supplied by the client library)

The policy is very simple:

* If the data requested is in memory, and It has not been expired, get it from memory.
* Else if the data requested is in persistence layer, and It has not been expired, get it from persistence.
* Else get it from the loader layer.

## Proguard
Proguard users MUST add the two given lines to their proguard configuration file and MUST use the `@ProviderKey` annotation method for every method that is being used as provider. Without the `@ProviderKey` annotation the method name will be used instead which can lead to providers that use the same name, see issue [#96](https://github.com/VictorAlbertos/RxCache/issues/96) for detailed information.

```
-dontwarn io.rx_cache2.internal.**
-keepclassmembers enum io.rx_cache2.Source { *; }
-keepclassmembernames class * { @io.rx_cache2.* <methods>; }
```

## Author

**Víctor Albertos**

* <https://twitter.com/_victorAlbertos>
* <https://www.linkedin.com/in/victoralbertos>
* <https://github.com/VictorAlbertos>

## RxCache Swift version:
[RxCache](https://github.com/VictorAlbertos/RxSCache): Reactive caching library for Swift.

## Another author's libraries using RxJava:
* [Mockery](https://github.com/VictorAlbertos/Mockery): Android and Java library for mocking and testing networking layers with built-in support for Retrofit.
* [RxActivityResult](https://github.com/VictorAlbertos/RxActivityResult): A reactive-tiny-badass-vindictive library to break with the OnActivityResult implementation as it breaks the observables chain.
* [RxFcm](https://github.com/VictorAlbertos/RxFcm): RxJava extension for Android Firebase Cloud Messaging (aka fcm).
* [RxSocialConnect](https://github.com/VictorAlbertos/RxSocialConnect-Android): OAuth RxJava extension for Android.

repository: VictorAlbertos/RxCache

gha_language: Java

repo_name: VictorAlbertos/RxCache


text:
# sanmodal
Free Responsive Modal
For using in your HTML, PHP, .Net, Java, Python, NodeJs, Ruby, Angular, React projects.

This is a basic working structure that you can customize to style according to your desired theme.

Free for use for the purpose of personal and commercial till you keep the copyright information in header as it is.
### Example: [San Modal](http://sanjibchatterjee.com/sanmodal/sanmodal.html).

## How to use?
* Link the CSS file sanmodal.css with the html inside <head> Tag.
* Link the button/ div/ image/ any element, you like to link the modal with as per given Id.
```
<div id="openBtn">Modal 1</div>
```
* Add the following html-
```
<div id="sanmodal" class="sanmodal">
	<div class="modal-wrapper">
		<div class="modal-top">
			<span class="close" id="close">×</span>
			<div class="modal-title">Modal 1 Title</div>
		</div>

		<div class="modal-contents">
			Modal subjects and data goes here. . . .<br>
			More data goes here. . . .<br>
			And more data goes here. . . .<br>
		</div>
		<div class="modal-bottom">Modal bottom part.</div>
	</div>
</div>
```
* Add the following javascript in the html after the related html code, ie at bottom part inside the body. This is the custom part where you can change the id as per the id given to the element.
```
<script>
var modal = document.getElementById('sanmodal');
var btn = document.getElementById('openBtn');
var close = document.getElementById('close');
</script>
```
* Link the Javascript file sanmodal.js under the above script. and Bingo!
## NB: There is more in this plugin-
If you like to have the modal pop up from downside and stays at bottom you just need to change the id and class as per following information:
The js-
```
var modalbot = document.getElementById('sanmodalbot');
var btnbot = document.getElementById('openBtnbot');
var closebot = document.getElementById('closebot');
```
and just change the id & class names from sanmodal to sanmodalbot; modal-wrapper to modal-wrapperbot in the html. And your modal will be coming from bottom like you see in mobiles.

repository: Sanjibchatterjee/sanmodal

repo_name: Sanjibchatterjee/sanmodal


text:
---
layout: project
type: project
image: images/emart.jpg
title: E-Mart
permalink: projects/emart
# All dates must be YYYY-MM-DD format!
date: 2022-04-25
labels:
  - React JS
  - Bootstrap-sass
  - Redux
  - Fake Store API
summary: An E-Commerce Store built with React, Redux, Bootstrap and Fake Store API.
---

An E-Commerce Store built with React, Redux, Bootstrap and Fake Store API.

You can learn more at the [E-Mart Website](https://pjmantoss.github.io/e-mart/).

Github


text:
# Grocery Store AI

Grocery Store AI is an Artificial Intelligence based game made with Unity developed for a university project in CITM UPC (Terrasa, Spain) in our degree in Videogame Developement and Design.

## Information

Grocery Store AI has 4 entities; cashier, client, cleaner and dependent that complete their function in a usual grocery store by our own programmed Steering Behaviours and with their own Behaviour Trees to move across, in and out of the store with its corresponding day/night cycle.

## Innovation Website

Go to our website for full information and visuals: https://manavld.github.io/GroceryStoreAI/

### Cashier

Spawn, Paths to his cash and waits till his turn is finished. Then goes home around 10 o'clock at night.

### Client

Spawns when the shop is open, goes to inside the shop, picks an area to pick an object, then wait his turn in the queue to buy the thing he picked, when a spot is clear, he goes in and buys. He stays there a bit with the cashier, waiting his change. After he got the change, he goes home.

### Cleaner

At 12::00 at night he comes to clean the shop, after he cleaned all the shop he goes home.

### Dependent

Goes to the store when his shift starts, waits and observes clients if they need help, helps the clients when they do, goes home when shift ends. For dependent movements, when a client needs your help to decide wich product will buy, you have to click the dependent, and then click the client. Afterwards the dependent will talk with the client and help him decide, so he goes home happy.

## Controls

* WASD: Camera Movement
* R: Return camera to initial position
* With the mouse you can tell the dependent to help a client.
* Car Botton: Click and put the car around the outside of the store to spawn car
* Cashier Botton: Click to automatically create a cashier machine inside the store (maximum of 3 active)
* Pause Botton: Click to pause game
* Lvl up cashier so they sell faster.
* Marketing Campaign button: Does a marketing campeign to increase a star.

## Win/Loss Condition

* **Win**: The player will win if he/she successfuly completed 3 days without upseting more than 4 clients by leaving them unattending when they ask for help.
* **Loss**: The player will lose if the store review has 0 stars.

## Authors

* Gerard Gil: https://github.com/Gerard346
* Manav Lakhwani: https://github.com/manavld

## Instructions

Download the .zip in the last release in https://github.com/Gerard346/Project-AI/releases and open the file .exe to play the game.

## Github Repository

https://github.com/Gerard346/Project-AI

## Link to the Wiki

You will find information about the game and the Behaviour Trees in the wiki: https://github.com/Gerard346/Project-AI/wiki

## Behaviour Trees

* **Client**: The client will decide to go to the store if open, go to the object he need and pick it up or ask for help, when picked the client will go to the queue, buy his items, and go home when bought.

![Client BT](https://github.com/manavld/AIProjectPics/blob/master/Client%20BT2.jpg)

* **Cashier**: The cashier will go to work when the store is open, start working when its his turn, attend the clients when client is buying and go home when his turn ended.

![Cashier BT](https://github.com/manavld/AIProjectPics/blob/master/Cashier%20BT.jpg)

* **Cleaner**: The cleaner will walk to work when its his turn to work, grab the mob and start working until his time is done, leaves the mob back and goes back home.

![Cleaner BT](https://github.com/manavld/AIProjectPics/blob/master/Cleaner%20BT.jpg)

* **Dependent**: The dependent will go to work when his shift starts, will observe the clients in case they need help, when client is in need of help the dependent will go there and help the client and when his shift ends he will leave the shop and go home.

![Dependent BT](https://github.com/manavld/AIProjectPics/blob/master/Dependent%20BT.jpg)

## License

We use the MIT License this is a permissive free software license originating at the Massachusetts Institute of Technology.

MIT License

Copyright (c) 2019 Gerard Gil & Manav Lakhwani

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

 IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


text:
---
title: Generating package documentation
category: installing
permalink: /FAQ-install-doc
---

We are faced with a range of "normal" provision, as well as several
oddities.  One should note that documentation of many packages is
available on CTAN, without the need of any further effort by
the user — such documentation can usually be browsed _in situ_.

However, if you find a package that does not offer documentation on
the archive, or if you need the documentation in some other format
than the archive offers, you can usually generate the documentation
yourself from what you download from the archive.

The standard mechanism, for LaTeX packages, is simply to run
LaTeX on the `package.dtx` file, as you would any ordinary
LaTeX file (i.e., repeatedly until the warnings go away).

A variant is that the unpacking process provides a file
`package.drv`; if such a thing appears, process it in preference
to the `package.dtx` (it seems that when the documented LaTeX
source mechanism was first discussed, the `.drv` mechanism was
suggested, but it's not widely used nowadays).

Sometimes, the LaTeX run will complain that it can't find
`package.ind` (the code line index) and/or `package.gls`
(the list of change records, not as you might imagine, a glossary).
Both types of file are processed with special `makeindex`
style files; appropriate commands are:
```latex
makeindex -s gind package
makeindex -s gglo -o package.gls package.glo
```
This author finds that the second (the change record) is generally of
limited utility when reading package documentation; it is, however,
valuable if you're part of the package development team.  If you don't
feel you need it, just leave out that step

Another common (and reasonable) trick performed by package authors is
to provide a separate file `package-doc.tex` or even simply
`manual.tex`; if the file `package.dtx` doesn't help, simply
look around for such alternatives.  The files are treated in the same
way as any "ordinary" LaTeX file.


text:
# protobuf-jackson

protobuf-jackson is a library for efficient marshalling of Protocol Buffer messages to and from
JSON. It is based on the streaming API of the Jackson JSON handling library and uses Byte Buddy to
generate efficient bytecode at runtime for marshalling specific message types.

This library requires Java 7 only to allow cleaner syntax (e.g., multi-catch, diamond operator) for
easier maintenance. If there is demand, re-targeting to Java 6 is conceivable.

## Why another Protocol Buffer <-> JSON marshaller

The official Protocol Buffer Java library comes with a util library for marshalling to JSON, using
a class called JsonFormat. Unfortunately, JsonFormat is very slow, and its core design of using
manual JSON printers / GSON parsers and introspection during serialization time limit how fast it
can get.

JSON marshalling is important - it can allow existing REST services to be migrated to Protocol
Buffers and makes it easier to evangelize their use in organizations currently tied heavily to JSON.
However, slow marshalling prevents these use cases from being practical, so this library aims to
allow JSON marshalling to be fast enough for production. It will never be as good as binary
serialization, but should be about as fast as standard REST API libraries.

If the protoc compiler supports generating source code for JSON marshalling, this library will
likely be deprecated.

## Usage

Include protobuf-jackson as a dependency. Gradle users can add

```groovy
'org.curioswitch.curiostack:protobuf-jackson:1.0.0'
```

to their dependencies.

The API is exposed in ```MessageMarshaller```. Use its builder to configure options and register
specific Protocol Buffer message types you will marshall. Any other types will not be marshallable
by the built ```MessageMarshaller```.

```java
class MessageApi {

  private static final MessageMarshaller marshaller = MessageMarshaller.builder()
      .register(ApiRequest.getDefaultInstance())
      .register(ApiResponse.getDefaultInstance())
      .build();

  String coolApi(String jsonRequest) {
    ApiRequest.Builder request = ApiRequest.newBuilder();
    marshaller.mergeValue(jsonRequest, request);

    ApiResponse response = processRequest(request);

    return marshaller.writeValueAsString(response);
  }
}
```

## Design

protobuf-jackson introspects registered message types during bytecode generation time and generates
code specific to the type. Unlike JsonFormat, this means that during actually marshalling, there is
no introspection of the message type at all - it's already been done during registration. In
addition, messages are accessed through their standard Java generated API, no reflection is needed.
No reflection allows the JIT to optimize generated machine code as much as possible. By generating
bytecode, we approach the same speed that could be achieved by generating the source code itself.

All of the same tests as ```JsonFormat``` (besides the differences listed below) pass, so
protobuf-jackson should be mostly compatible with upstream and ready for production.

## Differences with upstream

Differences with JsonFormat are

- No support for ```DynamicMessage```. The library is designed to interact with generated code for
optimal performance. If you don't know what ```DynamicMessage``` is, you are not using it. If you
do, stick with ```JsonFormat```.

- Does not support parsing Any messages where ```@type``` is not the first field.

- Correctly handles invalid array syntax. ```JsonFormat``` does not due to its dependency on GSON.
See [JsonFormatTest](https://github.com/google/protobuf/blob/master/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java#L1124).

- Correctly rejects invalid JSON which specifies the same field twice. ```JsonFormat``` does not due
to its dependency on GSON. See [JsonFormatTest](https://github.com/google/protobuf/blob/master/java/util/src/test/java/com/google/protobuf/util/JsonFormatTest.java#L458)

- Fields already present in the passed in ```Message.Builder``` will be overwritten, rather than
causing the parse to fail, as is usual with merge semantics.

## Benchmarks

First, a synthetic benchmark that uses the upstream ```TestAllTypes``` proto which contains all
types of fields.

```
Benchmark                                  Mode  Cnt        Score       Error  Units
JsonParserBenchmark.codegenJson           thrpt   50   114260.817 ±  1162.079  ops/s
JsonParserBenchmark.fromBinary            thrpt   50   448586.946 ±  7946.499  ops/s
JsonParserBenchmark.upstreamJson          thrpt   50    43392.884 ±   715.184  ops/s
JsonSerializeBenchmark.codegenJson        thrpt   50   204768.672 ±  2459.787  ops/s
JsonSerializeBenchmark.toBytes            thrpt   50  1071878.319 ± 12628.059  ops/s
JsonSerializeBenchmark.upstreamJson       thrpt   50    49941.606 ±   707.045  ops/s
```

protobuf-jackson generally shows a 4x speed up in serialization and 3x speed up in parsing vs
upstream JSON parsing. It is about 4-5x slower than protobuf binary marshalling.

For a more real-world example, the JSON response of the [GitHub search API](https://developer.github.com/v3/search/#example)
was used. A proto file corresponding to the format was made to model what an actual data exchange
may look like. This is just one example, and other examples may have different results, but
hopefully the trends are similar

```
Benchmark                                  Mode  Cnt        Score       Error  Units
GithubApiBenchmark.marshallerParseString  thrpt   50     1696.653 ±   170.891  ops/s
GithubApiBenchmark.marshallerWriteString  thrpt   50     3042.433 ±   172.438  ops/s
GithubApiBenchmark.protobufParseBytes     thrpt   50     4599.390 ±    56.570  ops/s
GithubApiBenchmark.protobufToBytes        thrpt   50    21315.212 ±   210.659  ops/s
GithubApiBenchmark.upstreamParseString    thrpt   50      472.902 ±     6.455  ops/s
GithubApiBenchmark.upstreamWriteString    thrpt   50      717.227 ±     8.834  ops/s
```

For both parsing and serializing, protobuf-jackson is about 4x faster.

One other way to look at these results is that JSON marshalling is now less than an order of
magnitude different than protobuf binary marshalling, which was not the case before. While binary
marshalling will always be preferred, for use cases that demand it, JSON should also be acceptable
in production.


text:
# Setting up Ruuvi Collector

## Collecting data

This second part will configure Rasberry to collect the data.

## Install software

Ruuvi provides both Python and Java libraries to collect data from tags. However, the python code is not so great so let's use Java. Thus, a Java and Maven are needed.

```bash
sudo apt install default-jdk maven
```

Bluetooth libraries are needed, too. Raspbian uses Linux SE, so need to set capabilities also.

```bash
sudo apt install bluez bluez-hcidump
sudo setcap 'cap_net_raw,cap_net_admin+eip' `which hcitool`
sudo setcap 'cap_net_raw,cap_net_admin+eip' `which hcidump`
```

## Build and configure RuuviCollector

Ok, ready to build RuuviCollector.

```bash
cd /src/git
git clone https://github.com/Scrin/RuuviCollector
cd RuuviCollector
mvn clean package
```

If there were no errors we're good to set RuuviCollector up.

```bash
cd; mkdir ruuvitag
cp src/git/RuuviCollector/target/ruuvi-collector-0.2.jar ruuvitag/
cp src/git/RuuviCollector/ruuvi-collector.properties.example ruuvitag/ruuvi-collector.properties
cp src/git/RuuviCollector/ruuvi-names.properties.example ruuvitag/ruuvi-names.properties
cd ruuvitag/
touch ruuvicollector.service
```

Edit `ruuvi-collector.properies` with following options (replace obvious part with valid data):

```bash
influxUrl=https://[remote_host]/influxdb/

influxDatabase=house

influxUser=ruuvi
influxPassword=[secretpassword]

influxGzip=false
```

Edit `ruuvi-names.properties` to taste (get tag-ids with `hcidump`).

## Make sure Collector runs at any time

Put the following into `ruuvicollector.service` file:

```bash
[Unit]
Description=RuuviCollector Service
After=network.target

[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/RuuviCollector
ExecStart=/usr/bin/java -jar /home/pi/RuuviCollector/ruuvi-collector-0.2.jar
Restart=always

[Install]
WantedBy=multi-user.target
```

Finally, set up a systemctl service and fire it up.

```bash
sudo cp ruuvicollector.service /etc/systemd/system/
sudo systemctl enable ruuvicollector.service
sudo systemctl start ruuvicollector
sudo systemctl status ruuvicollector.service
```

## Raspberry configuration is done

At this point Raspberry should be configured, up and running and pushing collected measurements into remote database. Only that this remote database does not exist yet so all you get are errors.

repository: heikkil/homemon

repo_name: heikkil/homemon


text:
# "Classic" Style
- Literals
 - A
- Negation
 - NOT A
- Conjunctions
 - A AND B
- Disjunctions
 - A OR B
- Implication
 - A IMPLIES B
- Biconditional
    - A IFF B

#Sample Input file:
- NOTE: Last Input input line corresponds to the conclusion

 ```sh
A IMPLIES (N OR Q)
NOT(N OR NOT A)
A IMPLIES Q
```

repository: astonshane/davisputnam

repo_name: astonshane/davisputnam


text:
# react-repeatable [![build status](https://travis-ci.org/cheton/react-repeatable.svg?branch=master)](https://travis-ci.org/cheton/react-repeatable) [![Coverage Status](https://coveralls.io/repos/github/cheton/react-repeatable/badge.svg?branch=master)](https://coveralls.io/github/cheton/react-repeatable?branch=master)

[![NPM](https://nodei.co/npm/react-repeatable.png?downloads=true&stars=true)](https://nodei.co/npm/react-repeatable/)

A press and hold wrapper component that can trigger hold action multiple times while holding down.

Demo: https://cheton.github.io/react-repeatable

## Installation

```
npm install --save react-repeatable
```

## Usage

```jsx
<Repeatable
    repeatDelay={500}
    repeatInterval={32}
    onPress={(event) => {
        // Callback fired when the mousedown or touchstart event is triggered.
    }}
    onHoldStart={() => {
        // Callback fired once before the first hold action.
    }}
    onHold={() => {
        // Callback fired mutiple times while holding down.
    }}
    onHoldEnd={() => {
        // Callback fired once after the last hold action.
    }}
    onRelease={(event) => {
        // Callback fired when the mouseup, touchcancel, or touchend event is triggered.
    }}
>
    Press Me
</Repeatable>
```

### Repeatable Button

```jsx
const RepeatableButton = ({ onClick, ...props }) => (
    <Repeatable
        tag="button"
        type="button"
        onHold={onClick}
        onRelease={onClick}
        {...props}
    />
);

<RepeatableButton onClick={handleClick} />
```

## API

### Sequence of Events

#### Hold action is occurred
onPress -> onHoldStart -> onHold (once or more) -> onHoldEnd -> onRelease

#### Hold action is not occurred
onPress -> onRelease

### Properties

Name | Type | Default | Description
:--- | :--- | :------ | :----------
tag | element | 'div' | A custom element for this component.
disabled | Boolean | false | Set it to true to disable event actions.
repeatDelay | Number | 500 | The time (in milliseconds) to wait before the first hold action is being triggered.
repeatInterval | Number | 32 | The time interval (in milliseconds) on how often to trigger a hold action.
repeatCount | Number | 0 | The number of times the hold action will take place. A zero value will disable the repeat counter.
onPress | Function(event) | | Callback fired when the mousedown or touchstart event is triggered.
onHoldStart | Function() | | Callback fired once before the first hold action.
onHold | Function() | | Callback fired mutiple times while holding down.
onHoldEnd | Function() | | Callback fired once after the last hold action.
onRelease | Function(event) | | Callback fired when the mouseup, touchcancel, or touchend event is triggered.

## License

MIT

repository: cheton/react-repeatable

repo_name: cheton/react-repeatable


text:
Building gSuneido
================

The Windows version with DLL and COM support needs [cgo](https://golang.org/cmd/cgo/) so it requires a C/C++ compiler on the path. I am using [Mingw-w64](https://sourceforge.net/projects/mingw-w64/). You can either install Msys2 or just Mingw-w64. The specific version of GCC shouldn't be critical (but not too ancient). I would recommend using a normal install of Go, *not* installing it in Msys2 with pacman. Go just needs gcc on the path.

From the terminal, running:

    g++ --version

Should give something like:

    g++ (x86_64-posix-seh-rev0, Built by MinGW-W64 project) 8.1.0

I've been mostly working on the Windows version so building on Linux or Mac may occasionally be broken due to build tags etc. Cgo is not required for these versions, they are plain Go. But the only UI is the command line REPL.

I use the included makefile (requires make). If you prefer not to use make you can just look at the makefile to see what the build commands are. There is a make included with mingw_w64 but it's called `mingw32_make.exe` You can make a copy and rename it to `make.exe`

You should be able to run the tests with the usual: `go test ./..`

To run the [portable tests](https://github.com/apmckinlay/suneido_tests) (shared with cSuneido and jSuneido) you need to clone or download the separate Github repository. It needs to be a peer of the gsuneido directory, and must be called suneido_tests. e.g. `c:/stuff/mygsuneido` and `c:/stuff/suneido_tests`

All my development and testing has been on 64 bit. In theory you could build a 32 bit version of gSuneido but I suspect it would require some changes. It might be useful for client mode since it would use less memory because pointers and int's would be smaller (32 bits instead of 64) The client is unlikely to need access to more than 2gb of memory.

There are some warnings for the code - `composite literal uses unkeyed fields` and `possible misuse of unsafe.Pointer`. I've been trying to fix other warnings.

My normal environment is [Visual Studio Code](https://code.visualstudio.com/) with the [Go extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.Go) using gopls. Debugging (with the included Delve) can be problematic, sometimes it works.

repository: apmckinlay/gsuneido

gha_language: Go

repo_name: apmckinlay/gsuneido


text:
---
title: Contributing to the docs
---

Contributing is welcome and easy!

For text changes:

* Press the `EDIT` button at the bottom left of the page.
* Press the `Fork this repository` button when prompted.
* Make your edits and press `Propose change`.
* On the `Comparing changes` screen, press `Create pull request`.

You can test out our changes locally using Docker and Docker Compose. Clone your forked repository, and then run `docker-compose up`. Open `http://localhost:3000` in your browser to see the docs site.

If you you have bigger changes to submit, read the [CONTRIBUTING.md](https://github.com/pact-foundation/docs.pact.io/blob/master/CONTRIBUTING.md) file in the docs repository.


text:
# Else-CI-CD
[![Build Status](https://travis-ci.org/frederickjansen/else-ci-cd.svg?branch=master)](https://travis-ci.org/frederickjansen/else-ci-cd)

### Babel

[Babel](https://babeljs.io/) is used to transpile JavaScript code in order to target older browsers.

```npm install --save-dev babel-cli babel-preset-env```

Create a new `.babelrc` file with ES2015 as the environment:

```json
{
  "presets": ["env"]
}
```

Add a build step to npm to transpile code to ES2015:

```
"scripts": {
  "build": "babel src -d dist"
}
```

Build your code with ```npm run build```.

### Webpack
See the [Babel Modules](https://babeljs.io/docs/plugins/#transform-plugins-modules) doc for the different module options.

Install Webpack with the Babel loader:

```npm install --save-dev babel-loader webpack```

Add Webpack as a build step to package.json:

```
"scripts": {
  "webpack": "webpack"
}
```

Create a new configuration file `webpack.config.js`:

```javascript
var path = require('path');

module.exports = {
  entry: './src/app.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['env']
          }
        }
      }
    ]
  },
  stats: {
    colors: true
  },
  devtool: 'source-map'
};
```

Compile your code with ```npm run webpack```.

### Mocha + Chai + Sinon

Install [Mocha](https://mochajs.org/), [Chai](http://chaijs.com/), and [Sinon]():

```npm install --save-dev mocha chai sinon sinon-chai```

Create a `test` folder and add your tests, following the `$name$-test.js` pattern.
Add a new test command to `package.json`:

```
"scripts": {
  "test": "mocha --require babel-register"
}
```

Run your tests with ```npm test```.

#### Spies and mocks

Install mock local storage:

```npm install --save-dev mock-local-storage```

And register it with Mocha in package.json:

```
"scripts": {
  "test": "mocha --require babel-register mock-local-storage"
}
```

Import the mocked localstorage object in your tests:

```javascript
global.window = {};
import localStorage from 'mock-local-storage';
window.localStorage = global.localStorage;
```

#### Mock Server

Create a fake `XMLHttpRequest`:

```javascript
xhr = sinon.useFakeXMLHttpRequest();
requests = [];
xhr.onCreate = function (req) { requests.push(req); };
```

Add fake response for XHR requests:

```javascript
requests[0].respond(
  200,
  { 'Content-Type': 'application/json' },
  JSON.stringify([{ id: 1, title: 'Finish demo', completed: true }])
);
```

### Istanbul

Install Istanbul:

```npm install --save-dev nyc```

Modify testing script with nyc:

```
"scripts": {
  "test": "nyc mocha --require babel-register"
}
```

### Travis

Add Coveralls as a dependency:

```npm install --save-dev coveralls```

Create script that pipes Istanbul coverage to Coveralls:

```
"scripts": {
  "coverage": "nyc report --reporter=text-lcov | coveralls"
}
```

Create `.travis.yml` file:

```yaml
language: node_js
node_js:
 - "stable"
after_success: npm run coverage
```

Enter environment variable `COVERALLS_REPO_TOKEN` in Travis.

### Karma

### ESLint


text:
Making a custom rock
====================

Each release of the SimpleITK Luarock is tied to a specific release of
SimpleITK.  For example the 1.2 SimpleITK Luarock downloads v1.2 of
SimpleITK from GitHub.

If you would prefer to build a different version of SimpleITK, you need
a custom version of the rockspec file.  Here is what such a rockspec
file would look like.

    #!/usr/bin/env lua

    package = 'SimpleITK'
    version = 'x.0-0'
    source  = {
        url    = 'file://SimpleITKLuarock.tgz',
        dir = 'SimpleITKLuarock',
    }
    description = {
        summary  = "A Lua binding to SimpleITK.",
        detailed = '',
        homepage = 'https://github.com/SimpleITK/SimpleITKLuaRock',
        license  = 'BSD',
    }
    dependencies = {
        'lua >= 5.1'
    }
    build    = {
        type = 'cmake',
        modules = {
            SimpleITK = "SimpleITK-build/Wrapping/Lua/lib/SimpleITK.so",
        },
        variables = {
            INSTALL_CMOD      = "$(LIBDIR)",
            CMAKE_BUILD_TYPE  = "$(CMAKE_BUILD_TYPE)",
            ["CFLAGS:STRING"] = "$(CFLAGS)",
        },
        copy_directories = { "doc", "examples" }
    }

The main difference between this rockspec and the standard version is the
**source** section.  In this rockspec the source points to a local tar
file.

Also, this rockspec does not have the SimpleITK_VERSION variable
in the build/variables section that the v1.2 rockspec does.  So the v1.2
rockspec tells CMake to use SimpleITK version 1.2.  Because this custom
rockspec does not have the SimpleITK_VERSION set, cmake will use the
latest version from GitHub's master branch of SimpleITK.

If you wanted to test build a newer version of the SimpleITK Lua rock,
just create a custom rockspec with SimpleITK_VERSION set to the newer
version.

repository: SimpleITK/SimpleITKLuaRock

gha_language: CMake

repo_name: SimpleITK/SimpleITKLuaRock


text:
# Prevents usage of discouraged words. (best-practices/no-discouraged-words)

Use in order to prevent discouraged words in variable names and comments.

```js
// .eslintrc.json
{
  "plugins": ["@spotify/eslint-plugin"],
  "rules": {
    "@spotify/best-practices/no-discouraged-words": "error",
  }
}
```

## Discouraged words

```js
const discouragedWords = ['blacklist', 'whitelist'];
```

To make a contribution to the list, see [this file](./no-discouraged-words.ts). PRs are most welcome!

## Rule details

This rule will raise the following error whenever you refer to one of the discouraged words above:

> Usage of the word "{word}" is strongly discouraged. Please use a different word.

repository: spotify/web-scripts

gha_language: TypeScript

repo_name: spotify/web-scripts


text:
Furious - An Asynchronous Workflow Library.
===========================================

Introduction
------------

Furious is a lightweight library that wraps Google App Engine taskqueues to
make building dynamic workflows easy.

Installation
------------

Include `furious` within your App Engine project's libary directory, often
`/lib`.  If that does not make sense to you, simply include the `furious`
subdirectory within your application's root directory (where your `app.yaml`
is located).

Usage
-----

In the simplest form, usage looks like:

    from furious.async import Async

    # Create an Async object.
    async = Async(
        target="your.module.func",
        args=("positional", "args"),
        kwargs={"foo": "bar"})

    # Tell the async to insert itself to be run.
    async.start()

This inserts a task that will make the following call:

    your.module.func("positional", "args", foo="bar")

**CAUTION**: Arguments **must** be json-serializable.
Contrast that with the [deferred lib](https://cloud.google.com/appengine/articles/deferred),
which allows any picklable type
(see [What can be pickled and unpickled?](https://docs.python.org/2/library/pickle.html#what-can-be-pickled-and-unpickled)).

Why did furious choose this limitation?
When a python object that is pickled gets moved in the code base,
attempts to unpickle it will blow up. Furious tasks can run on
different instances at a future time by which there may have
been a code deploy done. References:

* [Alex Gaynor: Pickles are for Delis, not Software - PyCon 2014 - YouTube](https://www.youtube.com/watch?v=7KnfGDajDQw&t=1292)
* [Don't Pickle Your Data](http://www.benfrederickson.com/dont-pickle-your-data/)

### Grouping async jobs

You can group jobs together,

    from furious import context

    # Instantiate a new Context.
    with context.new() as batch:

        for number in xrange(10):

            # Create a new Async object that will be added to the Context.
            batch.add(target="square_a_number", args=(number,))

### Setting defaults.

It is possible to set options, like the target queue,

    from furious import context
    from furious.async import defaults

    @defaults(queue='square')
    def square_a_number(number):
        return number * number

    @defaults(queue='delayed_square', task_args={'countdown': 20})
    def delayed_square(number):
        return number * number

    # Instantiate a new Context.
    with context.new() as batch:

        for number in xrange(10):

            if number % 2:
                # At insert time, the task is added to the 'square' queue.
                batch.add(target="square_a_number", args=(number,))
            else:
                # At insert time, the task is added to the 'delayed_square'
                # queue with a 20 second countdown.
                batch.add(target="delayed_square", args=(number,))

Tasks targeted at the same queue will be batch inserted.

### Workflows via Contexts

*NOTE*: The `Context.on_complete` method is not yet fully implemented.

Contexts allow you to build workflows easily,

    from furious.async import Async
    from furious.context import get_current_context, new

    def square_a_number(number):
        return number ** number

    def sum_results():
        # Get the current context.
        context = get_current_context()

        # Get an iterator that will iterate over the results.
        results = context.get_results()

        # Do something with the results.
        return sum(result.payload for result in results)

    # Instantiate a new Context.
    with context.new() as batch:

        # Set a function to be called when all async jobs are complete.
        batch.on_complete(sum_results)

        for number in xrange(10):

            # Create a new Async object that will be added to the Context.
            batch.add(target="square_a_number", args=(number,))

### Workflows via nesting

Asyncs and Contexts maybe nested to build more complex workflows.

    from furious.async import Async
    from furious.context import new

    def do_some_work(number):
        if number > 1000:
            # We're done! Square once more, then return the number.
            return number * number

        # The number is not large enough yet!  Recurse!
        return Async(target="do_some_work", args=(number * number,))

    def all_done():
        from furious.context import get_current_async

        # Get the executing async.
        async = get_current_async()

        # Log the result.  This will actually be the result of the
        # number returned last.
        logging.info("Result is: %d", async.result)

    # Create an Async object.
    async = Async(
        target="do_some_work",
        args=(2,),
        callbacks={'success': all_done})

    # Tell the async to insert itself to be run.
    async.start()

This inserts a task that will keep recursing until the value is large enough,
then it will log the final value.  Nesting may be combined with Contexts to
build powerful fan-out / fan-in flows.

Working Examples
-----

For working examples see `examples/__init__.py`.  To use the examples, start
dev_appserver.py then step through the code and make a request to the
corresponding URLs.

repository: Workiva/furious

gha_language: Python

repo_name: Workiva/furious


text:
# AAC Code Challenge

A Javascript code challenge to fetch and render data from the [randomuser.me](https://randomuser.me/) API endpoint.

## 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

If changes are made to files in assets/js folder they will need to be concated and minified using Gulp. To do so you will need gulp-cli installed globally then just run the following npm script:
```
npm install gulp-cli -g
npm run gulp
```

### Installing

A npm script has been written to install all dependencies and start the server

```
npm run init
```

Once the project has already been init it can be started again with:

```
npm run start
```

## Built With

* [Node](https://nodejs.org)
* [Gulp](https://gulpjs.com/)

## Contributing

Please read [CONTRIBUTING.md](https://gist.github.com/PurpleBooth/b24679402957c63ec426) for details on our code of conduct, and the process for submitting pull requests to us.

## Authors

* **Kevin Ullyott** - [Orrison](https://github.com/Orrison)

## License

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

license: ISC

repository: Orrison/aac-coding-challenge

repo_name: Orrison/aac-coding-challenge


text:
# pulse-divider
*Simple pulse divider for irrigation flow meter*

[![Build](https://img.shields.io/travis/claybar/pulse-divider/master.svg)](https://travis-ci.org/claybar/pulse-divider)
[![Issues](https://img.shields.io/github/issues/claybar/pulse-divider/.svg)](https://github.com/claybar/pulse-divider/issues)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT)

---
A simple pulse rate reducer to interface a high pulse-rate irrigation flow meter with a controller.  Developed for use with a 0-120 l/m Q4.5 water meter and an [OpenSprinkler irrigation controller](opensprinkler.com).

## Hardware

Developed and tested using a [DigiSpark](http://digistump.com/products/1) clone based on an ATTiny85.

The Opensprinler controller is primarilly designed for 2-wire dry-contact flow sensors but since the pulse IO is simply a GPIO input it can be driven with a 5V logic-level pulse train.  From the [2.1.7 user manual](https://openthings.freshdesk.com/support/solutions/articles/5000716364-user-manual-firmware-2-1-7-current-)
> Flow sensors with 3 wires and runs on 5V can also be used with OpenSprinkler. In this case,
insert the black wire (ground) to the right pin of the sensor terminal, data wire to the left pin of the sensor terminal, and
solder the red wire (5V) to the VIN pin on the circuit board.

## Interfacing

DigiSpark IO | Usage
------------ | ----------
P?           | Ground
P?           | +5V supply
P?           | Pulse in
P?           | Pulse out

## Maths

Calculating the reduction factor requries a bit of maths.  Starting with:

Pulse Meter
* 0-120 l/m
* Q = 4.5

Opensprinkler controller
* Maximum pulse rate 200 p/s ([see Rays comment](https://opensprinkler.com/forums/topic/3-wire-flow-sensor/#post-41339))
* Liters per pulse accuracy, 2 decimal places

At maximum flow rate the meter will produce a pulse frequency of `f = 120 * 4.5 = 540 Hz` which is in excess of the permitteed maximum of `200 p/s`.   The minimum pulse division is therefore `540/200 = 2.7`.  Non-integer division is more tricky to implement, so a candidate divisor of 10 would be suitable.  Checking this against the pulse measurement accuracy of the controller (2 dp) gives a volume per pulse of:
```
120 l / 60 s = 2 l/s
540 p/s / 27 = 20 p/s
2 l/s / 20 p/s = 0.1 l/p
```
This seems to fit well with th restrictions of OpenSprinkler, 10x under the maximum pulse rate and only requiring 1 decimal place of accuracy for the pulse volume.

repository: claybar/pulse-divider

repo_name: claybar/pulse-divider


text:
# poker
Poker game evaluation program written in Python 3.7.

This program takes a string of cards in the form:

4h 9s tc jd qs kc ah

in either uppercase or lowercase, with the cards for each hand separated
by a newline character. The strings are stored in the program source code
at the bottom of the game.py file.

The code handles straights with an ace.

repository: cmdoffing/poker

repo_name: cmdoffing/poker