text:
Split is a rack based ab testing framework designed to work with Rails, Sinatra or any other rack based app.

Split is heavily inspired by the Abingo and Vanity rails ab testing plugins and Resque in its use of Redis.

Split is designed to be hacker friendly, allowing for maximum customisation and extensibility.

[![Gem Version](https://badge.fury.io/rb/split.svg)](http://badge.fury.io/rb/split)
[![Build Status](https://secure.travis-ci.org/splitrb/split.svg?branch=master)](http://travis-ci.org/splitrb/split)
[![Dependency Status](https://gemnasium.com/splitrb/split.svg)](https://gemnasium.com/splitrb/split)
[![Code Climate](https://codeclimate.com/github/splitrb/split.svg)](https://codeclimate.com/github/splitrb/split)
[![Coverage Status](http://img.shields.io/coveralls/splitrb/split.svg)](https://coveralls.io/r/splitrb/split)

## Requirements

Split currently requires Ruby 1.9.2 or higher. If your project requires compatibility with Ruby 1.8.x and Rails 2.3, please use v0.8.0.

Split uses redis as a datastore.

Split only supports redis 2.0 or greater.

If you're on OS X, Homebrew is the simplest way to install Redis:

```bash
brew install redis
redis-server /usr/local/etc/redis.conf
```

You now have a Redis daemon running on 6379.

## Setup

```bash
gem install split
```

### Rails

Adding `gem 'split'` to your Gemfile will autoloaded it when rails starts up, as long as you've configured redis it will 'just work'.

### Sinatra

To configure sinatra with Split you need to enable sessions and mix in the helper methods. Add the following lines at the top of your sinatra app:

```ruby
require 'split'

class MySinatraApp < Sinatra::Base
  enable :sessions
  helpers Split::Helper

  get '/' do
  ...
end
```

## Usage

To begin your ab test use the `ab_test` method, naming your experiment with the first argument and then the different alternatives which you wish to test on as the other arguments.

`ab_test` returns one of the alternatives, if a user has already seen that test they will get the same alternative as before, which you can use to split your code on.

It can be used to render different templates, show different text or any other case based logic.

`finished` is used to make a completion of an experiment, or conversion.

Example: View

```erb
<% ab_test(:login_button, "/images/button1.jpg", "/images/button2.jpg") do |button_file| %>
  <%= image_tag(button_file, alt: "Login!") %>
<% end %>
```

Example: Controller

```ruby
def register_new_user
  # See what level of free points maximizes users' decision to buy replacement points.
  @starter_points = ab_test(:new_user_free_points, '100', '200', '300')
end
```

Example: Conversion tracking (in a controller!)

```ruby
def buy_new_points
  # some business logic
  finished(:new_user_free_points)
end
```

Example: Conversion tracking (in a view)

```erb
Thanks for signing up, dude! <% finished(:signup_page_redesign) %>
```

You can find more examples, tutorials and guides on the [wiki](https://github.com/splitrb/split/wiki).

## Statistical Validity

Split has two options for you to use to determine which alternative is the best.

The first option (default on the dashboard) uses a z test (n>30) for the difference between your control and alternative conversion rates to calculate statistical significance. This test will tell you whether an alternative is better or worse than your control, but it will not distinguish between which alternative is the best in an experiment with multiple alternatives. Split will only tell you if your experiment is 90%, 95%, or 99% significant, and this test only works if you have more than 30 participants and 5 conversions for each branch.

As per this [blog post](http://www.evanmiller.org/how-not-to-run-an-ab-test.html) on the pitfalls of A/B testing, it is highly recommended that you determine your requisite sample size for each branch before running the experiment. Otherwise, you'll have an increased rate of false positives (experiments which show a significant effect where really there is none).

[Here](http://www.evanmiller.org/ab-testing/sample-size.html) is a sample size calculator for your convenience.

The second option uses simulations from a beta distribution to determine the probability that the given alternative is the winner compared to all other alternatives. You can view these probabilities by clicking on the drop-down menu labeled "Confidence." This option should be used when the experiment has more than just 1 control and 1 alternative. It can also be used for a simple, 2-alternative A/B test.

## Extras

### Weighted alternatives

Perhaps you only want to show an alternative to 10% of your visitors because it is very experimental or not yet fully load tested.

To do this you can pass a weight with each alternative in the following ways:

```ruby
ab_test(:homepage_design, {'Old' => 18}, {'New' => 2})

ab_test(:homepage_design, 'Old', {'New' => 1.0/9})

ab_test(:homepage_design', {'Old' => 9}, 'New')
```

This will only show the new alternative to visitors 1 in 10 times, the default weight for an alternative is 1.

### Overriding alternatives

For development and testing, you may wish to force your app to always return an alternative.
You can do this by passing it as a parameter in the url.

If you have an experiment called `button_color` with alternatives called `red` and `blue` used on your homepage, a url such as:

    http://myawesomesite.com?button_color=red

will always have red buttons. This won't be stored in your session or count towards to results, unless you set the `store_override` configuration option.

In the event you want to disable all tests without having to know the individual experiment names, add a `SPLIT_DISABLE` query parameter.

    http://myawesomesite.com?SPLIT_DISABLE=true

It is not required to send `SPLIT_DISABLE=false` to activate Split.

### Starting experiments manually

By default new AB tests will be active right after deployment. In case you would like to start new test a while after
the deploy, you can do it by setting the `start_manually` configuration option to `true`.

After choosing this option tests won't be started right after deploy, but after pressing the `Start` button in Split admin dashboard.

### Reset after completion

When a user completes a test their session is reset so that they may start the test again in the future.

To stop this behaviour you can pass the following option to the `finished` method:

```ruby
finished(:experiment_name, reset: false)
```

The user will then always see the alternative they started with.

### Multiple experiments at once

By default Split will avoid users participating in multiple experiments at once. This means you are less likely to skew results by adding in more variation to your tests.

To stop this behaviour and allow users to participate in multiple experiments at once enable the `allow_multiple_experiments` config option like so:

```ruby
Split.configure do |config|
  config.allow_multiple_experiments = true
end
```

### Experiment Persistence

Split comes with three built-in persistence adapters for storing users and the alternatives they've been given for each experiment.

By default Split will store the tests for each user in the session.

You can optionally configure Split to use a cookie, Redis, or any custom adapter of your choosing.

#### Cookies

```ruby
Split.configure do |config|
  config.persistence = :cookie
end
```

__Note:__ Using cookies depends on `ActionDispatch::Cookies` or any identical API

#### Redis

Using Redis will allow ab_users to persist across sessions or machines.

```ruby
Split.configure do |config|
  config.persistence = Split::Persistence::RedisAdapter.with_config(lookup_by: -> (context) { context.current_user_id })
  # Equivalent
  # config.persistence = Split::Persistence::RedisAdapter.with_config(lookup_by: :current_user_id)
end
```

Options:
* `lookup_by`: method to invoke per request for uniquely identifying ab_users (mandatory configuration)
* `namespace`: separate namespace to store these persisted values (default "persistence")

#### Custom Adapter

Your custom adapter needs to implement the same API as existing adapters.
See `Split::Persistance::CookieAdapter` or `Split::Persistence::SessionAdapter` for a starting point.

```ruby
Split.configure do |config|
  config.persistence = YourCustomAdapterClass
end
```

### Trial Event Hooks

You can define methods that will be called at the same time as experiment
alternative participation and goal completion.

For example:

``` ruby
Split.configure do |config|
  config.on_trial_choose   = :log_trial_choose
  config.on_trial_complete = :log_trial_complete
end
```

Set these attributes to a method name available in the same context as the
`ab_test` method. These methods should accept one argument, a `Trial` instance.

``` ruby
def log_trial_choose(trial)
  logger.info "experiment=%s alternative=%s user=%s" %
    [ trial.experiment.name, trial.alternative, current_user.id ]
end

def log_trial_complete(trial)
  logger.info "experiment=%s alternative=%s user=%s complete=true" %
    [ trial.experiment.name, trial.alternative, current_user.id ]
end
```

#### Views

If you are running `ab_test` from a view, you must define your event
hook callback as a
[helper_method](http://apidock.com/rails/AbstractController/Helpers/ClassMethods/helper_method)
in the controller:

``` ruby
helper_method :log_trial_choose

def log_trial_choose(trial)
  logger.info "experiment=%s alternative=%s user=%s" %
    [ trial.experiment.name, trial.alternative, current_user.id ]
end
```

### Experiment Hooks

You can assign a proc that will be called when an experiment is reset or deleted. You can use these hooks to call methods within your application to keep data related to experiments in sync with Split.

For example:

``` ruby
Split.configure do |config|
  config.on_experiment_reset  = -> (example) { # Do something on reset }
  config.on_experiment_delete = -> (experiment) { # Do something else on delete }
end
```

## Web Interface

Split comes with a Sinatra-based front end to get an overview of how your experiments are doing.

If you are running Rails 2: You can mount this inside your app using Rack::URLMap in your `config.ru`

```ruby
require 'split/dashboard'

run Rack::URLMap.new \
  "/"       => Your::App.new,
  "/split" => Split::Dashboard.new
```

However, if you are using Rails 3: You can mount this inside your app routes by first adding this to the Gemfile:

```ruby
gem 'split', require: 'split/dashboard'
```

Then adding this to config/routes.rb

```ruby
mount Split::Dashboard, at: 'split'
```

You may want to password protect that page, you can do so with `Rack::Auth::Basic` (in your split initializer file)

```ruby
Split::Dashboard.use Rack::Auth::Basic do |username, password|
  username == 'admin' && password == 'p4s5w0rd'
end
```

You can even use Devise or any other Warden-based authentication method to authorize users. Just replace `mount Split::Dashboard, :at => 'split'` in `config/routes.rb` with the following:
```ruby
match "/split" => Split::Dashboard, anchor: false, via: [:get, :post, :delete], constraints: -> (request) do
  request.env['warden'].authenticated? # are we authenticated?
  request.env['warden'].authenticate! # authenticate if not already
  # or even check any other condition such as request.env['warden'].user.is_admin?
end
```

More information on this [here](http://steve.dynedge.co.uk/2011/12/09/controlling-access-to-routes-and-rack-apps-in-rails-3-with-devise-and-warden/)

### Screenshot

![split_screenshot](https://raw.githubusercontent.com/caser/caser.github.io/master/dashboard.png)

## Configuration

You can override the default configuration options of Split like so:

```ruby
Split.configure do |config|
  config.db_failover = true # handle redis errors gracefully
  config.db_failover_on_db_error = -> (error) { Rails.logger.error(error.message) }
  config.allow_multiple_experiments = true
  config.enabled = true
  config.persistence = Split::Persistence::SessionAdapter
  #config.start_manually = false ## new test will have to be started manually from the admin panel. default false
  config.include_rails_helper = true
  config.redis_url = "custom.redis.url:6380"
end
```

Split looks for the Redis host in the environment variable ```REDIS_URL``` then defaults to ```localhost:6379``` if not specified by configure block.

### Filtering

In most scenarios you don't want to have AB-Testing enabled for web spiders, robots or special groups of users.
Split provides functionality to filter this based on a predefined, extensible list of bots, IP-lists or custom exclude logic.

```ruby
Split.configure do |config|
  # bot config
  config.robot_regex = /my_custom_robot_regex/ # or
  config.bots['newbot'] = "Description for bot with 'newbot' user agent, which will be added to config.robot_regex for exclusion"

  # IP config
  config.ignore_ip_addresses << '81.19.48.130' # or regex: /81\.19\.48\.[0-9]+/

  # or provide your own filter functionality, the default is proc{ |request| is_robot? || is_ignored_ip_address? }
  config.ignore_filter = -> (request) { CustomExcludeLogic.excludes?(request) }
end
```

### Experiment configuration

Instead of providing the experiment options inline, you can store them
in a hash. This hash can control your experiment's alternatives, weights,
algorithm and if the experiment resets once finished:

```ruby
Split.configure do |config|
  config.experiments = {
    my_first_experiment: {
      alternatives: ["a", "b"],
      resettable: false
    },
    :my_second_experiment => {
      algorithm: 'Split::Algorithms::Whiplash',
      alternatives: [
        { name: "a", percent: 67 },
        { name: "b", percent: 33 }
      ]
    }
  }
end
```

You can also store your experiments in a YAML file:

```ruby
Split.configure do |config|
  config.experiments = YAML.load_file "config/experiments.yml"
end
```

You can then define the YAML file like:

```yaml
my_first_experiment:
  alternatives:
    - a
    - b
my_second_experiment:
  alternatives:
    - name: a
      percent: 67
    - name: b
      percent: 33
  resettable: false
```

This simplifies the calls from your code:

```ruby
ab_test(:my_first_experiment)
```

and:

```ruby
finished(:my_first_experiment)
```

You can also add meta data for each experiment, very useful when you need more than an alternative name to change behaviour:

```ruby
Split.configure do |config|
  config.experiments = {
    my_first_experiment: {
      alternatives: ["a", "b"],
      metadata: {
        "a" => {"text" => "Have a fantastic day"},
        "b" => {"text" => "Don't get hit by a bus"},
      }
    },
  }
end
```

```yaml
my_first_experiment:
  alternatives:
    - a
    - b
  metadata:
    a:
      text: "Have a fantastic day"
    b:
      text: "Don't get hit by a bus"
```

This allows for some advanced experiment configuration using methods like:

```ruby
trial.alternative.name # => "a"

trial.metadata['text'] # => "Have a fantastic day"
```

or in views:

```erb
<% ab_test("my_first_experiment") do |alternative, meta| %>
  <%= alternative %>
  <small><%= meta['text'] %></small>
<% end %>
```

#### Metrics

You might wish to track generic metrics, such as conversions, and use
those to complete multiple different experiments without adding more to
your code. You can use the configuration hash to do this, thanks to
the `:metric` option.

```ruby
Split.configure do |config|
  config.experiments = {
    my_first_experiment: {
      alternatives: ["a", "b"],
      metric: :my_metric,
    }
  }
end
```

Your code may then track a completion using the metric instead of
the experiment name:

```ruby
finished(:my_metric)
```

You can also create a new metric by instantiating and saving a new Metric object.

```ruby
Split::Metric.new(:my_metric)
Split::Metric.save
```

#### Goals

You might wish to allow an experiment to have multiple, distinguishable goals.
The API to define goals for an experiment is this:

```ruby
ab_test({link_color: ["purchase", "refund"]}, "red", "blue")
```

or you can you can define them in a configuration file:

```ruby
Split.configure do |config|
  config.experiments = {
    link_color: {
      alternatives: ["red", "blue"],
      goals: ["purchase", "refund"]
    }
  }
end
```

To complete a goal conversion, you do it like:

```ruby
finished(link_color: "purchase")
```

**NOTE:** This does not mean that a single experiment can have/complete progressive goals.

**Good Example**: Test if listing Plan A first result in more conversions to Plan A (goal: "plana_conversion") or Plan B (goal: "planb_conversion").

**Bad Example**: Test if button color increases conversion rate through multiple steps of a funnel. THIS WILL NOT WORK.

### DB failover solution

Due to the fact that Redis has no automatic failover mechanism, it's
possible to switch on the `db_failover` config option, so that `ab_test`
and `finished` will not crash in case of a db failure. `ab_test` always
delivers alternative A (the first one) in that case.

It's also possible to set a `db_failover_on_db_error` callback (proc)
for example to log these errors via Rails.logger.

### Redis

You may want to change the Redis host and port Split connects to, or
set various other options at startup.

Split has a `redis` setter which can be given a string or a Redis
object. This means if you're already using Redis in your app, Split
can re-use the existing connection.

String: `Split.redis = 'localhost:6379'`

Redis: `Split.redis = $redis`

For our rails app we have a `config/initializers/split.rb` file where
we load `config/split.yml` by hand and set the Redis information
appropriately.

Here's our `config/split.yml`:

```yml
development: localhost:6379
test: localhost:6379
staging: redis1.example.com:6379
fi: localhost:6379
production: redis1.example.com:6379
```

And our initializer:

```ruby
split_config = YAML.load_file(Rails.root.join('config', 'split.yml'))
Split.redis = split_config[Rails.env]
```

## Namespaces

If you're running multiple, separate instances of Split you may want
to namespace the keyspaces so they do not overlap. This is not unlike
the approach taken by many memcached clients.

This feature is provided by the [redis-namespace](https://github.com/defunkt/redis-namespace) library, which
Split uses by default to separate the keys it manages from other keys
in your Redis server.

Simply use the `Split.redis.namespace` accessor:

```ruby
Split.redis.namespace = "split:blog"
```

We recommend sticking this in your initializer somewhere after Redis
is configured.

## Outside of a Web Session

Split provides the Helper module to facilitate running experiments inside web sessions.

Alternatively, you can access the underlying Metric, Trial, Experiment and Alternative objects to
conduct experiments that are not tied to a web session.

```ruby
# create a new experiment
experiment = Split::ExperimentCatalog.find_or_create('color', 'red', 'blue')
# create a new trial
trial = Split::Trial.new(:experiment => experiment)
# run trial
trial.choose!
# get the result, returns either red or blue
trial.alternative.name

# if the goal has been achieved, increment the successful completions for this alternative.
if goal_acheived?
  trial.complete!
end

```

## Algorithms

By default, Split ships with `Split::Algorithms::WeightedSample` that randomly selects from possible alternatives for a traditional a/b test.
It is possible to specify static weights to favor certain alternatives.

`Split::Algorithms::Whiplash` is an implementation of a [multi-armed bandit algorithm](http://stevehanov.ca/blog/index.php?id=132).
This algorithm will automatically weight the alternatives based on their relative performance,
choosing the better-performing ones more often as trials are completed.

Users may also write their own algorithms. The default algorithm may be specified globally in the configuration file, or on a per experiment basis using the experiments hash of the configuration file.

To change the algorithm globally for all experiments, use the following in your initializer:

```ruby
Split.configure do |config|
  config.algorithm = Split::Algorithms::Whiplash
end
```

## Extensions

  - [Split::Export](http://github.com/splitrb/split-export) - easily export ab test data out of Split
  - [Split::Analytics](http://github.com/splitrb/split-analytics) - push test data to google analytics
  - [Split::Mongoid](https://github.com/MongoHQ/split-mongoid) - store experiment data in mongoid (still uses redis)
  - [Split::Cacheable](https://github.com/harrystech/split_cacheable) - automatically create cache buckets per test
  - [Split::Counters](https://github.com/bernardkroes/split-counters) - add counters per experiment and alternative

## Screencast

Ryan bates has produced an excellent 10 minute screencast about split on the Railscasts site: [A/B Testing with Split](http://railscasts.com/episodes/331-a-b-testing-with-split)

## Blogposts

* [A/B Testing with Split in Ruby on Rails](http://grinnick.com/posts/a-b-testing-with-split-in-ruby-on-rails)
* [Recipe: A/B testing with KISSMetrics and the split gem](http://robots.thoughtbot.com/post/9595887299/recipe-a-b-testing-with-kissmetrics-and-the-split-gem)
* [Rails A/B testing with Split on Heroku](http://blog.nathanhumbert.com/2012/02/rails-ab-testing-with-split-on-heroku.html)

## Contributors

Over 70 different people have contributed to the project, you can see them all here: https://github.com/splitrb/split/graphs/contributors

## Development

Source hosted at [GitHub](http://github.com/splitrb/split).
Report Issues/Feature requests on [GitHub Issues](http://github.com/splitrb/split/issues).
Discussion at [Google Groups](https://groups.google.com/d/forum/split-ruby)

Tests can be ran with `rake spec`

### Note on Patches/Pull Requests

 * Fork the project.
 * Make your feature addition or bug fix.
 * Add tests for it. This is important so I don't break it in a
   future version unintentionally.
 * Add documentation if necessary.
 * Commit, do not mess with rakefile, version, or history.
   (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
 * Send a pull request. Bonus points for topic branches.

## Copyright

Copyright (c) 2015 Andrew Nesbitt. See [LICENSE](https://github.com/splitrb/split/blob/master/LICENSE) for details.


text:
==========================
Version 0.25 Release Notes
==========================

**Release Date:** March 31, 2015

Release Summary
===============

The 0.25 release is primarily dedicated to :doc:`MOTECH Data Services <../get_started/model_data/model_data>` improvements, including MDS REST APIs and the ability to import entities to MDS via CSV file.

This release also features a new, simplified IVR module to replace the assorted IVR modules that were deprecated in 0.24.

Where to Get it
===============

**Source Code:** `Platform <https://code.google.com/p/motech/source/list?name=motech-0.25>`_ | `Modules <https://github.com/motech/modules/tree/modules-0.25>`_

**Binary Distribution**

`Platform WAR <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/motech-platform-server/0.25/motech-platform-server-0.25.war>`_

Modules:

* `Alerts <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/alerts/0.25/alerts-0.25.jar>`_
* `Appointments <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/appointments/0.25/appointments-0.25.jar>`_
* `Batch <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/batch/0.25/batch-0.25.jar>`_
* `CMS Lite <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/cms-lite/0.25/cms-lite-0.25.jar>`_
* `CommCare <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/commcare/0.25/commcare-0.25.jar>`_
* `Event Logging <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/event-logging/0.25/event-logging-0.25.jar>`_
* `Hindi Transliteration <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/hindi-transliteration/0.25/hindi-transliteration-0.25.jar>`_
* `HTTP Agent <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/http-agent/0.25/http-agent-0.25.jar>`_
* `Hub <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/hub/0.25/hub-0.25.jar>`_
* `IVR <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/ivr/0.25/ivr-0.25.jar>`_
* `Message Campaign <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/message-campaign/0.25/message-campaign-0.25.jar>`_
* `mTraining <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/mtraining/0.25/mtraining-0.25.jar>`_
* `OpenMRS 1.9 <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/openmrs-19/0.25/openmrs-19-0.25.jar>`_
* `Pill Reminder <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/pill-reminder/0.25/pill-reminder-0.25.jar>`_
* `Schedule Tracking <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/schedule-tracking/0.25/schedule-tracking-0.25.jar>`_
* `SMS <http://nexus.motechproject.org/content/repositories/releases/org/motechproject/sms/0.25/sms-0.25.jar>`_

Major Changes
=============

CSV Import of MDS Entities
--------------------------

It is now possible to bulk import MDS entity data in CSV format. See the :doc:`bulk upload tutorial <../demos/mds_csv_import/mds_csv_import_demo>` for more information.

MDS REST API Generation
-----------------------

MDS CRUD Events
---------------

Other MDS Improvements
----------------------

* Two-way relationships

New IVR Module
--------------

WAR File Changes
----------------

CouchDB Removal
---------------

Support for CouchDB, which was deprecated in version 0.24, has been completely removed in version 0.25. As part of the removal process, the development team extensively tested MDS performance to ensure that the migration to MDS had not introduced performance regressions in MOTECH modules.

Tickets
=======

You can browse the list of tickets resolved for this release on our `issue tracker <https://applab.atlassian.net/issues/?jql=fixVersion%20%3D%200.25%20AND%20project%20%3D%20MOTECH>`_.

redpajama_set_name: RedPajamaGithub


text:
THIS=$(shell basename `pwd` .tproj)

install:: obj all

all obj installhdrs installsrc clean ${THIS} install::
	env MAKEOBJDIRPREFIX=${OBJROOT} bsdmake COPTS="-Os -mdynamic-no-pic" ARCH_FLAGS="${RC_CFLAGS}" NO_MANCOMPRESS=true DESTDIR=${DSTROOT} -f BSDmakefile $@

install::
	perl mksymroot ${DSTROOT} ${SYMROOT} ${OBJROOT}


text:
package co.cdev.agave.template;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.servlet.jsp.JspException;

/**
 * Inserts a fragment of content into a templated page.  A JSP is intended to
 * have one or multiple {@code <template:use />} tags so that the fragments can
 * be pulled from the request and injected into the page.
 *
 * @author damian
 */
public class UseFragmentTag extends TemplateTag {

	private static final long serialVersionUID = 1L;
	private String name;
    private boolean required = false;
    private int indent = 0;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public boolean isRequired() {
        return required;
    }

    public void setRequired(boolean required) {
        this.required = required;
    }

    public int getIndent() {
        return indent;
    }

    public void setIndent(int indent) {
        this.indent = indent;
    }

    /**
     * Inserts the named JSP fragment after the tag has finished processing.
     *
     * @return the constant to continue with page evaluation
     * @throws javax.servlet.jsp.JspException
     */
    @Override
    public int doEndTag() throws JspException {
        super.doEndTag();

        String fragment = null;

        Map<String, String> templateFragments = getCurrentFragmentMap();
        if (templateFragments != null && templateFragments.containsKey(name)) {
            fragment = templateFragments.get(name);

            if (fragment == null) {
                // in the event that a supplied fragment has not been provide
                // render the content of the use tag, if any
                fragment = bodyContent.getString();
            } else {
                // otherwise use the supplied fragment, and work with the
                // indentation, so that it's pretty-printed
                fragment = indent(fragment, indent);
            }
        } else {
            // try in the global section of additive fragments
            Map<String, List<String>> globalFragmentMap = getGlobalFragmentMap();
            if (globalFragmentMap.containsKey(name)) {
                StringBuilder compoundFragment = new StringBuilder();
                for (String additiveFragment : globalFragmentMap.get(name)) {
                    compoundFragment.append(additiveFragment);
                }
                fragment = indent(compoundFragment.toString(), indent);
            }
        }
        try {
            pageContext.getOut().write(fragment);
        } catch (IOException ex) {
            throw new JspException(ex);
        }

        this.release();
        return EVAL_PAGE;
    }

}


text:
Dir[File.join(File.dirname(__FILE__),'goodies','*.rb')].each do |file|
  require file
end


text:
gorc::game::world::events::landed::landed(thing_id thing)
    : thing(thing) {
    return;
}


text:
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
    <stroke
        android:width="1dp"
        android:color="@color/gray_background" />

    <solid android:color="@color/gray_background" />

    <padding
        android:left="1dp"
        android:right="1dp"
        android:top="1dp" />

    <corners android:radius="5dp" />

</shape>


text:
VINet is a Web App, designed to connect those isolating as a result of CoViD-19 with volunteers. The aim of the app is to allow isolates to request help from volunteers, for tasks the isolate cannot complete due to the restrictions on movement during the CoViD-19 pandemic. These tasks could include going to the shops for some groceries, collecting a package from the couriers and so on.

## Core Features

The core features of the VInet Web App include:

- User Authentication
- Isolate Issue Tracking
- Volunteer Availability Tracking
- Isolate / Volunteer Matching

### User Authentication

User Authentication for the VInet Web App is done via the App Engine UserService API.

This allows people to log in with their Google accounts, providing a seamless experience for users.

All ingress / egress points have user authentication, ensuring that user data is safe and secure on the app's backend.

### Isolate Issue Tracking

To allow isolates to request help from volunteers, we implemented a ticketing system, allowing isolates to send in requests that they would like fulfilled.

The ticketing system's UI is displayed below ![screenshot of the request ticketing UI](screenshots/request_ticket_ui.png)

As can be seen from the above example, an isolate's request contains a variable number of tickets, and these tickets allow an isolate to describe what sort of help they need, such as help with grocery shopping.

### Volunteer Availability Tracking

To allow volunteers to input their availability in regards to fulfilling requests, we implemented an availability tracking system, which allows volunteers to indicate at what time and on which days they are available.

The availability tracking system's UI is displayed below ![screenshot of the availability tracking UI](screenshots/volunteer_availability_tracking_ui.png)

### Isolate / Volunteer Matching

To match isolates with volunteers, VInet uses the [Hopcroft-Karp bipartite matching algorithm](https://en.wikipedia.org/wiki/Hopcroft%E2%80%93Karp_algorithm). This algorithm produces a maximum cardinality matching, which is to say, the algorithm ensures that the number of isolates helped is as large as possible.

Matching is run as a cron job each evening at 8pm. This was determined as the ideal time to run the matching algorithm, as it would allow for the matching algorithm to run to completion overnight, and for users to be notified of the matchings produced on the following morning.

Once the algorithm has run, the matches found are accessible to both volunteers and isolates in a table as below.

![screenshot of matches UI](screenshots/matches.png)

## Getting Started

### Prerequisites

In order to build and/or run this project, you will need:

1. [Git](https://git-scm.com/)
2. [Apache Maven](https://maven.apache.org/)

### Building Locally

The first thing you will need to do is `git clone` this repo using one of the following commands:

HTTPS:

```bash
git clone https://github.com/googleinterns/step226-2020.git
```

SSH:

```bash
git clone git@github.com:googleinterns/step226-2020.git
```

GitHub CLI:

```bash
gh repo clone googleinterns/step226-2020
```

Now that you have the project available locally you can either:

- Run the tests for this project.
- Run the project locally on a development server.
- Deploy the project to Google's App Engine.

#### Running Tests

To run the tests for this project, run the following command from the terminal:

```bash
mvn test
```

The first time you run this command, it might take a few minutes to fetch all of the project dependencies - this is normal.

#### Running the project locally on a development server

To run this project locally on a development server, run the following command from the terminal:

```bash
mvn package appengine:run
```

Once the development server has started, the project will be available at <localhost:8080>.

Note: The development server will not hot-reload files. If you wish to make and test changes, you must reload the development server.

#### Deploying the Project to App Engine

To deploy this project to App Engine, you will need to enable to [App Engine](cloud.google.com/appengine) service from the [google cloud console](console.cloud.google.com).

Once you have done so, copy the [project id](cloud.google.com/resource-manager/docs/creating-managing-projects#identifying_projects) of your google cloud console project.

Navigate into this project's root directory, and edit the `pom.xml` file. You will need to change the following entry in the `<plugins>` section:

```xml
<plugin>
  <groupId>com.google.cloud.tools</groupId>
  <artifactId>appengine-maven-plugin</artifactId>
  <version>2.2.0</version>
  <configuration>
    <deploy.projectId>YOUR_PROJECT_ID</deploy.projectId>
    <deploy.version>1</deploy.version>
  </configuration>
</plugin>
```

Under `<configuration>`, change the `<deploy.projectId>` tag to contain **your google cloud project's id**.

Once this has been configured, run the following command:

```bash
mvn package appengine:deploy
```

The project will be deployed, and will be visible under the App Engine dashboard.


text:
package org.locationtech.geogig.api.porcelain;

import static com.google.common.base.Preconditions.checkState;

import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.jdt.annotation.Nullable;
import org.locationtech.geogig.api.AbstractGeoGigOp;
import org.locationtech.geogig.api.CommitBuilder;
import org.locationtech.geogig.api.ObjectId;
import org.locationtech.geogig.api.Platform;
import org.locationtech.geogig.api.Ref;
import org.locationtech.geogig.api.RevCommit;
import org.locationtech.geogig.api.SymRef;
import org.locationtech.geogig.api.plumbing.FindCommonAncestor;
import org.locationtech.geogig.api.plumbing.ForEachRef;
import org.locationtech.geogig.api.plumbing.RefParse;
import org.locationtech.geogig.api.plumbing.UpdateRef;
import org.locationtech.geogig.api.plumbing.UpdateSymRef;
import org.locationtech.geogig.api.porcelain.ResetOp.ResetMode;
import org.locationtech.geogig.repository.Repository;
import org.locationtech.geogig.storage.GraphDatabase;

import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.common.base.Suppliers;
import com.google.common.collect.Collections2;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * Operation to squash commits into one.
 */
public class SquashOp extends AbstractGeoGigOp<ObjectId> {

    private RevCommit since;

    private RevCommit until;

    private String message;

    /**
     * Indicates the first commit to squash. If no message is provided, the message from this commit
     * will be used
     *
     * @param the first (oldest) commit to squash
     * @return {@code this}
     */
    public SquashOp setSince(final RevCommit since) {
        this.since = since;
        return this;
    }

    /**
     * Indicates the last commit to squash
     *
     * @param the last (most recent) commit to squash
     * @return {@code this}
     */
    public SquashOp setUntil(RevCommit until) {
        this.until = until;
        return this;
    }

    /**
     * Indicates the message to use for the commit. If null, the message from the 'since' commit
     * will be used
     *
     * @param the message to use for the commit
     * @return {@code this}
     */
    public SquashOp setMessage(String message) {
        this.message = message;
        return this;
    }

    /**
     * Executes the squash operation.
     *
     * @return the new head after modifying the history squashing commits
     * @see org.locationtech.geogig.api.AbstractGeoGigOp#call()
     */
    @Override
    protected ObjectId _call() {

        Preconditions.checkNotNull(since);
        Preconditions.checkNotNull(until);

        GraphDatabase graphDb = graphDatabase();
        Repository repository = repository();
        Platform platform = platform();

        final Optional<Ref> currHead = command(RefParse.class).setName(Ref.HEAD).call();
        Preconditions.checkState(currHead.isPresent(), "Repository has no HEAD, can't squash.");
        Preconditions.checkState(currHead.get() instanceof SymRef,
                "Can't squash from detached HEAD");
        final SymRef headRef = (SymRef) currHead.get();
        final String currentBranch = headRef.getTarget();

        Preconditions.checkState(index().isClean() && workingTree().isClean(),
                "You must have a clean working tree and index to perform a squash.");

        Optional<ObjectId> ancestor = command(FindCommonAncestor.class).setLeft(since)
                .setRight(until).call();
        Preconditions.checkArgument(ancestor.isPresent(),
                "'since' and 'until' command do not have a common ancestor");
        Preconditions.checkArgument(ancestor.get().equals(since.getId()),
                "Commits provided in wrong order");

        Preconditions.checkArgument(!since.getParentIds().isEmpty(),
                "'since' commit has no parents");

        // we get a a list of commits to apply on top of the squashed commits
        List<RevCommit> commits = getCommitsAfterUntil();

        ImmutableSet<Ref> refs = command(ForEachRef.class).setPrefixFilter(Ref.HEADS_PREFIX).call();

        // we create a list of all parents of those squashed commits, in case they are
        // merge commits. The resulting commit will have all these parents
        //
        // While iterating the set of commits to squash, we check that there are no branch starting
        // points among them. Any commit with more than one child causes an exception to be thrown,
        // since the squash operation does not support squashing those commits

        Iterator<RevCommit> toSquash = command(LogOp.class).setSince(since.getParentIds().get(0))
                .setUntil(until.getId()).setFirstParentOnly(true).call();
        List<ObjectId> firstParents = Lists.newArrayList();
        List<ObjectId> secondaryParents = Lists.newArrayList();
        final List<ObjectId> squashedIds = Lists.newArrayList();
        RevCommit commitToSquash = until;
        while (toSquash.hasNext()) {
            commitToSquash = toSquash.next();
            squashedIds.add(commitToSquash.getId());
            Preconditions
                    .checkArgument(
                            graphDb.getChildren(commitToSquash.getId()).size() < 2,
                            "The commits to squash include a branch starting point. Squashing that type of commit is not supported.");
            for (Ref ref : refs) {
                // In case a branch has been created but no commit has been made on it and the
                // starting commit has just one child
                Preconditions
                        .checkArgument(
                                !ref.getObjectId().equals(commitToSquash.getId())
                                        || ref.getObjectId().equals(currHead.get().getObjectId())
                                        || commitToSquash.getParentIds().size() > 1,
                                "The commits to squash include a branch starting point. Squashing that type of commit is not supported.");
            }
            ImmutableList<ObjectId> parentIds = commitToSquash.getParentIds();
            for (int i = 1; i < parentIds.size(); i++) {
                secondaryParents.add(parentIds.get(i));
            }
            firstParents.add(parentIds.get(0));
        }
        Preconditions.checkArgument(since.equals(commitToSquash),
                "Cannot reach 'since' from 'until' commit through first parentage");

        // We do the same check in the children commits
        for (RevCommit commit : commits) {
            Preconditions
                    .checkArgument(
                            graphDb.getChildren(commit.getId()).size() < 2,
                            "The commits after the ones to squash include a branch starting point. This scenario is not supported.");
            for (Ref ref : refs) {
                // In case a branch has been created but no commit has been made on it
                Preconditions
                        .checkArgument(
                                !ref.getObjectId().equals(commit.getId())
                                        || ref.getObjectId().equals(currHead.get().getObjectId())
                                        || commit.getParentIds().size() > 1,
                                "The commits after the ones to squash include a branch starting point. This scenario is not supported.");
            }
        }

        ObjectId newHead;
        // rewind the head
        newHead = since.getParentIds().get(0);
        command(ResetOp.class).setCommit(Suppliers.ofInstance(newHead)).setMode(ResetMode.HARD)
                .call();

        // add the current HEAD as first parent of the resulting commit
        // parents.add(0, newHead);

        // Create new commit
        List<ObjectId> parents = Lists.newArrayList();
        parents.addAll(firstParents);
        parents.addAll(secondaryParents);
        ObjectId endTree = until.getTreeId();
        CommitBuilder builder = new CommitBuilder(until);
        Collection<ObjectId> filteredParents = Collections2.filter(parents,
                new Predicate<ObjectId>() {
                    @Override
                    public boolean apply(@Nullable ObjectId id) {
                        return !squashedIds.contains(id);
                    }

                });

        builder.setParentIds(Lists.newArrayList(filteredParents));
        builder.setTreeId(endTree);
        if (message == null) {
            message = since.getMessage();
        }
        long timestamp = platform.currentTimeMillis();
        builder.setMessage(message);
        builder.setCommitter(resolveCommitter());
        builder.setCommitterEmail(resolveCommitterEmail());
        builder.setCommitterTimestamp(timestamp);
        builder.setCommitterTimeZoneOffset(platform.timeZoneOffset(timestamp));
        builder.setAuthorTimestamp(until.getAuthor().getTimestamp());

        RevCommit newCommit = builder.build();
        repository.objectDatabase().put(newCommit);

        newHead = newCommit.getId();
        ObjectId newTreeId = newCommit.getTreeId();

        command(UpdateRef.class).setName(currentBranch).setNewValue(newHead).call();
        command(UpdateSymRef.class).setName(Ref.HEAD).setNewValue(currentBranch).call();

        workingTree().updateWorkHead(newTreeId);
        index().updateStageHead(newTreeId);

        // now put the other commits after the squashed one
        newHead = addCommits(commits, currentBranch, newHead);

        return newHead;

    }

    private ObjectId addCommits(List<RevCommit> commits, String currentBranch,
            final ObjectId squashedId) {

        final Platform platform = platform();
        final Map<ObjectId, ObjectId> replacedCommits = Maps.newHashMap();
        replacedCommits.put(until.getId(), squashedId);
        ObjectId head = squashedId;
        for (RevCommit commit : commits) {
            CommitBuilder builder = new CommitBuilder(commit);
            Collection<ObjectId> parents = Collections2.transform(commit.getParentIds(),
                    new Function<ObjectId, ObjectId>() {
                        @Override
                        @Nullable
                        public ObjectId apply(@Nullable ObjectId id) {
                            if (replacedCommits.containsKey(id)) {
                                return replacedCommits.get(id);
                            } else {
                                return id;
                            }
                        }
                    });
            builder.setParentIds(Lists.newArrayList(parents));
            builder.setTreeId(commit.getTreeId());
            long timestamp = platform.currentTimeMillis();
            builder.setCommitterTimestamp(timestamp);
            builder.setCommitterTimeZoneOffset(platform.timeZoneOffset(timestamp));

            RevCommit newCommit = builder.build();
            replacedCommits.put(commit.getId(), newCommit.getId());
            objectDatabase().put(newCommit);
            head = newCommit.getId();
            ObjectId newTreeId = newCommit.getTreeId();

            command(UpdateRef.class).setName(currentBranch).setNewValue(head).call();
            command(UpdateSymRef.class).setName(Ref.HEAD).setNewValue(currentBranch).call();

            workingTree().updateWorkHead(newTreeId);
            index().updateStageHead(newTreeId);
        }

        return head;
    }

    private List<RevCommit> getCommitsAfterUntil() {
        Iterator<RevCommit> commitIterator = command(LogOp.class).setSince(until.getId()).call();
        List<RevCommit> commits = Lists.newArrayList(commitIterator);
        Collections.reverse(commits);
        return commits;
    }

    private String resolveCommitter() {
        final String key = "user.name";
        Optional<String> name = command(ConfigGet.class).setName(key).call();

        checkState(
                name.isPresent(),
                "%s not found in config. Use geogig config [--global] %s <your name> to configure it.",
                key, key);

        return name.get();
    }

    private String resolveCommitterEmail() {
        final String key = "user.email";
        Optional<String> email = command(ConfigGet.class).setName(key).call();

        checkState(
                email.isPresent(),
                "%s not found in config. Use geogig config [--global] %s <your email> to configure it.",
                key, key);

        return email.get();
    }

}


text:
define([
        "dojo/_base/declare",
        "dojo/_base/lang",
        "dojo/dom-class",

        "geta-epi-imageshop/widgets/_ImageSelector",

        "epi/epi",
        'dojo/text!./templates/ImageSelector.html',

        'xstyle/css!./templates/ImageSelector.css'
],
    function (
        declare,
        lang,
        domClass,

        _ImageSelector,

        epi,
        template
    ) {

        return declare("geta-epi-imageshop/widgets/ImageSelector", [_ImageSelector], {
            //
            // Public
            //

            baseClass: "imageExt",
            store: null,
            templateString: template,
            value: null,

            //
            // Life cycle
            //

            postCreate: function () {
                this.inherited(arguments);
                this.showHideAddButton(this.value);

                if (this.isVideo) {
                    domClass.add(this.noImageNode, 'isVideo');
                }
            },

            postMixInProperties: function () {
                this.inherited(arguments);
            },

            //
            // Public methods
            //

            clearProperty: function (evt) {
                this._setValue(null);
                this.currentImage = null;
                this.onFocus();
            },

            loadThumb: function (value) {
                if (value == null) {
                    this.thumbContainer.style.display = "none";
                    this.thumbImg.src = "";
                } else {
                    this.thumbContainer.style.display = "block";
                    this.thumbImg.src = this._getPreviewImageUrl(value);
                }
            },

            onImageSelected: function() {
                this.inherited(arguments);
                this._setValue(this.currentImage);
            },

            showHideAddButton: function (value) {
                if (value == null) {
                    this.noImageNode.style.display = "block";
                } else {
                    this.noImageNode.style.display = "none";
                }
            },

            //
            // Private methods
            //

            _getPreviewImageUrl: function (image) {
                if (this.previewCropName) {
                    return image.url + "-" + this.previewCropName;
                }

                return image.url;
            },

            _setValueAttr: function (value) {
                this.currentImage = value;
                this._set("value", this.currentImage);
                this.loadThumb(value);
                this.showHideAddButton(value);
            },

            _setValue: function (value) {
                if (this._started && epi.areEqual(this.value, value)) {
                    return;
                }

                this._set("value", value);
                this.loadThumb(value);
                this.showHideAddButton(value);

                if (this._started && this.validate()) {
                    // Trigger change event
                    this.onChange(this.value);
                }
            }
        });
    });


text:
  <button
    aria-label="{{ processor.collapsed ? 'Expand Processor' : 'Collapse Processor' }}"
    tooltip="{{ processor.collapsed ? 'Expand Processor' : 'Collapse Processor' }}"
    tooltip-append-to-body="true"
    ng-click="processor.collapsed = !processor.collapsed"
    type="button"
    class="btn btn-primary btn-xs processor-ui-container-header-toggle">

  </button>

      {{processor.title}}

      - {{ processor.description }}

      - Error

    <button
      aria-label="Increase Priority"
      tooltip="Increase Priority"
      tooltip-append-to-body="true"
      ng-click="pipeline.moveUp(processor)"
      type="button"
      class="btn btn-xs btn-primary"
      ng-disabled="pipeline.hasCompileError">

    </button>

    <button
      aria-label="Decrease Priority"
      tooltip="Decrease Priority"
      tooltip-append-to-body="true"
      ng-click="pipeline.moveDown(processor)"
      type="button"
      class="btn btn-xs btn-primary"
      ng-disabled="pipeline.hasCompileError">

    </button>

    <button
      aria-label="Remove Processor"
      tooltip="Remove Processor"
      tooltip-append-to-body="true"
      ng-click="pipeline.remove(processor)"
      type="button"
      class="btn btn-xs btn-danger"
      ng-disabled="pipeline.hasCompileError && !processor.error">

    </button>


text:
//
//  MobFoxInterstitialAd.h
//  MobFoxSDKCore
//
//  Created by Shimi Sheetrit on 6/18/17.
//  Copyright © 2017 Matomy Media Group Ltd. All rights reserved.
//

#ifndef MobFoxInterstitialAd_h
#define MobFoxInterstitialAd_h

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>

//#import "MFWaterfallManager.h"
#import "MobFoxWebView.h"
#import "MobFoxCustomEvent.h"
#import "MobFoxInterstitialCustomEvent.h"
#import "MFLocationServicesManager.h"
#import "MobFoxInterstitialCustomEventRequest.h"

@class MobFoxInterstitialAd;

@protocol MobFoxInterstitialAdDelegate <NSObject>

@required

- (void)MobFoxInterstitialAdDidLoad:(MobFoxInterstitialAd *)interstitial;

@optional

- (void)MobFoxInterstitialAdDidFailToReceiveAdWithError:(NSError *)error;

- (void)MobFoxInterstitialAdWillShow:(MobFoxInterstitialAd *)interstitial;

- (void)MobFoxInterstitialAdDidShow:(MobFoxInterstitialAd *)interstitial;

- (void)MobFoxInterstitialAdClicked;

- (void)MobFoxInterstitialAdClosed;

- (void)MobFoxInterstitialAdFinished;

@end

@interface MobFoxInterstitialAd : NSObject <MobFoxWebViewAdDelegate,MobFoxInterstitialCustomEventRequestDelegate >

@property (nonatomic, weak) id <MobFoxInterstitialAdDelegate> delegate;
@property (nonatomic, weak) UIViewController* rootViewController;

@property (nonatomic, copy) NSString* longitude;
@property (nonatomic, copy) NSString* latitude;
@property (nonatomic, copy) NSString* demo_gender; //"m/f"
@property (nonatomic, copy) NSString* accuracy;
@property (nonatomic, copy) NSString* demo_age;
@property (nonatomic, copy) NSString* s_subid;
@property (nonatomic, copy) NSString* sub_name;
@property (nonatomic, copy) NSString* sub_domain;
@property (nonatomic, copy) NSString* sub_storeurl;
@property (nonatomic, copy) NSString* r_floor;
@property (nonatomic, strong) NSString* v_rewarded;

@property (nonatomic, strong) MFLocationServicesManager *locationServicesManager;

@property (nonatomic, assign) BOOL      gdpr;
@property (nonatomic, strong) NSString* gdpr_consent;

@property (nonatomic, copy) NSNumber* v_dur_min;
@property (nonatomic, copy) NSNumber* v_dur_max;
@property (nonatomic, assign) BOOL v_autoplay;
@property (nonatomic, assign) BOOL v_startmute;

@property (nonatomic, strong) NSString* invh;
//@property (nonatomic, strong) NSString *requestID;

@property (nonatomic, assign) BOOL c_mraid;
@property (nonatomic, assign) BOOL dev_js;
@property (nonatomic, assign) BOOL imp_secure;
@property (nonatomic, assign) BOOL ready;
@property (nonatomic, strong) NSNumber* refresh;
@property (nonatomic, copy) NSString* debugReqCustomEventURLStr;
@property (nonatomic, copy) NSString* debug_ad_request_url;

@property (nonatomic, strong) NSString* adapter;

@property (nonatomic, strong) NSNumber* cpm;

- (id) init:(NSString*)invh;
- (id) init:(NSString*)invh withRootViewController:(UIViewController*)root;
- (void) loadAd;
- (void) show;
- (void) dismissAd;

@end

#endif /* MobFoxInterstitialAd_h */


text:
GouvCamp Mobile
===============

GouvCamp mobile is an OpenSource [Appcelerator Titanium Mobile](www.appcelerator.com) application built by the guys at [JoliCode](http://jolicode.com/) in the occasion of the [first French GouvCamp](parlement-et-citoyens.fr) which will be held on tuesday, April 10th 2012.

Install and run
---------------

The project has been tested along with Titanium 1.8.2. Just grab the source:

    $ https://github.com/jolicode/GouvCamp-mobile.git

and import it in Titanium Studio. The application runs smoothly on both iOs and Android.

Architecture concepts
---------------------

The application tries to do the best use of the [CommonJS module pattern](http://www.commonjs.org/), and is divided in three layers - controllers, views and models. It has a dependancy to the ORM [joli.js](https://github.com/xavierlacot/joli.js).

The application fetches several json webservice endpoints, particularly the one of EventBrite, through a proxy called joli.api.js, which uses a local database as a caching engine.

We believe some developers could find interesting ideas in the code, so don't hesitate to go on and look at the source!

Demonstration
-------------

Would you like to test it, the application is available in both stores:

*   Google Play: https://play.google.com/store/apps/details?id=com.jolicode.gouvcamp2012
*   Apple Store: Application currently in review (aka. "we are crossing fingers")

**Share the love!**


text:
ACCEPTED

#### According to
The Catalogue of Life, 3rd January 2011

#### Published in
in Smith, Poot & Kull, Stud. Mycol. 31: 175 (1989)

#### Original name
Candida pseudolambica M.T. Sm. & Poot, 1989

### Remarks
null


text:
/**
 * Templates.
 */
package io.werval.api.templates;


text:
date: '2020-10-25 18:15:00 GMT-3'
image: '/files/2020/10/youtube-dl-takedown-en.jpg'
layout: post
published: true
nickname: 'youtube-dl-takedown'
title: 'Microsoft Disables GitHub Repository of Open Source Project youtube-dl'
excerpt: 'The open source project youtube-dl is one of the best tools to download videos from YouTube and many other video hosting websites. But the existence of this project is under threat right now. Recording Industry Association of America, Inc. (RIAA) sent a notice to GitHub against youtube-dl and its forked repositories on 23 Oct 2020.'
---

{% capture note1 %}
The following is a partial copy of the news originally written by Abhishek Prakash and published at [It's FOSS](https://itsfoss.com/youtube-dl-github-takedown/). The original news was made available under the [CC BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/) license.
{% endcapture %}

{% include note.html text=note1 %}

{% include image.html src='/files/2020/10/youtube-dl-takedown-en.jpg' %}

The open source project [youtube-dl is one of the best tools to download videos][youtube-dl] from YouTube and many other video hosting websites.

But the existence of this project is under threat right now. Recording Industry Association of America, Inc. (RIAA) sent a notice to GitHub against youtube-dl and its forked repositories on 23 Oct 2020.

Microsoft owned GitHub complied immediately and within 24 hours, the official youtube-dl and its forked repository were disabled as DMCA takedown.

{% include image.html src='/files/2020/10/youtube-dl-dmca.jpg' %}

[youtube-dl]: https://itsfoss.com/download-youtube-linux/

{% capture note2 %}
Did you get interested? Do you want to read the full text? Please continue on **It's FOSS**:

- [Microsoft Disables GitHub Repository of Open Source Project youtube-dl - It's FOSS](https://itsfoss.com/youtube-dl-github-takedown/)

I actually just wanted to translate this text into Brazilian Portuguese. I put this excerpt here just to point to the right text in case anyone reads [my translation]({% post_url pt/2020-10-25-microsoft-tira-do-ar-repositorio-github-do-projeto-de-codigo-aberto-youtube-dl %}) and clicks "This page in English".
{% endcapture %}

{% include note.html text=note2 %}


text:
@interface SDLFakeViewControllerPresenter ()

@property (assign, nonatomic, readwrite) BOOL presented;

@end

@implementation SDLFakeViewControllerPresenter

- (void)present {
    if (!self.viewController) { return; }

    _presented = YES;
}

- (void)dismiss {
    if (!self.viewController) { return; }

    _presented = NO;
}

@end


text:
package org.wso2.andes.kernel;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
 * AndesChannel keep track of the states of the local channels
 */
public class AndesChannel {
    /**
     * Class logger
     */
    private static Log log = LogFactory.getLog(AndesChannel.class);

    /**
     * Used to generate unique IDs for channels
     */
    private static AtomicLong idGenerator = new AtomicLong(0);

    /**
     * Lister used to communicate with the local channels
     */
    private final FlowControlListener listener;

    /**
     * This is the limit used to release flow control on the channel
     */
    private final Integer flowControlLowLimit;

    /**
     * This is the limit used to enforce the flow control on the channel
     */
    private final Integer flowControlHighLimit;

    /**
     * Flow control manager used to handle gobal flow control events
     */
    private final FlowControlManager flowControlManager;

    /**
     * Channel of the current channel
     */
    private final long id;

    /**
     * Scheduled executor service used to create flow control timeout events
     */
    private final ScheduledExecutorService executor;

    /**
     * Flow control timeout task for current channel
     */
    private Runnable flowControlTimeoutTask = new FlowControlTimeoutTask();

    /**
     * Number of messages waiting in the buffer
     */
    private AtomicInteger messagesOnBuffer;

    /**
     * Indicate if the flow control is enabled for this channel
     */
    private boolean flowControlEnabled;

    /**
     * Track global flow control status
     */
    private boolean globalFlowControlEnabled;

    /**
     * Used to close the flow control timeout task if not required
     */
    private ScheduledFuture<?> scheduledFlowControlTimeoutFuture;

    public AndesChannel(FlowControlManager flowControlManager, FlowControlListener listener,
                        boolean globalFlowControlEnabled) {
        this.flowControlManager = flowControlManager;
        this.listener = listener;
        // Used the same executor used by the flow control manager
        this.executor = flowControlManager.getScheduledExecutor();
        this.globalFlowControlEnabled = globalFlowControlEnabled;

        // Read limits
        this.flowControlLowLimit = flowControlManager.getChannelLowLimit();
        this.flowControlHighLimit = flowControlManager.getChannelHighLimit();

        this.id = idGenerator.incrementAndGet();
        this.messagesOnBuffer = new AtomicInteger(0);
        this.flowControlEnabled = false;

        log.info("Channel created with ID: " + id);
    }

    /**
     * This method is called by the flow control manager when flow control is enforced globally
     */
    public void notifyGlobalFlowControlActivation() {
        globalFlowControlEnabled = true;
    }

    /**
     * This method is called by the flow control manager when flow control is not enforced globaly
     */
    public void notifyGlobalFlowControlDeactivation() {
        globalFlowControlEnabled = false;
        unblockLocalChannel();
    }

    /**
     * Notify local channel to unblock channel
     */
    private synchronized void unblockLocalChannel() {
        if (flowControlEnabled) {
            scheduledFlowControlTimeoutFuture.cancel(false);
            flowControlEnabled = false;
            listener.unblock();

            log.info("Flow control disabled for channel " + id + ".");
        }
    }

    /**
     * This method should be called when a message is put into the buffer
     *
     * @param size
     *         Number of items added to buffer
     */
    public void recordAdditionToBuffer(int size) {
        flowControlManager.notifyAddition(size);

        int count = messagesOnBuffer.addAndGet(size);

        if (!flowControlEnabled && (globalFlowControlEnabled || count >= flowControlHighLimit)) {
            blockLocalChannel();
        }
    }

    /**
     * Notify local channel to block channel temporary
     */
    private synchronized void blockLocalChannel() {
        if (!flowControlEnabled) {
            flowControlEnabled = true;
            listener.block();
            scheduledFlowControlTimeoutFuture = executor.schedule(flowControlTimeoutTask, 1, TimeUnit.MINUTES);

            log.info("Flow control enabled for channel " + id + ".");
        }
    }

    /**
     * This method should be called after a message is processed and no longer required in the buffer.
     *
     * @param size
     *         Number of items removed from buffer
     */
    public void recordRemovalFromBuffer(int size) {
        flowControlManager.notifyRemoval(size);

        int count = messagesOnBuffer.addAndGet(-size);

        if (flowControlEnabled && !globalFlowControlEnabled && count <= flowControlLowLimit) {
            unblockLocalChannel();
        }
    }

    /**
     * This timeout task avoid flow control being enforced forever. This can happen if the recordAdditionToBuffer get a
     * context switch after evaluating the existing condition and during that time all the messages get processed from
     * the StateEventHandler.
     */
    private class FlowControlTimeoutTask implements Runnable {
        @Override
        public void run() {
            if (flowControlEnabled && !globalFlowControlEnabled && messagesOnBuffer.get() <= flowControlLowLimit) {
                unblockLocalChannel();
            }
        }
    }
}


text:
namespace flutter {

LayerRasterCacheItem::LayerRasterCacheItem(Layer* layer,
                                           int layer_cached_threshold,
                                           bool can_cache_children)
    : RasterCacheItem(
          RasterCacheKeyID(layer->unique_id(), RasterCacheKeyType::kLayer),
          // The layer raster_cache_item's cache state default value is none.
          CacheState::kNone),
      layer_(layer),
      layer_cached_threshold_(layer_cached_threshold),
      can_cache_children_(can_cache_children) {}

void LayerRasterCacheItem::PrerollSetup(PrerollContext* context,
                                        const SkMatrix& matrix) {
  cache_state_ = CacheState::kNone;
  if (context->raster_cache && context->raster_cached_entries) {
    context->raster_cached_entries->push_back(this);
    child_items_ = context->raster_cached_entries->size();
    matrix_ = matrix;
  }
}

std::unique_ptr<LayerRasterCacheItem> LayerRasterCacheItem::Make(
    Layer* layer,
    int layer_cache_threshold,
    bool can_cache_children) {
  return std::make_unique<LayerRasterCacheItem>(layer, layer_cache_threshold,
                                                can_cache_children);
}

void LayerRasterCacheItem::PrerollFinalize(PrerollContext* context,
                                           const SkMatrix& matrix) {
  if (!context->raster_cache || !context->raster_cached_entries) {
    return;
  }
  // We've marked the cache entry that we would like to cache so it stays
  // alive, but if the following conditions apply then we need to set our
  // state back to kDoNotCache so that we don't populate the entry later.
  if (context->has_platform_view || context->has_texture_layer ||
      !SkRect::Intersects(context->cull_rect, layer_->paint_bounds())) {
    return;
  }
  child_items_ = context->raster_cached_entries->size() - child_items_;
  if (num_cache_attempts_ >= layer_cached_threshold_) {
    // the layer can be cached
    cache_state_ = CacheState::kCurrent;
    context->raster_cache->MarkSeen(key_id_, matrix_, true);
  } else {
    num_cache_attempts_++;
    // access current layer
    if (can_cache_children_) {
      if (!layer_children_id_.has_value()) {
        auto ids = RasterCacheKeyID::LayerChildrenIds(layer_);
        if (!ids.has_value()) {
          return;
        }
        layer_children_id_.emplace(std::move(ids.value()),
                                   RasterCacheKeyType::kLayerChildren);
      }
      cache_state_ = CacheState::kChildren;
      context->raster_cache->MarkSeen(layer_children_id_.value(), matrix_,
                                      true);
    }
  }
}

std::optional<RasterCacheKeyID> LayerRasterCacheItem::GetId() const {
  switch (cache_state_) {
    case kCurrent:
      return key_id_;
    case kChildren:
      return layer_children_id_;
    default:
      return {};
  }
}

const SkRect* LayerRasterCacheItem::GetPaintBoundsFromLayer() const {
  switch (cache_state_) {
    case CacheState::kCurrent:
      return &(layer_->paint_bounds());
    case CacheState::kChildren:
      FML_DCHECK(layer_->as_container_layer());
      return &(layer_->as_container_layer()->child_paint_bounds());
    default:
      FML_DCHECK(cache_state_ != CacheState::kNone);
      return nullptr;
  }
}

bool Rasterize(RasterCacheItem::CacheState cache_state,
               Layer* layer,
               const PaintContext& paint_context,
               SkCanvas* canvas) {
  FML_DCHECK(cache_state != RasterCacheItem::CacheState::kNone);
  SkISize canvas_size = canvas->getBaseLayerSize();
  SkNWayCanvas internal_nodes_canvas(canvas_size.width(), canvas_size.height());
  internal_nodes_canvas.setMatrix(canvas->getTotalMatrix());
  internal_nodes_canvas.addCanvas(canvas);
  PaintContext context = {
      // clang-format off
          .internal_nodes_canvas         = static_cast<SkCanvas*>(&internal_nodes_canvas),
          .leaf_nodes_canvas             = canvas,
          .gr_context                    = paint_context.gr_context,
          .dst_color_space               = paint_context.dst_color_space,
          .view_embedder                 = paint_context.view_embedder,
          .raster_time                   = paint_context.raster_time,
          .ui_time                       = paint_context.ui_time,
          .texture_registry              = paint_context.texture_registry,
          .raster_cache                  = paint_context.raster_cache,
          .checkerboard_offscreen_layers = paint_context.checkerboard_offscreen_layers,
          .frame_device_pixel_ratio      = paint_context.frame_device_pixel_ratio,
      // clang-format on
  };

  switch (cache_state) {
    case RasterCacheItem::CacheState::kCurrent:
      FML_DCHECK(layer->needs_painting(context));
      layer->Paint(context);
      break;
    case RasterCacheItem::CacheState::kChildren:
      layer->PaintChildren(context);
      break;
    case RasterCacheItem::CacheState::kNone:
      FML_DCHECK(cache_state != RasterCacheItem::CacheState::kNone);
      return false;
  }
  return true;
}

static const auto* flow_type = "RasterCacheFlow::Layer";

bool LayerRasterCacheItem::TryToPrepareRasterCache(const PaintContext& context,
                                                   bool parent_cached) const {
  if (!context.raster_cache || parent_cached) {
    return false;
  }
  if (cache_state_ != kNone) {
    if (const SkRect* paint_bounds = GetPaintBoundsFromLayer()) {
      RasterCache::Context r_context = {
          // clang-format off
          .gr_context         = context.gr_context,
          .dst_color_space    = context.dst_color_space,
          .matrix             = matrix_,
          .logical_rect       = *paint_bounds,
          .flow_type          = flow_type,
          // clang-format on
      };
      return context.raster_cache->UpdateCacheEntry(
          GetId().value(), r_context,
          [ctx = context, cache_state = cache_state_,
           layer = layer_](SkCanvas* canvas) {
            Rasterize(cache_state, layer, ctx, canvas);
          });
    }
  }
  return false;
}

bool LayerRasterCacheItem::Draw(const PaintContext& context,
                                const SkPaint* paint) const {
  return Draw(context, context.leaf_nodes_canvas, paint);
}

bool LayerRasterCacheItem::Draw(const PaintContext& context,
                                SkCanvas* canvas,
                                const SkPaint* paint) const {
  if (!context.raster_cache || !canvas) {
    return false;
  }
  switch (cache_state_) {
    case RasterCacheItem::kNone:
      return false;
    case RasterCacheItem::kCurrent: {
      return context.raster_cache->Draw(key_id_, *canvas, paint);
    }
    case RasterCacheItem::kChildren: {
      return context.raster_cache->Draw(layer_children_id_.value(), *canvas,
                                        paint);
    }
  }
}

}  // namespace flutter


text:
<title>listing - Using as</title>
<meta http-equiv="Content-Type" content="text/html">
<meta name="description" content="Using as">
<meta name="generator" content="makeinfo 4.7">
<link title="Top" rel="start" href="index.html#Top">
<link rel="up" href="Invoking.html#Invoking" title="Invoking">
<link rel="prev" href="L.html#L" title="L">
<link rel="next" href="M.html#M" title="M">
<link href="http://www.gnu.org/software/texinfo/" rel="generator-home" title="Texinfo Homepage">

<meta http-equiv="Content-Style-Type" content="text/css">

Next: M,
Previous: L,
Up: Invoking

2.8 Configuring listing output: --listing

The listing feature of the assembler can be enabled via the command line switch
-a (see a).  This feature combines the input source file(s) with a
hex dump of the corresponding locations in the output object file, and displays
them as a listing file.  The format of this listing can be controlled by
directives inside the assembler source (i.e., .list (see List),
.title (see Title), .sbttl (see Sbttl),
.psize (see Psize), and
.eject (see Eject) and also by the following switches:

--listing-lhs-width=number
Sets the maximum width, in words, of the first line of the hex byte dump.  This
dump appears on the left hand side of the listing output.

--listing-lhs-width2=number
Sets the maximum width, in words, of any further lines of the hex byte dump for
a given input source line.  If this value is not specified, it defaults to being
the same as the value specified for --listing-lhs-width.  If neither
switch is used the default is to one.

--listing-rhs-width=number
Sets the maximum width, in characters, of the source line that is displayed
alongside the hex dump.  The default value for this parameter is 100.  The
source line is displayed on the right hand side of the listing output.

--listing-cont-lines=number
Sets the maximum number of continuation lines of hex dump that will be
displayed for a given single line of source input.  The default value is 4.


text:
<?php

namespace Magento\Sales\Controller\Adminhtml\Order;

class Cancel extends \Magento\Sales\Controller\Adminhtml\Order
{
    /**
     * Cancel order
     *
     * @return void
     */
    public function execute()
    {
        $order = $this->_initOrder();
        if ($order) {
            try {
                $order->cancel()->save();
                $this->messageManager->addSuccess(__('You canceled the order.'));
            } catch (\Magento\Framework\Model\Exception $e) {
                $this->messageManager->addError($e->getMessage());
            } catch (\Exception $e) {
                $this->messageManager->addError(__('You have not canceled the item.'));
                $this->_objectManager->get('Magento\Framework\Logger')->logException($e);
            }
            $this->_redirect('sales/order/view', ['order_id' => $order->getId()]);
        }
    }
}


text:
import { $, $$, extend, isUndefined, elementData } from './helpers/helpers'
import Stage from './Stage'
import Canvas from './Canvas'
import o from 'riot-observable'

/**
 * There is no need to listen several times all the window events
 * with this class we listen them once and we subscribe/unsubscribe all the Parallax instances to the main events dispatcher
 * @type {Stage}
 */
let stage

/**
 * Parallax class
 * @param { String } selector - the tag selector where we will bind the parallax
 * @param { Object } opts - parallax options
 */
class Parallax {
  constructor(selector = null, opts = {}) {

    // make this object observable
    o(this)
    // set the options extending the _defaults
    this.opts = opts
    this.selector = selector
    this.canvases = []
    this.bound = false

    // allow to initialize without adding any dom elements
    if (selector !== null) {
      this.add(selector)
    }

    // lazy stage instance initialization
    if (!stage)
      stage = new Stage()

    return this
  }

  /**
   * Initialize the parallax
   * @returns { Object } - Parallax
   */
  init() {
    if (this.bound) {
      throw 'The parallax instance has already been initialized'
    }

    if (!this.canvases.length && this.selector !== null) {
      console.warn(`No elements were found with the selector "${this.selector}"`)
    } else {
      this.elementsLoaded = 0
      this.bind()
    }

    return this
  }

  /**
   * Bind the instance events setting all the callbacks
   * @returns { Object } - Parallax
   */
  bind() {

    // cache these function in order to unbind them when
    // this instance will be destroyed
    this._onResize = (...args) => this.resize.apply(this, args)
    this._onScroll = (...args) => this.scroll.apply(this, args)

    stage.on('resize', this._onResize)
    stage.on('scroll', this._onScroll)

    this.canvases.forEach((canvas) => {
      canvas.one('loaded', () => this.onCanvasLoaded(canvas))
      canvas.load()
    })

    this.bound = true

    return this
  }

  /**
   * Force manually a redraw
   * @returns { Object } - Parallax
   */
  refresh() {
    this._onResize(stage.size)
    this._onScroll(stage.scrollTop)
    return this
  }

  /**
   * Callback triggered once a canvas has loaded its element
   * @param   { Object } canvas - canvas instance
   * @returns { Object } - Parallax
   */
  onCanvasLoaded(canvas) {
    this.trigger('element:loaded', canvas.element, canvas)
    this.elementsLoaded++
    canvas.draw(stage)
    if (this.elementsLoaded == this.canvases.length) this.trigger('elements:loaded')
    return this
  }

  /**
   * Callback triggered on scroll
   * @param   { Number } scrollTop - page offset top
   * @returns { Object } - Parallax
   */
  scroll(scrollTop) {
    const offsetYBounds = this.opts.offsetYBounds,
      { height, width } = stage

    let i = this.canvases.length

    while (i--) {
      let canvas = this.canvases[i],
        canvasHeight = canvas.size.height,
        canvasOffset = canvas.offset

      if (
        canvas.isLoaded &&
          scrollTop + stage.height + offsetYBounds > canvasOffset.top &&
          canvasOffset.top + canvasHeight > scrollTop - offsetYBounds
      ) {
        canvas.draw({ height, scrollTop, width })
        this.trigger('draw', canvas.element)
      }

    }

    this.trigger('update', scrollTop)

    return this
  }

  /**
   * Add parallax elements to this parallax instance
   * @param { String|Array } els - DOM selector or node list
   * @returns { Object } - Parallax
   */
  add(els) {
    const canvases = this.createCanvases($$(els))

    if (this.bound) {
      canvases.forEach((canvas) => {
        canvas.one('loaded', () => this.onCanvasLoaded(canvas))
        canvas.load()
      })
    }

    this.canvases = this.canvases.concat(canvases)

    return this
  }

  /**
   * Remove parallax elements from this parallax instance
   * @param { String|Array } els - DOM selector or node list
   * @returns { Object } - Parallax
   */
  remove(els) {
    $$(els).forEach((el) => {
      let i = this.canvases.length
      while (i--) {
        if (el == this.canvases[i].element) {
          this.canvases[i].destroy()
          this.canvases.splice(i, 1)
          break
        }
      }
    })
    return this
  }

  /**
   * Kill all the internal and external callbacks listening this instance events
   * @returns { Object } - Parallax
   */
  destroy() {
    this.off('*')
    this.canvases = []
    stage.off('resize', this._onResize).off('scroll', this._onScroll)
    return this
  }

  /**
   * Callback triggered on window resize
   * @param   { Object } size - object containing the window width and height
   * @returns { Object } - Parallax
   */
  resize(size) {
    let i = this.canvases.length
    while (i--) {
      const canvas = this.canvases[i]
      if (!canvas.isLoaded) return
      canvas.update().draw(stage)
    }
    this.trigger('resize')
    return this
  }

  /**
   * Set the canvases instances
   * @param   { Array } els - list of the elements we want to parallax
   * @returns { Array } - list of canvas instances
   */
  createCanvases(els) {
    return els.map(el => {
      const data = elementData(el)
      return new Canvas(el, {
        intensity: !isUndefined(data.intensity) ? +data.intensity : this.opts.intensity,
        center: !isUndefined(data.center) ? +data.center : this.opts.center,
        safeHeight: !isUndefined(data.safeHeight) ? +data.safeHeight : this.opts.safeHeight
      })
    })
  }

  /**
   * The options will be always set extending the script _defaults
   * @param   { Object } opts - custom options
   */
  set opts(opts) {
    this._defaults = {
      offsetYBounds: 50,
      intensity: 30,
      center: 0.5,
      // make sure that the elements can always properly parallax
      // They should be at least 15% higher than their wrappers (7.5% bottom + 7.5% top)
      safeHeight: 0.15 // 15%
    }
    extend(this._defaults, opts)
  }

  /**
   * Get the script options object
   * @returns { Object } - current options
   */
  get opts() {
    return this._defaults
  }
}

export default Parallax


text:
<ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder'
             xmlns:g='urn:import:com.google.gwt.user.client.ui'
             xmlns:p='urn:import:com.vaadin.polymer.paper.widget'
             xmlns:i='urn:import:com.vaadin.polymer.iron.widget'
        >

    <g:HTMLPanel addStyleNames="button-sample">

Flat

button

colorful

disabled

noink

ok

cancel

Raised

button

colorful

disabled

noink

ok

cancel

Toggleable

button

noink

colorful

colorful

ok

cancel

Color

button

noink

colorful

colorful

ok

cancel

    </g:HTMLPanel>
</ui:UiBinder>


text:
"""
send status log to s3
"""

import boto
from uuid import getnode as get_mac
import time
import platform
from boto.s3.connection import S3Connection

def send_log(type=None):
    assert type in ['start','finish','crash']

    ts = time.time()

    bucket_name = 'myconnectome'

    conn = S3Connection(anon=True)
    bucket = conn.get_bucket(bucket_name)

    mac = get_mac()

    k = bucket.new_key('logs/%s:%d:%d'%(type,mac,ts))
    k.set_contents_from_string(' '.join(platform.uname()))


text:
package com.tle.core.db.tables

import com.tle.core.db.types.InstId

case class Setting(institution_id: InstId, property: String, value: String)


text:
<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <parent>
    <groupId>com.squareup.okhttp</groupId>
    <artifactId>parent</artifactId>
    <version>2.2.0-SNAPSHOT</version>
  </parent>

  <artifactId>okhttp-hpacktests</artifactId>
  <name>OkHttp HPACK Tests</name>

  <dependencies>
    <dependency>
      <groupId>com.squareup.okio</groupId>
      <artifactId>okio</artifactId>
    </dependency>
    <dependency>
      <groupId>com.squareup.okhttp</groupId>
      <artifactId>okhttp</artifactId>
      <version>${project.version}</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>com.squareup.okhttp</groupId>
      <artifactId>mockwebserver</artifactId>
      <version>${project.version}</version>
      <scope>test</scope>
    </dependency>
    <!--  Gson: Java to Json conversion -->
    <dependency>
      <groupId>com.google.code.gson</groupId>
      <artifactId>gson</artifactId>
      <scope>compile</scope>
    </dependency>
  </dependencies>

  <build>
    <plugins>
      <!-- Do not deploy this as an artifact to Maven central. -->
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-deploy-plugin</artifactId>
        <configuration>
          <skip>true</skip>
        </configuration>
      </plugin>
    </plugins>
  </build>
</project>


text:
require 'rails_helper'

RSpec.describe Item, type: :model do
  it "is valid with valid attributes" do
    item = create(:item)
    expect(item).to be_valid
  end

  describe Item do
    it { should have_attached_file(:image) }
    it { should validate_attachment_presence(:image) }
    it { should validate_attachment_content_type(:image).
                  allowing('image/png', 'image/gif').
                  rejecting('text/plain', 'text/xml') }
    it { should validate_attachment_size(:image).
                  less_than(2.megabytes) }
  end

end


text:
FROM golang:1.4.2-cross
MAINTAINER peter.edge@gmail.com

RUN mkdir -p /go/src/github.com/peter-edge/go-env
ADD . /go/src/github.com/peter-edge/go-env/
WORKDIR /go/src/github.com/peter-edge/go-env


text:
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/module.h>
#include <linux/usb.h>
#include <linux/usb/serial.h>

static struct usb_device_id id_table [] = {
	{ USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
	{ USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */
	{ },
};
MODULE_DEVICE_TABLE(usb, id_table);

#define URB_TRANSFER_BUFFER_SIZE	4096
#define NUM_READ_URBS			4
#define NUM_WRITE_URBS			4
#define NUM_BULK_EPS			3
#define MAX_BULK_EPS			6

/* if overridden by the user, then use their value for the size of the
 * read and write urbs, and the number of endpoints */
static int buffer_size = URB_TRANSFER_BUFFER_SIZE;
static int endpoints = NUM_BULK_EPS;
static int debug;
struct airprime_private {
	spinlock_t lock;
	int outstanding_urbs;
	int throttled;
	struct urb *read_urbp[NUM_READ_URBS];

	/* Settings for the port */
	int rts_state;	/* Handshaking pins (outputs) */
	int dtr_state;
	int cts_state;	/* Handshaking pins (inputs) */
	int dsr_state;
	int dcd_state;
	int ri_state;
};

static int airprime_send_setup(struct usb_serial_port *port)
{
	struct usb_serial *serial = port->serial;
	struct airprime_private *priv;

	dbg("%s", __FUNCTION__);

	if (port->number != 0)
		return 0;

	priv = usb_get_serial_port_data(port);

	if (port->tty) {
		int val = 0;
		if (priv->dtr_state)
			val |= 0x01;
		if (priv->rts_state)
			val |= 0x02;

		return usb_control_msg(serial->dev,
				usb_rcvctrlpipe(serial->dev, 0),
				0x22,0x21,val,0,NULL,0,USB_CTRL_SET_TIMEOUT);
	}

	return 0;
}

static void airprime_read_bulk_callback(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	unsigned char *data = urb->transfer_buffer;
	struct tty_struct *tty;
	int result;

	dbg("%s - port %d", __FUNCTION__, port->number);

	if (urb->status) {
		dbg("%s - nonzero read bulk status received: %d",
		    __FUNCTION__, urb->status);
		return;
	}
	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);

	tty = port->tty;
	if (tty && urb->actual_length) {
		tty_insert_flip_string (tty, data, urb->actual_length);
		tty_flip_buffer_push (tty);
	}

	result = usb_submit_urb (urb, GFP_ATOMIC);
	if (result)
		dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n",
			__FUNCTION__, result);
	return;
}

static void airprime_write_bulk_callback(struct urb *urb)
{
	struct usb_serial_port *port = urb->context;
	struct airprime_private *priv = usb_get_serial_port_data(port);
	unsigned long flags;

	dbg("%s - port %d", __FUNCTION__, port->number);

	/* free up the transfer buffer, as usb_free_urb() does not do this */
	kfree (urb->transfer_buffer);

	if (urb->status)
		dbg("%s - nonzero write bulk status received: %d",
		    __FUNCTION__, urb->status);
	spin_lock_irqsave(&priv->lock, flags);
	--priv->outstanding_urbs;
	spin_unlock_irqrestore(&priv->lock, flags);

	usb_serial_port_softint(port);
}

static int airprime_open(struct usb_serial_port *port, struct file *filp)
{
	struct airprime_private *priv = usb_get_serial_port_data(port);
	struct usb_serial *serial = port->serial;
	struct urb *urb;
	char *buffer = NULL;
	int i;
	int result = 0;

	dbg("%s - port %d", __FUNCTION__, port->number);

	/* initialize our private data structure if it isn't already created */
	if (!priv) {
		priv = kzalloc(sizeof(*priv), GFP_KERNEL);
		if (!priv) {
			result = -ENOMEM;
			goto out;
		}
		spin_lock_init(&priv->lock);
		usb_set_serial_port_data(port, priv);
	}

	/* Set some sane defaults */
	priv->rts_state = 1;
	priv->dtr_state = 1;

	for (i = 0; i < NUM_READ_URBS; ++i) {
		buffer = kmalloc(buffer_size, GFP_KERNEL);
		if (!buffer) {
			dev_err(&port->dev, "%s - out of memory.\n",
				__FUNCTION__);
			result = -ENOMEM;
			goto errout;
		}
		urb = usb_alloc_urb(0, GFP_KERNEL);
		if (!urb) {
			kfree(buffer);
			dev_err(&port->dev, "%s - no more urbs?\n",
				__FUNCTION__);
			result = -ENOMEM;
			goto errout;
		}
		usb_fill_bulk_urb(urb, serial->dev,
				  usb_rcvbulkpipe(serial->dev,
						  port->bulk_out_endpointAddress),
				  buffer, buffer_size,
				  airprime_read_bulk_callback, port);
		result = usb_submit_urb(urb, GFP_KERNEL);
		if (result) {
			usb_free_urb(urb);
			kfree(buffer);
			dev_err(&port->dev,
				"%s - failed submitting read urb %d for port %d, error %d\n",
				__FUNCTION__, i, port->number, result);
			goto errout;
		}
		/* remember this urb so we can kill it when the port is closed */
		priv->read_urbp[i] = urb;
	}

	airprime_send_setup(port);

	goto out;

 errout:
	/* some error happened, cancel any submitted urbs and clean up anything that
	   got allocated successfully */

	while (i-- != 0) {
		urb = priv->read_urbp[i];
		buffer = urb->transfer_buffer;
		usb_kill_urb (urb);
		usb_free_urb (urb);
		kfree (buffer);
	}

 out:
	return result;
}

static void airprime_close(struct usb_serial_port *port, struct file * filp)
{
	struct airprime_private *priv = usb_get_serial_port_data(port);
	int i;

	dbg("%s - port %d", __FUNCTION__, port->number);

	priv->rts_state = 0;
	priv->dtr_state = 0;

	airprime_send_setup(port);

	for (i = 0; i < NUM_READ_URBS; ++i) {
		usb_kill_urb (priv->read_urbp[i]);
		kfree (priv->read_urbp[i]->transfer_buffer);
		usb_free_urb (priv->read_urbp[i]);
	}

	/* free up private structure */
	kfree (priv);
	usb_set_serial_port_data(port, NULL);
}

static int airprime_write(struct usb_serial_port *port,
			  const unsigned char *buf, int count)
{
	struct airprime_private *priv = usb_get_serial_port_data(port);
	struct usb_serial *serial = port->serial;
	struct urb *urb;
	unsigned char *buffer;
	unsigned long flags;
	int status;
	dbg("%s - port %d", __FUNCTION__, port->number);

	spin_lock_irqsave(&priv->lock, flags);
	if (priv->outstanding_urbs > NUM_WRITE_URBS) {
		spin_unlock_irqrestore(&priv->lock, flags);
		dbg("%s - write limit hit\n", __FUNCTION__);
		return 0;
	}
	spin_unlock_irqrestore(&priv->lock, flags);
	buffer = kmalloc(count, GFP_ATOMIC);
	if (!buffer) {
		dev_err(&port->dev, "out of memory\n");
		return -ENOMEM;
	}
	urb = usb_alloc_urb(0, GFP_ATOMIC);
	if (!urb) {
		dev_err(&port->dev, "no more free urbs\n");
		kfree (buffer);
		return -ENOMEM;
	}
	memcpy (buffer, buf, count);

	usb_serial_debug_data(debug, &port->dev, __FUNCTION__, count, buffer);

	usb_fill_bulk_urb(urb, serial->dev,
			  usb_sndbulkpipe(serial->dev,
					  port->bulk_out_endpointAddress),
			  buffer, count,
			  airprime_write_bulk_callback, port);

	/* send it down the pipe */
	status = usb_submit_urb(urb, GFP_ATOMIC);
	if (status) {
		dev_err(&port->dev,
			"%s - usb_submit_urb(write bulk) failed with status = %d\n",
			__FUNCTION__, status);
		count = status;
		kfree (buffer);
	} else {
		spin_lock_irqsave(&priv->lock, flags);
		++priv->outstanding_urbs;
		spin_unlock_irqrestore(&priv->lock, flags);
	}
	/* we are done with this urb, so let the host driver
	 * really free it when it is finished with it */
	usb_free_urb (urb);
	return count;
}

static struct usb_driver airprime_driver = {
	.name =		"airprime",
	.probe =	usb_serial_probe,
	.disconnect =	usb_serial_disconnect,
	.id_table =	id_table,
	.no_dynamic_id =	1,
};

static struct usb_serial_driver airprime_device = {
	.driver = {
		.owner =	THIS_MODULE,
		.name =		"airprime",
	},
	.usb_driver =		&airprime_driver,
	.id_table =		id_table,
	.num_interrupt_in =	NUM_DONT_CARE,
	.num_bulk_in =		NUM_DONT_CARE,
	.num_bulk_out =		NUM_DONT_CARE,
	.open =			airprime_open,
	.close =		airprime_close,
	.write =		airprime_write,
};

static int __init airprime_init(void)
{
	int retval;

	airprime_device.num_ports =
		(endpoints > 0 && endpoints <= MAX_BULK_EPS) ? endpoints : NUM_BULK_EPS;
	retval = usb_serial_register(&airprime_device);
	if (retval)
		return retval;
	retval = usb_register(&airprime_driver);
	if (retval)
		usb_serial_deregister(&airprime_device);
	return retval;
}

static void __exit airprime_exit(void)
{
	dbg("%s", __FUNCTION__);

	usb_deregister(&airprime_driver);
	usb_serial_deregister(&airprime_device);
}

module_init(airprime_init);
module_exit(airprime_exit);
MODULE_LICENSE("GPL");

module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled");
module_param(buffer_size, int, 0);
MODULE_PARM_DESC(buffer_size, "Size of the transfer buffers in bytes (default 4096)");
module_param(endpoints, int, 0);
MODULE_PARM_DESC(endpoints, "Number of bulk EPs to configure (default 3)");